Computing visibility polygon from a point in the boundary - computational-geometry

I'm using the CGAL library to compute Visibility Polygons from a point p within a simple polygon P, where p is in the boundary of P.
I'm using the class "Simple_polygon_visibility_2" and when the visibility polygon is computed, the results seem to be wrong. I'm sending in the attachment both the polygon P and the resulting visibility polygon.
In this example, I'm interested in finding the visibility polygon from the vertex labeled "7". As you can see, the resulting visibility polygon has the edge from "4" to "5" (and consequently, the triangle "7-4-5") which is not valid, since this triangle is not part of P.
I've read the paper from Joe and Simpson, and they mention:
"For a boundary viewpoint z, we orient the vertices of P in
counterclockwise order and label them z, v_0, v_1, ..., v_{n-1}, v_n
and z, where v_0 is the successor vertex of z and v_n is the
predecessor vertex of z. We also assume that the coordinate system is
translated and rotated so that z is at the origin and v_0 is on the
positive x-axis"
I think that maybe this is the issue, because I'm not sure if CGAL's implementation tests whether the query point is on the boundary or not and if so, treats it as an especial case.
If so, do I have to do this translation/rotation a priori?

Actually, its was my mistake. Since the point is in the boundary, it does not belong to either the interior or exterior face (when the arrangement is a simple polygon). So instead of using this version of the "compute_visibility" method, I should use the one in which the half-edge containing the query point is the parameter. In this case, it works as expected.

Related

Maximum enclosing disk

Let A and B be two sets of points, each consisting of n points, all lying in unit square S.
I am trying to find a efficient algorithm for finding the largest disk D such that:
(i) The center of D lie in S.
(ii) The interior of D is empty.
(iii) The boundary of D touches atleast one point from A and one point from B.
Im having a real problem with this question. Any hints will be usefull.
To complete Yves Daoust's partial solution, compute the Voronoi diagram (which is dual to the Delaunay triangulation) bounded by S. We can find an optimal circle center at some Voronoi vertex (i.e., a point in the interior of S where the nearest three points in A ∪ B are equidistant, or a point on the boundary of S where the nearest two points in A ∪ B are equidistant) where one of the nearest points is in A and another is in B.
Such a vertex is clearly feasible as a center. If we try to take any other center, then we can apply stark's observation. This center must be equidistant from a point in A and a point in B, so assuming that A ∩ B is empty (I really don't want to think about the degenerate cases; we can always perturb our way out), we can slide the center along the perpendicular bisector of AB until we hit either a third point or the boundary.

Polygon in Polygon Algorithm

The problem is relatively simple, determine if a polygon is completely inside, completely outside, or cut by another polygon, however, the polygons may share vertices or parts of edges.
First I thought just check for every vertex in polygon A if it lies inside/outside of polygon B, this fails as soon as B cuts A, see:
Left: A would be classified as outside of B
Right: A would be classified as in the inside of B
The next Idea was, check for intersections if there are any, it's classified as cut, if there are none, check for any point of A if it's inside B. This, however, fails in cases where this checked point falls on an edge of B, where it could be both, inside or outside.
So, just check the all points of A against B, until a point is found that doesn't lie on an edge of B, this, however, can also fail, if all points of A lie on edges of B, see:
Left: A should be classified as inside
Right: A should be classified as outside
So the question remains, how can you in this case without a doubt determine if polygon A lies inside or outside polygon B, if edges and vertices may be shared.
So all vertices of the green polygon lie on the boundary of the black polygon, and there are no "obvious" x-shaped edge intersections (you should have already already eliminated those; or you could insert an artificial vertex at each intersection point to reduce the problem to the below case).
First, for every vertex of either polygon that lies on the boundary of another polygon, insert an artificial vertex to the other polygon at that point (if there isn't one already there). You do that for all green vertices, and maybe some black vertices. This is needed so that all edge intersections are simple. Two edges have no common points, one common point (at their common vertex), or all common points (both vertices and everything in between; such edges are identical).
Once all intersections are simple, the problem is easy.
For all midpoints of green edges, determine if said midpoints are inside or outside of the black polygon. Discard those that are on the boundary.
If they are all inside, the green polygon is inside the black one. If all are outside, then it is NOT inside (could be outside, or the black one could be inside the green one; reverse the roles and do the procedure again to determine which is the case). If some are inside and some outside, then there's a funny intersection.
Don't have any midpoint that is not on the boundary? The two polygons are identical.
If you want an algorithm, you can find two O(nlog(n)) algorithm in this article (Two efficient algorithms for determining intersection points between simple polygons) for the intersection of two simple polygones. Then, if you find that the intersection of two simple polygons is the same as one of them (order vertices and check their equalities), you will find the solution.
Moreover, you can find an implementation in python shapely package.

How do I determine label offset so the label is always on the outside of a polygon?

I'm have some vertices of a polygon with labels on them. I want to place the labels so that they are always on the outside of the polygon. So in the image above, all of the labels are fine except for #3 and #4, which I want to be on the bottom, outside of the polygon. So generally, how do I determine, for a particular vertex, how to offset it such that it's outside the polygon?
Since you do not show any code of your own, I will just state some ideas. If you want more details including code, show more effort of your own then ask.
I'll assume here that the polygon is assumed to be a simple polygon--one that does not intersect itself. If a polygon does intersect itself, the definition of its "inside" is not so straightforward and there are multiple definitions of the inside. I will not assume that the polygon is convex--all the interior angles are less than 180°. (That would allow an easier answer.) I'll also assume that you want the center of your label to be outside the polygon but will allow a corner or small part of the label to be inside.
First, traverse the polygon and find its "winding angle," the amount the direction angle changes during the traversal. If the polygon is simple, the angle will be either +180° or -180°. One of those means you traversed the polygon clockwise, the other one means counter-clockwise. (Which is which depends on your coordinate system: Cartesian or graphing or other.)
Then traverse the polygon again. Now that you know the direction of the polygon, at each vertex you can find whether the exterior angle goes clockwise or counterclockwise from the entering segment. Find that direction and the size of the angle, then move half that angle in that direction. Move a given distance from the vertex along that angle, and you have the position of the center of your label.
That should work well for the vast majority of polygons. In some edge cases for non-convex polygons, that location moved away from the polygon into another part of the polygon. You then reduce the distance the label is from its vertex until the label moves back into the polygon's outside.
I gave an answer to a related question: How do I efficiently determine if a polygon is convex, non-convex or complex?.
On every vertex, the incoming and outgoing edges form an angle that covers some sector. You can place the label at some distance along the bisector of this angle. You find the direction vector of the bisector by adding two unit vectors originating from the vertex in the directions of the edges.
Finding the correct bisector side requires some care. In the first place, you need to orient the polygon, i.e. check if it is clockwise or counterclockwise. This is simply done by computing the area with the shoelace formula and testing the sign.
Then, if I am right, you can test the area of triangle formed by the two edges and compare its sign to that of the whole polygon. This tells you if the angle is convex or reflex, and you know the proper side. For a convex polygon, the side is always negative for a vector computed as above.
Maybe follow something like this: First, make sure the polygon does not self-intersect, see the previous answers. Then, let the polygon be counter-clockwise oriented and represented by an array (a 2 by n+2 matrix) of its vertices (the vertices are traversed in counter-clockwise order)
double P[n+2][2] = {{pxn, pyn}, {px1, py1}, {px2, py2}, ..., {pxn, pyn}, {px1, py1}};
double Label_position[n][2];
void generate_labels(const double (&P)[n+2][2], double (&Label_position)[n][2]){
double v1[2];
double v2[2];
for(j = 1, j <= n, j = j+1) {
v1[0] = P[j][0] - P[j-1][0];
v1[1] = P[j][1] - P[j-1][1];
v2[0] = P[j+1][0] - P[j][0];
v2[1] = P[j+1][1] - P[j][1];
v1 = normalize(v1);
v2 = normalize(v2);
t = add_vectors(v1, v2);
t = normalize(t);
Label_position[j][0] = t[1] + P[j][0];
Label_position[j][1] = - t[0] + P[j][1];
}
}
This function generates the coordinates of the points at the tips of the unit angle bisector vectors pointing in the exterior of the polygon (see Yves Daoust's answer and the picture he has generated).

Point inside arbitrary polygon with partitions

Say I have a polygon. It can be a convex one or not, it doesn't matter, but it doesn't have holes. It also has "inner" vertices and edges, meaning that it is partitioned.
Is there any kind of popular/known algorithm or standard procedures for when I want to check if a point is inside that kind of polygon?
I'm asking because Winding Number and Ray Casting aren't accurate in this case
Thanks in advance
You need to clarify what you mean by 'inner vertices and edges'. Let's take a very general case and hope that you find relevance.
The ray casting (point in polygon) algorithm shoots off a ray counting the intersections with the sides of the POLYGON (Odd intersections = inside, Even = outside).
Hence it accurately gives the correct result regardless of whether you start from inside the disjoint trapezoidal hole or the triangular hole (inner edges?) or even if a part of the polygon is completely seperated and/or self intersecting.
However, in what order do you feed the vertices of the polygon such that all the points are evaluated correctly?
Though this is code specific, if you're using an implementation that is counting every intersection with the sides of the polygon then this approach will work -
- Break the master polygon into polygonal components. eg - trapezoidal hole is a polygonal component.
- Start with (0,0) vertex (doesn't matter whether (0,0) actually lies wrt your polygon) followed by the first component' vertices, repeating its first vertex after the last vertex.
- Include another (0,0) vertex.
- Include the next component , repeating its first vertex after the last vertex.
- Repeat the above two steps for each component.
- End with a final (0,0) vertex.
2 component eg- Let the vertices of the two components be (1x,1y), (2x,2y), (3x,3y) and (Ax,Ay), (Bx,By), (Cx,Cy). Where (Ax,Ay), (Bx,By), (Cx,Cy) could be anything from a disjoint triangular hole, intersecting triangle or separated triangle.
Hence , the vertices of a singular continous polygon which is mathematically equivalent to the 2 components is -
(0,0),(1x,1y),(2x,2y),(3x,3y),(1x,1y),(0,0),(Ax,Ay),(Bx,By),(Cx,Cy),(Ax,Ay),(0,0)
To understand how it works, try drawing this mathematically equivalent polygon on a scratch pad.-
1. Mark all the vertices but don't join them yet.
2. Mark the repeated vertices separately also. Do this by marking them close to the original points, but not on them. (at a distance e, where e->0 (tends to/approaches) ) (to help visualize)
3. Now join all the vertices in the right order (as in the example above)
You will notice that this forms a continuous polygon and only becomes disjoint at the e=0 limit.
You can now send this mathematically equivalent polygon to your ray casting function (and maybe even winding number function?) without any issues.

Testing tetrahedron-triangle intersection

I want to determine whether a given triangle intersects a tetrahedron. I do not want to compute the solution polygon(if it exists) itself. Is there any library/package/published practical algorithm which can be used to solve this problem directly(unlike my attempt below)?
I think as a last resort I will have to use standard polygon-polygon intersection algorithm implementations to solve this problem indirectly.
My attempt on this problem:
I thought of breaking it into the problem of polygon-polygon intersection. So for each triangular face(say T1) of the tetrahedron and the given triangle T2, I thought of doing the following:
Compute intersection(a line) between planes corresponding to each triangle, say L1.
For each triangle:
For each edge of the triangle say L2, compute point of intersection P between L1 and L2.
Test(maybe using parametric form) of L2, if the point lies on the edge L2.
If for both triangles T1 and T2, there exists at least one edge on which the intersection point P lies, then it implies that the triangles(and hence the given tetrahedron and the triangle T2) do intersect.
Create an orthonormal frame based on the triangle (origin at some vertex, axis X using the direction of some side, axis Y and Z using the direction of another side and Gram-Schmidt formulas).
Transform the coordinates of the 3 + 4 vertices to the new frame.
If all Z of the 4 tetrahedron vertices are of the same sign, there is no intersection. Otherwise, find the 3 or 4 intersection point of the edges into XY, by linear interpolation on Z.
Now you need to check for intersections between a triangle and a triangle or (convex) quadrilateral, in 2D. You can solve that by means of a standard clipping algorithm, made simple by convexity of the polygons.
As an easy optimization, note that it is useless to compute the Z of the triangle vertices (=0), and the XY of the tetrahedron vertices before you know that there is a possible intersection.
You can also speedup the polygon intersection process by first using a bounding box test.
I just found a function in CGAL library CGAL::do_intersect(Type1< Kernel > obj1,Type2< Kernel > obj2 ) for computing intersection between two geometric objects. It permits Type1 and Type2 to be Triangle_3<Kernel> and Tetrahedron_3<Kernel> respectively.

Resources