CGAL: Output from neighbour when the triangle has none - c++

So I am wondering what happens in CGAL Delaunay triangulation when you call the neighbor function for a neighbor that doesn't exist. In the documentation (HERE) it says this:
The neighbor with index i is the neighbor which is opposite to the vertex with index i.
Face_handle f.neighbor ( int i) const //returns the neighbor i of f.
//Precondition: 0 ≤ i ≤ 2.
But not all triangles can have 3 neighbors. Edge and corner triangles will neighbor only 2. Given that it must now return a Face_handle, what would happen for the neighbors that don't exist? Maybe it will be NULL? How can i check this?
The reason i am looking to do this is because i would like to identify all the edge triangles in a Delaunay triangulation. Being able to check for triangles with 2 or less neighbors would be very useful.
Any ideas?

See the documentation.
CGAL introduces an infinite vertex, hence each "border edge" has an additional neighbour, which is an infinite triangle composed of the two vertices of your edge and the infinite vertex.

Related

Find 2 points in X-Y Plane

I have X-Y plane and points (xi, yi) where x, y and i are integers. Now if I draw infinite lines of slope 1 and -1, I have to find those 2 points which either will lie on the same line or if none of them lie then should output:
Case : If atmost 1 point lies on a line the 2nd point should be the point which has minimum distance from the line. In such cases we can draw the line exactly between those 2 points to minimize the distance.
I am not able to find the solution to this problem. My approach was to look at the points in opposite quadrants but I did not get any solution better than O(n^2).
First, I would transform the points into a different coordinate system that is rotated by 45°:
u = x + y
v = x - y
If the original points lie on a line with slope 1, their v coordinate will be equal. If they lie on a line with slope -1, their u coordinate will be equal.
Now, create two lists of points. One sorted by u, the other sorted by v. Then iterate all the points. To find the point that is closest to the corresponding line, you just have to check the neighbors in the sorted order. If there are neighbors with the same u/v coordinate, you are done. If not, find the neighbor with the smallest u/v difference and remember it. Do this for all the points and report the pair with the smallest distance.

Calculating edge lengths of triangles obtained from Delaunay's triangulation

I have a set of discrete points and using them, I performed Delaunay's triangulation.
I want to calculate all the edge lengths from a vertex to the neighboring vertices.
How can I do/code this in c++?
I haven't tested the code that you posted, but the problem seems trivial.
In your main function after you draw all the triangles/points, get the list of all the triangles from subdiv with:
vector<Vec6f> triangleList;
subdiv.getTriangleList(triangleList);
(just like in the draw_delaunay(...) function)
Now you just iterate the triangles and compare each point of each triangle to your vertex.
If it's the same point as yours, then you calculate the lengths of edges with two other points of the triangle.
Length here = L2 norm of the vector v = point - your_vertex = Sqrt(v.x^2 + v.y^2).
There may be duplicates of some edges, so if you want to avoid it, just create a set and add all the point there and calculate the norms later.

How does the algorithm of merging two convex hulls by using their tangents work in practice?

I'm trying to implement in C++ the divide and conquer algorithm of finding the convex hull from a set of two dimensional points. For simplicity let's assume that all the points are described with integers.
The most important part of the algorithm is merging the two convex hulls that you have computed from previous recursive calls. This part involves finding the lower and upper tangents of the two convex hulls and then proceeding with the merging.
The merging is trivial, if you have found the four points that describe the tangents, then the points that aren't inside the polygon defined by these four points will be part of the new convex hull.
However, I have no idea how to find these four points.
Here is the pseudocode that most sources (this one is from http://www.cs.wustl.edu/~pless/506/l3.html) suggest for finding the lower tangent of convex hull HA and convex hull HB.
Finding the Lower Tangent
LowerTangent(HA ; HB ) :
(1) Let a be the rightmost point of HA .
(2) Let b be the leftmost point of HB .
(3) While ab is not a lower tangent for HA and HB do
(a) While ab is not a lower tangent to HA do a = a - 1 (move a clockwise).
(b) While ab is not a lower tangent to HB do b = b + 1 (move b counterCW).
(4) Return ab.
(1), (2)
The points are initially sorted by their x coordinate, so finding the rightmost point of HA and the leftmost point of HB can be done in O(1).
a = HA[HA.size-1]
b = HB[0]
Now I can't understand the next steps.
Having chosen this ab line segment, how can we check if ab is not a lower tangent so we can either enter the first while loop or not?
And then, how do we move the point a to a-1 by following a clockwise direction? The points are sorted by their x coordinate, and doing just a = a-1 will lead to wrong results.
Thanks!
Your reference only briefly states:
Lower tangency is a condition that can be tested locally by an
orientation test of the two vertices and neighboring vertices on the
hull. (This is a simple exercise.)
and doesn't appear to give any more details. I found this reference which goes into further details of how to find the lower tangency including some example code.
Also note that your should not be sorting the X-coordinates for this purpose. This algorithm relies on the points being in their normal consecutive order that defines the polygon. Sorting by X only helps you in finding the initial points.
Pseudo-code of the lower tangency algorithm from that reference is:
idx1 = (Rightmost point index of Poly1)
idx2 = (Leftmost point index of Poly2)
while (TRUE)
while (isLeft(Poly1[idx2], Poly2[idx1], Poly2[idx1+1]) <= 0)
++idx1;
end while
while (isLeft(Poly2[idx1], Poly1[idx2], Poly1[idx2-1]) >= 0)
--idx2;
done = FALSE;
end while
end while
// idx1/idx2 are now the two indices that form the lower tangent
The isLeft() code from the same reference is:
float isLeft (Point P0, Point P1, Point P2)
{
return (P1.x - P0.x)*(P2.y - P0.y) - (P2.x - P0.x)*(P1.y - P0.y);
}
If the two convex polygons are intersecting then it is incorrect to assume that there are only two tangents that connect the two polygons.
It depends upon how exactly the points are divided. If division ensures that the resultant convex hulls never intersect then it is fine to make such assumption. But if the division of points does not guarantee the convex hulls to be non intersecting then algorithm needs to be modified to find multiple tangents.

how to determine if points is on shape and in shape?

I have two of this:
bool isPointOnShape(int a, int b)
{
}
bool isPointInShape(int a, int b)
{
}
Say I have a square, first point (bottom left corner) is x,y (0,0) second point (top left) is (0,2), third is (2,2) and fourth is (0,2).
The Points on shape would be (0,1) (1,2) (2,1) (1,0) and Points in shape is (1,1)
How do I find out the points on shape / in shape and return a true value so that I can store it somewhere?
For a potentially non-convex shape you may use an algorithm like this:
Find how many shape edges intersect a ray starting at (a,b). You may choose any ray, but it is easier to calculate intersections if the ray is horizontal or vertical.
Point is inside if the number of intersections is odd.
Try going over this tutorial in openCV explaining how to use the point in polygon test. Also a good reference is this wiki page which covers several other methods.
If you don't want to use openCV - in general you can use the Ray casting algorithm:
take a line from the given point (x,y) in any direction you want, let's call it L
for each line in ((0,0),(0,2)), ((0,0),(2,0)), ((2,2),(0,2)), ((2,2),(2,0)) test if that line intersect with with L and count the number of intersections N
if N is odd the point (x,y) is in the polygon

Convexity of a polygon C++? [duplicate]

This question already has answers here:
How do I efficiently determine if a polygon is convex, non-convex or complex?
(10 answers)
How to check if polygon is convex? [duplicate]
(1 answer)
Closed 9 years ago.
How can i test if a polygon is convex or not only by knowing the points of the polygon
with their coordonates in c++?
For each side of polygon, calculate line equation (Ax+By+C=0) and check (put x and y into equation and get sign of it), that all points are from one side of it.
EDIT:
If travel convex polygon, you will always rotate into one direction (left or right) on every point.
Using cross product, you can simply deduce, onto which side (negative or positive) you will rotate next turn. If all cross products of three consecutive points will have equal sign, then your polygon is convex.
Find the convex hull using any of the common algorithms. A polygon is convex if and only if all its vertices belong to its convex hull.
This is O(n log n) but does not rely on the assumption that the points are given in the proper order around the edges of the polygon. If the assumption is true then the answer from hate-engine is optimal (i.e. linear time.)
the gift wrapping algorithm is an algorithm for computing the convex
hull of a given set of points.
Pseudocode from wiki:
jarvis(S)
pointOnHull = leftmost point in S
i = 0
repeat
P[i] = pointOnHull
endpoint = S[0] // initial endpoint for a candidate edge on the hull
for j from 1 to |S|-1
if (endpoint == pointOnHull) or
(S[j] is on left of line from P[i] to endpoint)
endpoint = S[j] // found greater left turn, update endpoint
i = i+1
pointOnHull = endpoint
until endpoint == P[0] // wrapped around to first hull point
If your points match detected points of above algorithm then the polygon is convex.