Polygon Detection from a Set of Lines? - c++

I have a set of connected, intersecting line segments. I want to detect all polygons that result from the intersection of these line segments, as follows:
I found a paper that presents an algorithm for solving this problem, but I'm not really a computer science person so I wasn't able to understand it. Here's a link to the paper. At this moment, my plan is to 1) find all intersections, and 2) somehow use these intersections to identify the polygons. I'm able to solve (1) through brute force, but (2) is a bit trickier. I'd prefer a solution in R or C++, but any language will do.

Assuming you have your line segments always as a closed polygonal chain and you have them in some sort of edge list. And, as you said, you have the intersection points already computed (brute force means O(n^2) time, in this case that is optimal as the line segments can intersect n^2 times).
You can insert your intersection points from (1) into this list splitting the intersecting line segments, mark them as intersection points and reference to all intersecting line segments in this point. Furthermore, on every line segment two polygons are incident, thus add respective reference fields to every edge. Then just take the leftmost vertex in you input and walk along the edge list. Add to every edge that is traversed a reference to its left incident polygon (in this case) polygon number one. If you reach an intersection point, put it on some sort of stack for later recovery. Now analyse that point and continue walking on the leftmost path (between the line segment on which you reached the intersection point and all outgoing segments). At some point you reach your starting point and you have the first simple polygon closed.
Now take the first intersection point from the stack. There must be an even number of line segments that start/end there. Find a line segment that has at most one incident polygon referenced (yet) and use it as as starting segment for polygon number two. You can walk along its chain in the same manner as before. (If you reference a line segment`s right incident polygon, take the rightmost turn on an intersection point.) When your stack ist empty your are done.
Edit: After I looked one more time for a solution I found this implementation from Dan Sunday. I assume that is more useful as it is also already implemented.

Alfredo Ferreira developed c++ code for detecting polygons from a set of overlapping lines. You can find the code at his page here: http://3dorus.ist.utl.pt/tools/PolygonDetector.html
Hope this Helps

I just published my implementation which is extremely fast after trying the algo from the paper.
The basic idea is to remove the detected cycles and redo the search (remove the “ears” of the detected cycle).
I am also unsing just the line segments that have connected points to the graph. The overlapping are removed in two steps: by using the area formula, which is pretty much exact and then approximate the intersection points difference in a specific range.
https://github.com/realuptime/PolyDetector

Related

Project a line segment onto a mesh

What are the graphic/mathematical algorithms I have to look for in order to achieve the red line in the following image?
Explaining it better: I need to plot two points on the mesh and then generate a straight line segment from one point to the next. This line segment would be formed by new vertices created on every single edge in its way.
I'm currently working with CGAL and Libigl, but none of them seem to have the solution. I have tried CGAL::Surface_mesh_shortest_path but it adds too much overhead (code runs very slowly) and the line would not be guaranteed to be straight depending on the mesh deformation.
Ignoring whatever you mean as "straight", here is one simple algorithm I can think of that would produce images to the one similar shown in the question. There is no guarantee of what is produced being the shortest path. I'm just spitballing here with no knowledge on the topic, there are probably better ways.
Pick 4 variables:
The starting point
The ending point
The line's normal
A marching constant
Let's calculate a few constants from the variables:
Direction = ending point - starting point
Increment vector = normalize(Direction) * marching constant.
Begin from the starting point and march towards your ending point by some constant, checking above and below your current position for where you are on the mesh. You use the line's normal to understand the "up" and "down" directions in order to perform intersection tests.
On each intersection test, if you do not intersect for both the up and down directions, then the normal you chose will not work for the given two points and mesh, and you'll have to try a different normal. If you do end up intersecting from one of the directions, you will need to add 2 points to your final line: a point on the calculated direction line closest to the start that lies on the triangle, and a point on the calculated direction line farthest from the start that lies on the triangle. If there's both an intersection on the up and down directions, choose the up direction to work with.

Finding a point inside a Boost::Geometry::Polygon

I have a Polygon object and I'm looking for an efficient way to find any point strictly inside it (not on its boundary). What is the best way to do so?
I had the following ideas, which I don't really like:
Triangulating the polygon and reporting a point on one of the triangulation edges (too expensive).
Checking the polygon's winding direction and reporting a point located in an epsilon-distance from one of the polygon's edges (doesn't work in edge-cases).
Given a polygon, you can find the first two points where the polygon crosses a line parallel to x axis and lies between the yMin & yMax of your polygon (0 & 1 in the image below).
Any point between these points will be inside your polygon. The basic idea comes from scan converting a polygon —i.e. these are the points you would fill. The part of the line after the second point has a winding of 0 or 2, depending on your polygon.
The first two crossings (or last) has to be taken, as the crossing points are sorted along the x-axis.
Some corner cases:
If you omit all points of the polygon which just touches the line, in some cases this can fail (image below).
If there are overlapping lines in your polygon, you have to resolve those.
To avoid the first issue, make sure to take the first point as a definite crossing and the next one can be either a crossing or a point where polygon just touches the line.
This can be easily implemented without using any special functions in most languages. Since I am not familiar with Boost methods, I am posting a sketch of the basic idea in javascript.
The drawing is done using paper.js —although, the code for the algorithm outlined here itself is self contained.
You can translate this to C++ as long as you can enumerate through all points in a Boost::polygon
Here is the demo.

How to split a general closed polygon by a line segment

I need a good (robust) algorithm for splitting a polygon into two sets(left/right) by a line segment. My polygon representation is simply a list of integer coordinates(ordered clock wise, never self intersecting) and the line segment is represented by a start and end point. The line always starts and ends outside the polygon, i.e. intersects the polygon an even number of times.
Here is an example:
The output of the algorithm should be the two sets(travelling clock wise):
Left: HABCH, FGDEF
Right: HCDGH, BAB, FEF
I can identify the points A-H by iterating the polygon and checking if a polygon segment crosses the line, taking care to respect border cases. I can also determine which side each multi-line belongs to. I cannot though, for the life of me, decide how to string these segment together.
Before you suggest a general purpose clipping library: I am using boost polygon which is very good at clipping polygons against each other, but I haven't found any library which let's you clip a polygon against a line segment and it is not possible in general to turn the line segment into a polygon which I could clip with.
EDIT: I had missed FEF and the fact that a polygon can have parts on both sides of the line segment.
Ok, here is a rather simple recipe of how to arrive at the answer:
Start with the set of intersection points ordered by traveling the contour clockwise:
ABCDEFGH
Sort them according to distance from the start of line:
HCFEDGBA
We also need to remember for each point if it is a left-to-right or right-to-left intersection.
Start with any point. Let's say G. Follow the contour clockwise and add GH
to the current polygon.
Now we need to travel along the line. The
direction depends on which side of the line we are. We are on the
right side, so we need to pick the value to the right of H in the
sorted set: C. Add HC to the current polygon.
Follow the contour clockwise and add CD to the current polygon.
We are on the right side, so we need to pick the value to the right of D in the sorted set: G. Add DG to the current polygon.
We have now reached the
starting point, so let's save the polygon(GHCDG) and remove used
points from the list.
Start over with another point.
For each intersection of the polygon border with the line segment:
Add a new point to the polygon.
Remember the new points in a new-point set.
Add the original polygon to the polygon set.
For each pair of points in the new-point set:
For each polygon in the current polygon set:
If the line segment between the points is completely inside the polygon.
Replace the polygon in the polygon set with two polygons
generated by dividing the original polygon along the line
segment between the points.
For each polygon in the polygon set:
Add it to the Left result set or the Right result set.
(Note this may not be possible.
Consider your example of the segment starting between C and F:
You will end up with a polygon (GABCFG) that touches both
sides of the dividing segment. Is that a Left or a Right?
I've solved something similar once and I gave up trying to be clever.
Run round all the vertices making them into connected line segments,
starting a new segment with a new point every time you intersect the
cutting line.
Find all segments which share an end point and join them back up into one longer one.
Connect all the open ends.

RANSAC line3d fitting by 3d line segments

I am having many 3d line segments. some of them are nearly parallel
and some are oriented in to different direction. I want to avoid
outliers and to get the best line 3d to represent the given 3d line
segments.
I am bit confused how RANSAC method apply for this case...
should i find a random line first or should i consider this as a given 3d point problem.?
can anyone post me the stucture to be followed when implenting this in c++. thanks
RANSAC is a good tool to fit data to a model. If you had a single 3D line in a collection of segments, by running RANSAC and selecting the line that maximized the amount of inliers would be enough. However, since you have many lines in the collection, you should try a different approach (even a non-RANSAC one, as I tell you later).
For example, you can run first RANSAC trying to find the line that matches as many segments as possible. After finding that line, remove the inlier segments from the collection and run RANSAC again.
To create a line, you only need a segment, so building the line model is quite easy.
To decide on whether a segment fits a line, you may compute the angle between both with the dot product (the closer to 0 the better) and the distance from the middle point of the segment to the line.
Also note that you can filter out very small segments at as first step. You could save some iterations later and avoid noisy results.
I can think of a Hough transform approach as well. Since you can create a line from each segment, you can get the parameters of its line (normal or directional vector and distance to origin), quantize them to some acceptable bin-size and add a vote to those parameters in a matrix. Finally, your lines lie in the peaks of the vote matrix.

matching line segments - robust and fast way

I have 2D line segments extracted from a single image data and would like to match with 3D line segments extracted from other source. for that, first I would like to project a 3D line segment to the image space using co-linearity equation (I know exterior orientation parameters). AS both line segments are in same coordinate system now I would like to find the best matching line segment to that line.
I am looking for a fast and robust algorithm to match corresponding line segments in order to update my 3D line segments later.
If any one have an idea on this, please give some suggestions. thanks in advance.
You're looking at a problem similar to line segment intersection. So unsuprisingly, it's solutions are probably similar as well.
The straightforward approach would be to compare each 2D segment to each 3D segment, best match is the one that most closely corresponds to the predicted length and position when compared to the actual. The actual being the 2D segments. That's something like O(AB), where A is the number of 2D segments and B is the number of 3D segments.
You can speed up the method somewhat by sorting the 2D segments lexicographically, then use the same kind of algorithm I asked about in this question to obtain all line segments whose x values are within a certain amount to the expected x value of one or both of the line segments end point*. In the worst case, you could still run into O(AB), but the average time should be closer to O(B log A). Although, it's not clear as to if you can use this method based on what you've said, so this paragraph should be considered more of an outline.
Faster than O(B log A) or O(A log B) is likely to require this to be a well researched problem.
You can probably get away with 1 end point, if you lexicographically sort the 2D endpoints.