Check if Line Segment is inside Polygon - geometry

What is the most efficient way to check, whether a line segment is (partly or totaly) outside of a polygon?
In the picture, the green line segements are allowed, whereas the red ones are forbidden.
Background information: This is for creating a Delaunay mesh.
One possible solution might be, to check, whether the line segment intersects any edge of the polygon or the middle point is outside the polygon. But is it really the most efficient way?

Related

What's the translation that brings one 2D polygon completely inside another?

Given two 2D polygons, how do I calculate the shortest translation that brings the first inside the second?
Assume there is a solution (i.e. the first does in fact fit inside the second)
Prefer a simple algorithm over completeness of solution. For example if the algorithm is simplified by making assumptions about the shapes having a certain number of sides, being concave, etc. then make those assumptions.
I can imagine a brute force solution, where I first calculate which are the offending vertices that lie outside the initial polygon. I'd then iterate through these external vertices and find the closest edge to each. Then I'm stuck. Each distance from an external vertex to an edge creates a constraint (a "need to move"). I then need to solve this system of constraints to find the movement that fulfills them all without creating any new violations.
I'm not sure if this can be a general solution, but here is at least a point to start with:
We want to move the green polygon into the red polygon. We use several translations. Each translation is defined by a start point and an end point.
Step 1: Start point is the mid-point between the left-most vertex and the right-most vertex in green polygon. End point, same criterion with the red polygon:
Step 2: Start point is the mid-point between the top-most vertex and the low-most vertex. End point, same criterion with the red polygon:
Notice that setps 1 & 2 are kind of centering. This method with mid points is similar to use the bounding boxes. Other way would be using circumcircles, but they are hard to get.
Step 3: Find the vertex in red polygon closest to an edge in the green polygon. You will need to iterate over all of them. Find the line perpendicular to that edge:
Well, this is not perfect. Depending on the given polygons it's better to proceed the other way: closest vertex in green to edges in red. Choose the smallest distance.
Finally, move the green polygon along that line:
If this method doesn't work (I'm sure there are cases where it fails), then you can also move the inner polygon along a line (a red edge or a perpendicular) that solves the issue. And continue moving until no issues are found.

Clipper polygon offsetting and straight line vertices

I am trying to offset a polygon using clipper, and I need all the vertices from the original polygon to be mirrored in the offset polygon. The trouble is that when you pass a polygon with vertices on a straight line, you get back a polygon without any vertices on straight lines, as I have attempted to illustrate in this diagram:
Polygon Offsetting vertices
Does anybody know of a way to modify the behaviour of clipper, or a different library that can do this for me?
Thanks
Internal routine FixupOutPolygon() removes such (usually redundant) vertices (in version 4.8). I see no option to disable it.
Read the license. If it permits to modify sources for yourself, then you could comment out it's call in the sources.

Determining if segment lies within a polygon

Given a concave polygon, how can I determine whether a segment(edge) connecting two vertices lies within the polygon? In picture below there is an edge(red) connecting two same vertices that weren't connected in original polygon. I have no idea how determine interior and exterior. Thank you for any help.
Example of polygons
If the additional segment intersects any other segment of the polygon, it is partly inside and partly outside.
Otherwise take a point on the additional segment, for example its midpoint and check if it is inside or outside. To test if a point is inside, take any ray extending from it and count the number of intersections with polygon edges. If the number of intersections is odd, it is inside.
Sounds simple, but be prepared to handle special cases like collinear lines or intersections at vertex points. That's what will make the implementation difficult.

How to test if a line intersects a convex polygon?

Assume you are given the equation of a line (in 2d), and the equations of lines that form a convex polygon (the polygon could be unbounded). How do I determine if the line intersects the polygon?
Furthermore, are there computational geometry libraries where such tasks are pre-defined? I ask because I'm interested not just in the 2D version but n-dimensional geometry.
For the 2D case, I think the problem simplifies a bit.
The line partitions the space into two regions.
If the polygon is present in only one of those regions, then the line does not intersect it.
If the polygon is present in both regions, then the line does intersect it.
So:
Take any perpendicular to the line, making the intersection with the
line the origin.
Project each vertex of the polytope onto the perpendicular.
If those projections occur with both signs, then the polygon
intersects the line.
[Update following elexhobby's comment.]
Forgot to include the handling of the unbounded case.
I meant to add that one could create a "virtual vertex" to represent the open area. What we really need is the "direction" of the open area. We can take this as the mean of the vectors for the bounding edges of the open area.
We then treat the dot product of that direction with the normal and add that to the set of vertex projections.
In geometry, typically see wikipedia a polygon is bounded.
What you are describing is usually called a polytope or a polyhedron see wikipedia
There are a few geometry libraries available, two that come to mind are boost (polygon) and CGAL. Generally, there is a distinct split between computational methods that deal with 2d,3d, and N-d - for obvious reasons.
For your problem, I would use a somewhat Binary Space Partitioning Tree approach. I would take the first line of your "poly" and trim the query line against it, creating a ray. The ray would start at the intersection of the two lines, and proceed in direction of the interior of the half-space generated by the first line of the "poly". Now I would repeat the procedure with the ray and the second line of the "poly". (this could generate a segment instead of ray) If at some point the ray (or now segment) origin lies on the outer side of a poly line currently considered and does not intersect it, then the answer is no - the line does not intersect your "poly". Otherwise it intersects. Take special care with various parallel edge cases. Fairly straight forward and works for multi-dimensional cases.
I am not fully sure, but I guess you can address this by use of duality. First normalize your line equations as a.x+b.y=1, and consider the set of points (a,b).
These must form a convex polygon, and my guess is that the new line may not correspond to a point inside the polygon. This is readily checked by verifying that the new point is on the same side of all the edges. (If you don't know the order of the lines, first construct the convex hull.)
Let's start from finite polygons.
To intersect polygon a line must intersect one of its edges. Intersection between line and an edge is possible only if two points lie on different sides from the line.
That can be easily checked with sign(cross_product(Ep-Lp,Ld)) for two points of the edge. Ep - edge point, Lp - some point on the line, Ld - direction vector of the line, cross_product(A,B)=Ax*By-Ay*Bx.
To deal with infinite polygons we may introduce "infinite points". If we have a half infinite edge with point E1 and direction Ed, its "second point" is something like E1+infinity*Ed, where infinity is "big enough number".
For "infinite points" the check will be slightly different:
cross_product(Ep-Lp,Ld)=
=cross_product(E1+infinity*Ed-Lp,Ld)=
=cross_product(E1-Lp+infinity*Ed,Ld)=
=cross_product(E1-Lp,Ld)+cross_product(infinity*Ed,Ld)=
=cross_product(E1-Lp,Ld)+infinity*cross_product(Ed,Ld)
If cross_product(Ed,Ld) is zero (the line is parallel to the edge), the sign will be determined by the first component. Otherwise the second component will dominate and determine the sign.

Projecting a line segment onto a polygon mesh

I am working on a 3d application and am currently looking for a way to project a line segment defined by two points in screen-space onto a three-dimensional polygonal mesh (in my case a triangle mesh). The goal is to find the intersection points in world-space of the line segment with the edges of the mesh.
I can only think of two ways to do this, but neither is ideal. The first is to sample the line segment (in screen-space) at small intervals and ray trace at those intervals to find the world-space coordinates where the ray hits the mesh, but this does not easily give me the intersection points of the line segment with the mesh edges.
The other way I can think of is to somehow back-project the mesh into screen-space, find the intersections there (in 2d) and then project those intersection points back to 3d. The problem with this is that the screen-space coordinate system may change between the selection of the first and second endpoints of the line segment (due to moving the camera).
If any of that was confusing, then here is an image that approximately shows what I'm trying to do (the white dots indicate the points that I want to find). However, in my case the yellow curve is simply a line segment.
[Yunjin Lee, et al. "Mesh scissoring with minima rule and part salience." 2005]
Any help is very much appreciated.
Here's my suggestion:
Project the screen line into world space (getting a plane in world space).
Intersect the plane with the triangles in the mesh, getting a set of edges.
Add the edges to a data structure that keeps only the parts of the edges that are closest to the camera plane (see the diagram below, in which the red line segments and their endpoints are the ones we want to keep). This is like building up an image via a Z-buffer, except that because we know that this set is piecewise linear, we don't have to rasterize it, we can just maintain a sorted list of endpoints.

Resources