I have a maze described by walls as line segments (no given order). Given a point, I need to determine whether its inside the maze or no. Everything is in the Cartezian plane(no discretization).
My idea is to transform the problem as follows:
Given some line segments in the plane, find all polygons with vertices in the endpoints of the given segments and with sides lying on the segments (you can see in the image below that you can't assume the sides will form a subset of segments).
And then just check: if a point is only inside one polygon, then its inside of the maze, otherwise no.
The solution I have in mind would be: hash endpoints and line intersections, and then look for loops.
Any other suggestions?
Thanks!
(ignore the colors in the image)
It is enough to find boundary (outer) polygon. That can be done by finding one point on the boundary and than traversing from that point by segments in one direction. If there are more possibilities to go than choose 'outer' one. Algorithm can be described:
find boundary point
find first direction to go and go to that point
while current point is different than fist one
find next direction to go
go to next point
First point can be find as point with highest Y coordinate, if there are more like that than one with lowest X among them. We can call it upper-left point.
First direction to go: first point is connected to other points and that points have <= Y coordinate, what means that connection segments are below first point. Choose right-most of them.
Next direction to go: current point is reached by some (incoming) segment, next segment to go is furthest away in positive direction from incoming one, what is same as first segment in clock-wise direction from incoming segment.
Related
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.
I am currently working on a project that involves measuring distances all around a robot with a laser module, the robot then has to move based on the points that he gets.
I currently have access to 360 points that represent the distance from the center for each of the corresponding angles. (a distance for 0°, a distance for 1°, etc)
Here's an example of what the points look like when displayed on a 2D surface:
Circular representation of the points
What I'd like to be able to do is, rather than feeding the robot all 360 points, to feed it segments containing multiple points. For instance, the bottom part of the image would be a single segment even though the points are not completely aligned.
My question to you is, is there an existing algorithm that would help me achieve what I am trying to do?
(I'm working in python but that shouldn't really be a factor)
Thanks a lot.
Assuming your points are ordered:
For each point, look ahead by two points, if the middle point is less than some distance away from the segment between the two points, then push your endpoint 1 pt further, and check that now both of the middle points are still within some distance of your line segment. Proceed to do this until false, at which point roll back one pt and generate a segment, then set the end of that segment as the start of your next segment. Also, you could consider angles instead of just distances as there are some cases where that would be favorable. Also, if no segment can be made from a certain start point for several attempts, push the start point forward one (as not everything is going to simplify into segments)
Alternately, you could convert to Cartesian points and use the hough voting algorithm to detect lines from the resulting point-cloud.
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.
Let's assume I have a polygon and I have computed all of its self-intersections. How do I determine whether a specific edge is inside or outside according to the nonzero fill rule? By "outside edge" I mean an edge which lies between a filled region and a non-filled region.
Example:
On the left is an example polygon, filled according to the nonzero fill rule. On the right is the same polygon with its outside edges highlighted in red. I'm looking for an algorithm that, given the edges of the polygon and their intersections with each other, can mark each of the edges as either outside or inside.
Preferably, the solution should generalize to paths that are composed of e.g. Bezier curves.
[EDIT] two more examples to consider:
I've noticed that the "outside edge" that is enclosed within the shape must cross an even number of intersections before they get to the outside. The "non-outside edges" that are enclosed must cross an odd number of intersections.
You might try an algorithm like this
isOutside = true
edge = find first outside edge*
edge.IsOutside = isOutside
while (not got back to start) {
edge = next
if (gone over intersection)
isOutside = !isOutside
edge.IsOutside = isOutside
}
For example:
*I think that you can always find an outside edge by trying each line in turn: try extending it infinitely - if it does not cross another line then it should be on the outside. This seems intuitively true but I wonder if there are some pathological cases where you cannot find a start line using this rule. Using this method of finding the first line will not work with curves.
I think, you problem can be solved in two steps.
A triangulation of a source polygon with algorithm that supports self-intersecting polygons. Good start is Seidel algorithm. The section 5.2 of the linked PDF document describes self-intersecting polygons.
A merge triangles into the single polygon with algorithm that supports holes, i.e. Weiler-Atherton algorithm. This algorithm can be used for both the clipping and the merging, so you need it's "merging" case. Maybe you can simplify the algorithm, cause triangles form first step are not intersecting.
I realized this can be determined in a fairly simple way, using a slight modification of the standard routine that computes the winding number. It is conceptually similar to evaluating the winding both immediately to the left and immediately to the right of the target edge. Here is the algorithm for arbitrary curves, not just line segments:
Pick a point on the target segment. Ensure the Y derivative at that point is nonzero.
Subdivide the target segment at the Y roots of its derivative. In the next point, ignore the portion of the segment that contains the point you picked in step 1.
Determine the winding number at the point picked in 1. This can be done by casting a ray in the +X direction and seeing what intersects it, and in what direction. Intersections at points where Y component of derivative is positive are counted as +1. While doing this, ignore the Y-monotonic portion that contains the point you picked in step 1.
If the winding number is 0, we are done - this is definitely an outside edge. If it is nonzero and different than -1, 0 or 1, we are done - this is definitely an inside edge.
Inspect the derivative at the point picked in step 1. If intersection of the ray with that point would be counted as -1 and the winding number obtained in step 3 is +1, this is an outside edge; similarly for +1/-1 case. Otherwise this is an inside edge.
In essence, we are checking whether intersection of the ray with the target segment changes the winding number between zero and non-zero.
I'd suggest what I feel is a simpler implementation of your solution that has worked for me:
1. Pick ANY point on the target segment. (I arbitrarily pick the midpoint.)
2. Construct a ray from that point normal to the segment. (I use a left normal ray for a CW polygon and a right normal ray for a CCW polygon.)
3. Count the intersections of the ray with the polygon, ignoring the target segment itself. Here you can chose a NonZero winding rule [decrement for polygon segments crossing to the left (CCW) and increment for a crossing to the right (CW); where an inside edge yields a zero count] or an EvenOdd rule [count all crossings where an inside edge yields an odd count]. For line segments, crossing direction is determined with a simple left-or-right test for its start and end points. For arcs and curves it can be done with tangents at the intersection, an exercise for the reader.
My purpose for this analysis is to divide a self-intersecting polygon into an equivalent set of not self-intersecting polygons. To that end, it's useful to likewise analyze the ray in the opposite direction and sense if the original polygon would be filled there or not. This results in an inside/outside determination for BOTH sides of the segment, yielding four possible states. I suspect an OUTSIDE-OUTSIDE state might be valid only for a non-closed polygon, but for this analysis it might be desirable to temporarily close it. Segments with the same state can be collected into non-intersecting polygons by tracing their shared intersections. In some cases, such as with a pure fill, you might even decide to eliminate INSIDE-INSIDE polygons as redundant since they fill an already-filled space.
And thanks for your original solution!!
Puzzle : Given an even number of points in general positions on the plane (that is, no three points co-linear), can you partition the points into pairs and connect the two points of each pair with a single straight line such that the straight lines do not overlap?
My Solution : One simple approach (that seems just too simple).
Start with the point with left-most x-coordinate and then draw a line to the next least left-most x-coordinate. Then find the next least pair of points and connect and so on!
Is this correct?
Just tried it! That's one of the solutions!