How to find number of intersections between polyline and given horizontal line?Horizontal line starts from x1 and ends at x2.
I think it is about segment trees but I dont know how to implement.
Related
I have a line and a polygon . The line can be partially inside and partially outside the polygon . The line can intersect the polygon at a single point or at multiple points. The example lines are shown as below
Please refer the picture . For horizontal red colored line I would like to get list of line segments . The desired output is (A-B) (C-D) (E-F) and for vertical line I want to get line segments 1-2 .
I went through how to detemine if a line segment is inside of a polygon? and other questions of stack overflow .
but could not get most optimized algorithm to get a list of line segments inside the polygon.
I went through the following link also
https://en.wikipedia.org/wiki/Bentley%E2%80%93Ottmann_algorithm but my question is there more optimized algorithm to find line segments within the polygon ?
I am answering in the case that no preprocessing is allowed, i.e. you have a single line segment (or a few) to process for a given polygon. The polygon is general (and can be with holes).
Rotate the line to make it horizontal, and simultaneously rotate the polygon vertices.
Then a side of the polygon intersects the supporting line of the segment if the endpoints have ordinates of a different sign. In this case, you can compute the location of the intersection.
The subsegments inside the polygon are made from the ordered intersection points found between the segment endpoints.
I have a set of Line segments in 2d (each with start and end points - (x1,y1),(x2,y2))
The CGAL example sweep_line.cpp shows me how to get all the intersection points of a set o segments. Because i'm not interested in only these points, also want to get all intersected segments for each intersection point. (with id or name or etc).
I'm trying to implement Edge drawing algorithm. I obtained lines of the image, the next step is fitting lines with a given treshold, my problem is that given a matrix of 1 and 0, (1 part of the lines) go through all the pixels and start fitting lines.
The idea is to generate a minimal length initial line segment by the least squares line fitting method, and then extend this line segment by adding more pixels to it. After the detection of a minimal length initial line segment, we should walk over the remaining pixels of the chain and compute the distance of each pixel to the currently fitted line. pixels are added to the current line as long as the pixels are within a certain distance from the current line. we continue adding pixels to the current line segment
until we turn a corner and the direction of the line changes. At that point, we output the current line segment. The remaining pixels of the chain are then processed recursively to extract further line segments.
My problem is that I don't know how to start going over the pixels...and if there is a specific direction I should first take...
I agree with flawr. Without more info like input image and wanted result example is very hard to answer. I guess you got incomplete contours of some object and want to regress/extrapolate the gaps in 2D space. In that case I would:
obtain the visible contour lines
You already have this.
sort the lines by its direction angle
If line(i) endpoints are A(i),B(i) then:
ang(i)=atan2(B(i).y-A(i).y,B(i).x-A(i).x)
merge lines
merge all lines that has:
similar angle
are not too far
have small perpendicular distance (as if were parallel)
the merged line is not intersecting any other line
close the gaps
After merging just find all the contours edge points. These points are connected to just single line. Now you can apply the extrapolation you propose in OP but I would try to connect the closest such points to each other with simple line instead (if the connection do not cross any line).
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.
I have a bounding box at (0, 0, w, h) and a point (x, y) somewhere within that, as well as a directional vector (dx, dy) pointing in some random direction, what I am trying to do is create a line from that point, in that direction to the edge of the bounding box.
Looking at the image below, the black dot is the point, the arrow is the directional vector and the red line is the resulting line I want.
What I am doing now is to simply extend the line by the vector times some random big number that is guaranteed to place it outside the box and then using a line clipping algorithm to clip it. And this totally works, but it feels like a very hacky solution, is there a better way to do this?
First, how to find the intersecting point with a vertical line.
Let (x0,y0) be the point inside the box, and (dx,dy) its slope. And say you are trying to find intersection with vertical line y=b.
x0+tdx and y0+tdy are points on the line. So the line intersects the vertical line at y1 such that y1=y0+tdy=b (t>=0). So solve for t (t=(b-y0)/dy) and use the same t to get x1 = x0 + tdx.
Similarly you can also find intersecting point with a horizontal line.
You should find the four points where the line intersects two edges. In most cases two of them will have negative t, discard them. Of the other, pick the one with lowest t and thats your answer.
Further optimization:
Based on the sign of dx and dy, the line could intersect one of the two edges. Eg if both are positive, then it might intersect either top or right side and so on. You can calculate t for only those two edges and pick the one with lowest t.