Context
I have to implement a polygon triangulation algorithm for a school assignment. I chose to follow the algorithm described in the book "Computational Geometry: Algorithms and Applications".
The input is a polygon stored as a doubly-connected edge list. The first step is to partition the polygon into monotone pieces. In order to do so, it's necessary to perform a line sweep and process each vertex according to its type. According to the authors, the vertex types are described as follows:
We distinguish five types of vertices in P—see Figure 3.3. Four of these
types are turn vertices: start vertices, split vertices, end vertices, and merge
vertices. They are defined as follows. A vertex v is a start vertex if its two
neighbors lie below it and the interior angle at v is less than π; if the interior
angle is greater than π then v is a split vertex. (If both neighbors lie below
v, then the interior angle cannot be exactly π.) A vertex is an end vertex if
its two neighbors lie above it and the interior angle at v is less than π; if the
interior angle is greater than π then v is a merge vertex. The vertices that
are not turn vertices are regular vertices. Thus a regular vertex has one of its
neighbors above it, and the other neighbor below it.
The problem
I can't figure out how to differentiate start vertices from split vertices, or end vertices from merge vertices. How can I do it?
Additional info
My data struct for the DCEL is something like this
class HalfEdge {
HalfEdge *previous, *next, *twin;
Point *to, *from;
};
Maybe if you keep track of a counter clock-wise orientation of the polygon's boundary (i.e. keep the edges directed), you could distinguish the two. Say the consecutive vertices are v[i-1], v[i], v[i+1] and v[i-1] and v[i+1] are below v[i]. Then form the 2D vectors v[i]-v[i-1] and v[i+1]-v[i]. After that, calculate the determinant det( v[i]-v[i-1] , v[i+1]-v[i] ). If the determinant is positive, then the vertex is start. If the determinant is negative, the vertex is split.
Related
Say that I have a big network with 10^4 nodes. And then I want to analyse the neighbourhood associated with a random node, say node 10. I can see which are the nodes connected to that node by looking at the 10th row entries of the adjacency matrix, and then I can repeat this if I want to look at the neighbours of those neighbours (second shell) and so on and so forth.
Is there an efficient way to do this - or even an inefficient but better than writing the whole thing from the scratch-? The actual network that I have is a Random Regular Graph and I am interested on the tree-like local structure for large networks.
If I understand your use case, there is a good way of doing this: the egonet function. You give it a graph, a starting vertex, and number of hops, and it will return an induced subgraph of the graph starting at the vertex and going out that number of hops. Here's the docstring:
egonet(g, v, d, distmx=weights(g))
Return the subgraph of g induced by the neighbors of v up to distance d, using weights (optionally) provided by distmx. This is equivalent to
induced_subgraph(g, neighborhood(g, v, d, dir=dir))[1].
Optional Arguments
––––––––––––––––––––
• dir=:out: if g is directed, this argument specifies the edge direction
with respect to v (i.e. :in or :out).
Edited to add: if all you need are the vertex indices, then neighborhood() is what you want:
neighborhood(g, v, d, distmx=weights(g))
Return a vector of each vertex in g at a geodesic distance less than or equal to d, where distances may be specified by distmx.
Optional Arguments
––––––––––––––––––––
• dir=:out: If g is directed, this argument specifies the edge direction
with respect to v of the edges to be considered. Possible values: :in or :out.
Given two simple polygons P and Q where P is convex but Q not, how fast can one compute the difference $P - Q$ between P and Q if P has n and Q has m vertices?
One can assume that the polygons are given as list of vertices ordered in clockwise direction.
"How fast" depends on lots of parameters, so I think, we should start with how to do it,first.
Firstly, I assume polygons lie on the same plane. Start with computing the finite intersection of each line of P with each line of Q. If the intersection exists and intersection point lies on intersecting lines(I mean between start and end, not on them), divide line into two and continue finite line-line intersections iteratively. Then, categorize each line segment(now I can call them as segment because that they are all divided if necessary) by using a point in polygon computation with mid-points of segments..Inner,Outer or OnthePolygon...After categorization construct a new polygon from the lines of P that lies outside of Q and lines of Q that lies inside of the P. Here, your challenge will be dealing with tolerances and lines that are lies on eachother..At first glance, overall algorithm is like this..
This algorithm can be improved by eliminating lines and even polygons by computing their ranges(min and max for each axis). Except from the hardware, programming language or data handling parameters, the speed of this operation is dependent on the input polygons and their orientation.
I have a polygon P made of N vertices. I need an algorithm that, given P, subdivide it in a certain number of convex polygons each using at most M vertices.
Ps.
P is a 2D polygon. Furthermore, i can use a polygon triangulation, but i am interested in algorithms that subdivide P into convex polygons having more than 3 vertices (and, as said above, at most M).
Quadtree methods would be my recommendation. Check those out.
Given an undirected graph in which each node has a Cartesian coordinate in space that has the general shape of a tree, is there an algorithm to convert the graph into a tree, and find the appropriate root node?
Note that our definition of a "tree" requires that branches do not diverge from parent nodes at acute angles.
See the example graphs below. How do we find the red node?
here is a suggestion on how to solve your problem.
prerequisites
notation:
g graph, g.v graph vertices
v,w,z: individual vertices
e: individual edge
n: number of vertices
any combination of an undirected tree g and a given node g.v uniquely determines a directed tree with root g.v (provable by induction)
idea
complement the edges of g by orientations in the directed tree implied by g and the yet-to-be-found root node by local computations at the nodes of g.
these orientations will represent child-parent-relationsships between nodes (v -> w: v child, w parent).
the completely marked tree will contain a sole node with outdegree 0, which is the desired root node. you might end up with 0 or more than one root node.
algorithm
assumes standard representation of the graph/tree structure (eg adjacency list)
all vertices in g.v are marked initially as not visited, not finished.
visit all vertices in arbitrary sequence. skip nodes marked as 'finished'.
let v be the currently visited vertex.
2.1 sweep through all edges linking v clockwise starting with a randomly chosen e_0 in the order of the edges' angle with e_0.
2.2. orient adjacent edges e_1=(v,w_1), e_2(v,w_2), that enclose an acute angle.
adjacent: wrt being ordered according to the angle they enclose with e_0.
[ note: the existence of such a pair is not guaranteed, see 2nd comment and last remark. if no angle is acute, proceed at 2. with next node. ]
2.2.1 the orientations of edges e_1, e_2 are known:
w_1 -> v -> w_2: impossible, as a grandparent-child-segment would enclose an acute angle
w_1 <- v <- w_2: impossible, same reason
w_1 <- v -> w_2: impossible, there are no nodes with outdegree >1 in a tree
w_1 -> v <- w_2:
only possible pair of orientations. e_1, e_2 might have been oriented before. if the previous orientation violates the current assignment, the problem instance has no solution.
2.2.2 this assignment implies a tree structure on the subgraphs induced by all vertices reachable from w_1 (w_2) on a path not comprising e_1 (e_2`). mark all vertices in both induced subtrees as finished
[ note: the subtree structure might violate the angle constraints. in this case the problem has no solution. ]
2.3 mark v visited. after completing steps 2.2 at vertex v, check the number nc of edges connecting that have not yet been assigned an orientation.
nc = 0: this is the root you've been searching for - but you must check whether the solution is compatible with your constraints.
nc = 1: let this edge be (v,z).
the orientation of this edge is v->z as you are in a tree. mark v as finished.
2.3.1 check z whether it is marked finished.
if it is not, check the number nc2 of unoriented edges connecting z.
nc2 = 1: repeat step 2.3 by taking z for v.
if you have not yet found a root node, your problem instance is ambiguous:
orient the remaining unoriented edges at will.
remarks
termination:
each node is visited at max 4 times:
once per step 2
at max twice per step 2.2.2
at max once per step 2.3
correctness:
all edges enclosing an acute angle are oriented per step 2.2.1
complexity (time):
visiting every node: O(n);
the clockwise sweep through all edges connecting a given vertex requires these edges to be sorted.
thus you need O( sum_i=1..m ( k_i * lg k_i ) ) at m <= n vertices under the constraint sum_i=1..m k_i = n.
in total this requires O ( n * lg n), as sum_i=1..m ( k_i * lg k_i ) <= n * lg n given sum_i=1..m k_i = n for any m <= n (provable by applying lagrange optimization).
[ note: if your trees have a degree bounded by a constant, you theoretically sort in constant time at each node affected; grand total in this case: O(n) ]
subtree marking:
each node in the graph is visited at max 2 times by this procedure if implemented as a dfs. thus a grand total of O(n) for the invocation of this subroutine.
in total: O(n * lg n)
complexity (space):
O(n) for sorting (with vertex-degree not constant-bound).
problem is probably ill-defined:
multiple solutions: e.g. steiner tree
no solution: e.g. graph shaped like a double-tipped arrow (<->)
A simple solution would be to define a 2d rectangle around the red node or the center of your node and compute each node with a moore curve. A moore curve is a space-filling curve, more over a special version of a hilbert curve where the start and end vertex is the same and the coordinate is in the middle of the 2d rectangle. In generell your problem looks like a discrete addressing space problem.
I have 2D polygons, with their vertices positioned in local polygon-space. I'm trying to calculate new vertices that would form a uniform length edge around the inside of the polygon.
Currently to calculate the edge, I'm basically shrinking the original vertices. For each polygon vertex I calculate the negated unit vector and multiply this by a constant edge length factor. Then I add this to the original polygon vertex.
Pseudocode:
const float edgeLength = 0.5;
for each vertex v
vec2 n = -v.unit();
vec2 edgeVertex = v + n * edgeLength;
The result works fine on regular polygons:
screenshot 1
However, on other polygons, such as rectangles, the edge lengths are not uniform:
screenshot 2
I've tried many different attempts, but nothing seems to work so far, any help would be greatly appreciated, thanks!
(Please ignore that the polygons are rendered in 3D, the actual polygon data is 2D).
Move each edge a fixed distance, in a direction perpendicular to the edge (all to the left, if the edges run counterclockwise). Then calculate the intersections of the new edges-- these are the new vertices.