Covering N line segments with unit disks - algorithm

Given a set of N disjoint horizontal line segments (parallel to the X-axis) of variable length and variable perpendicular distances in between, we need to place minimum numbers of unit disks that intersects at least one line segment or a unit disk such that the union of line segments and disks is connected. Is there any existing algorithm or anything I can use to solve this?

Finding an optimal solution is possibly NP-hard, as #j_random_hacker says. But perhaps a greedy algorithm produces a reasonable approximation.
Sort your segments by their left endpoints, and process the segments in that order, left-to-right. At any stage, you have a connected set of segments and disks to the left of the current not-yet-incorporated segment s. Find the closest object (segment or disk) to the left endpoint of s. Suppose this distance is d. Then connect s by a sequence of ceiling(d/2) disks along the line realizing that minimum distance d. s is now incorporated, and you can move on to the next segment.
One could easily create examples where this performs poorly, but there is quite a bit of room to improve via heuristics.

Related

Nearest point to set of line segments

I have a point p, and n line segments in the 2d space. Is there a way I can preprocess the line segments so that I can efficiently (i.e. sublineraly) find the line segment closest (i.e with lowest perpendicular distance) to P?
This is a real-world problem we're trying to solve. The best (approximate) answer we have is to preprocess the ends of the line segments of the points into a quad tree/2d kd tree, and find the nearest point. This should lead to a nearly optimal answer (or maybe even correct answer) in most cases.
Alternately one can use Mongodb's geonear, which works with points as well.
Can we do better than this, particularly in terms of accuracy?
If your segments are uniformly spread and not too long, you can think of a gridding approach: choose a cell size and determine for every cell which segment crosses it (this is done by "drawing" the segments on the grid). Then for a query point, find the nearest non-empty cell, by visiting neighborhoods of increasing size, and compute the exact nearest distance to the segment(s) so found. You need to continue the search as long as the distance between the query point and the next cells does not exceed the shortest distance found so far.
If the distribution is not uniform, a quad-tree decomposition can be better.
More generally, a suitable strategy is to use any acceleration device that quickly will report a small number of candidate segments, with a guaranty: the nearest segment must be among the candidates.

Maximum area of self-intersecting polygon

I'm looking for an algorithm for calculating the maximum area in a self-intersecting polygon. As it's self-intersecting it is not trivial to calculate the area with methods such as the shoelace formula.
Example:
The polygon in the example prioritises vertices with the "smallest" letter alphabetically, sometimes going back to the same vertex in a non-alphabetical way as it is self-intersecting. Although that shouldn't make a difference in the expected area.
In this case the algorithm should output 40: the area of the square (36) plus the area of the 4 outer triangles (4).
Constraints:
The intersection points are known in advance, no need to calculate them (as the example shows)
The last point is guaranteed to connect back to the figure, i.e. no dangling lines
The polygon is always traceable, i.e. it can be drawn, without lifting the pen
Time complexity ideally not worse than O(n log(n)) where n is the number of points
Thanks for your help!
I think I've got it.
Find the vertex with the lowest x. In case of a tie, pick the one with the lowest y. This process is O(n)
Of the 2+ segments connected to the vertex found in point 1, pick the one that forms the smallest angle with the x-axis, so as to start traversing the polygon in a clockwise direction. This process is O(s) where s is the number of segments that are connected to the starting vertex.
Keep choosing the next connected segments ignoring the order of the segments in the original polygon. In case of an intersection, pick the segment that forms the smallest angle with the current segment with the direction negated, measured clockwise. This is in order to choose the segment that lays on the outside of the polygon. This process is O(n i/2) where i is the average number of segments connected to each vertex.
Once back to the starting point, calculate the area using the shoelace formula. This could actually be calculated in parallel whilst traversing the polygon in points 2 and 3.
This algorithm's worst case time complexity is O(n i/2) where n is the number of vertices and i is the average number of segments connected to each vertex. The best case complexity is O(n) for a polygon that never intersects. In my case the polygons rarely intersect so this process is close to O(n).
Build the set of segments from the points given
For each point, test a ray to see if it intersects an even or odd number of those segments.
The even intersect counts are internal points, remove them.
Shoelace algo tells you the area of the remaining shape.
Let me think of a way where this isn't n^2, because you are comparing n points with n segments.

Approximate a curve with a limited number of line segments and arcs of circles

Is there any algorithm that would allow to approximate a path on the x-y plane (i.e. an ordered suite of points defined by x and y) with a limited number of line segments and arcs of circles (constant curvature)? The resulting curve needs to be C1 (continuity of slope).
The maximum number or segments and arcs could be a parameter. An additional interesting constraint would be to prevent two consecutive circles of arcs without an intermediate line segment joining them.
I do not see any way to do this, and I do not think that there exists a method for it, but any hint towards this objective is welcome.
Example:
Sample file available here
Consider this path. It looks like a line, but is actually an ordered suite of very close points. There is no noise and the order of the sequence of points is well known.
I would like to approximate this curve with a minimum number of succession of line segments and circular arcs (let's say 10 line segments and 10 circular arcs) and a C1 continuity. The number of segments/arcs is not an objective itself but I need any parameter which would allow to reduce/increase this number to attain a certain simplicity of the parametrization, at the cost of accuracy loss.
Solution:
Here is my solution, based on Spektre's answer. Red curve is original data. Black lines are segments and blue curves are circle arcs. Green crosses are arc centers with radii shown and blue ones are points where segments potentially join.
Detect line segments, based on slope max deviation and segment minimal length as parameters. The slope of the new segment step is compared with the average step of the existing segment. I would prefer an optimization-based method, but I do not think that it exists for disjoint segments with unknown number, position and length.
Join segments with tangent arcs. To close the system, the radius is chosen such that the segments extremities are the least possible moved. A minimum radius constraint has been added for my purposes. I believe that there will be some special cases to treat in the inflexion points are far away when (e.g. lines are nearly parallel) and interact with neigboring segments.
so you got a point cloud ... for such Usually points close together are considered connected so:
you need to add info about what points are close to which ones
points close only to 2 neighbors signaling interior of curve/line. Only one neighbor means endpoint of curve/lines and more then 2 means intersection or too close almost or parallel lines/curves. No neighbors means either noise or just a dot.
group path segments together
This is called connected component analysis. So you need to form polylines from your neighbor info table.
detect linear path chunks
these have the same slope among neighboring segments so you can join them to single line.
fit the rest with curves
Here related QAs:
Finding holes in 2d point sets?
Algorithms: Ellipse matching
How approximation search works see the sublinks there are quite a bit of examples of fitting
Trace a shape into a polygon of max n sides
[Edit1] simple line detection from #3 on your data
I used 5.0 deg angle change as threshold for lines and also minimal size fo detected line as 50 samples (too lazy to compute length assuming constant point density). The result looks like this:
dots are detected line endpoints, green lines are the detected lines and white "lines" are the curves so I do not see any problem with this approach for now.
Now the problem is with the points left (curves) I think there should be also geometric approach for this as it is just circular arcs so something like this
Formula to draw arcs ending in straight lines, Y as a function of X, starting slope, ending slope, starting point and arc radius?
And this might help too:
Circular approximation of polygon (or its part)
the C1 requirement demands the you must have alternating straights and arcs. Also realize if you permit a sufficient number of segments you can trivially fit every pair of points with a straight and use a tiny arc to satisfy slope continuity.
I'd suggest this algorithm,
1 best fit with a set of (specified N) straight segments. (surely there are well developed algorithms for that.)
2 consider the straight segments fixed and at each joint place an arc. Treating each joint individually i think you have a tractable problem to find the optimum arc center/radius to satisfy continuity and improve the fit.
3 now that you are pretty close attempt to consider all arc centers and radii (segments being defined by tangency) as a global optimization problem. This of course blows up if N is large.
A typical constraint when approximating a given curve by some other curve is to bound the approximate curve to an epsilon-hose within the original curve (in terms if Minkowski sum with a disk of fixed radius epsilon).
For G1- or C2-continuous approximation (which people from CNC/CAD like) with biarcs (and a straight-line segment could be seen as an arc with infinite radius) former colleagues of mine developed an algorithm that gives solutions like this [click to enlarge]:
The above picture is taken from the project website: https://www.cosy.sbg.ac.at/~held/projects/apx/apx.html
The algorithm is fast, that is, it runs in O(n log n) time and is based on the generalized Voronoi diagram. However, it does not give an approximation with the exact minimum number of elements. If you look for the theoretical optimum I would refer to a paper by Drysdale et al., Approximation of an Open Polygonal Curve with
a Minimum Number of Circular Arcs and Biarcs, CGTA, 2008.

Intersect n line segments (on integer grid)

I have a problem that looks almost like a classic CS problem of finding all intersection points of given line segments.
The slight modification is the fact that:
1. I need to split all the segments at their intersection points
2. The resulting split segments must have integer coordinates.
If I just apply standard sweepline algorithm to find all the intersection points, and than cast coordinates of these points to integers, I sometimes get new intersections caused by the moving of intersections points to the integer grid.
I may apply this algorithm repeatedly, and probably (I can't prove it), in limited number of steps reach a state where I find no new intersections.
But I'm convinced there must be a simpler, more elegant solution.
I was trying to find a paper about such algorithm, but somehow couldn't find one that would deal with exactly this problem.
Can you tell point me to such a pape, or a description of an algorithm used by graphics libraries (such as Boost Polygon Library)?
Thank you.
This is an interesting variation to Line-segment intersection problem. Original problem of finding co-ordinates of point of intersection of these segments can be done solved using Line Sweep algorithm.
Here is an in depth article talking about Line-Sweep technique implementation for above problem. With this, intersection can be found in O(n*logn) time.
Now, in order to find the integer co-ordinates, you can cast the intersection points. But here you need to make sure about the direction of casting (which will later help in convergence).
If C in an intersection point on line segment AB, then split it into AC and CB. In AC, you cast C in direction of A, while in CB you cast it in direction of B. (By direction, I don't mean along the line segment direction, but along the half plane containing another end point.) This ensures that length of line segment will be reduced after each intersection.
PROOF: Consider, M to be maximum length of an line segment. Every time an intersection point lies on it, the length of new line segment is reduced by at least one unit. So number of iterations is bounded by M
Thus, overall iterations of your algorithm cannot exceed M.
Complexity = O(M* n *logn)

Find all line intersections with tolerance (preferably a pre existing implementation)

The Bentley-Ottmann algorithm can be used to scan for all intersections in a set of line segments in n log n time. But is there a version out there that can do this with variable precision? i.e. where lines are considered to intersect if they come closer than a certain distance?
Assuming you're talking about line segments in 2D.
AFAIK, there's nothing special about that. You simply adjust the intersects(...) function of the LineSegment class/object. Instead of returning a boolean (or other) value indicating a "real" intersection, you return true if the smallest distance between the two segments is below your predefined threshold, indicating your definition of an intersection. No change in the algorithm.
1 See:
Shortest distance between two line segments
Connect two Line Segments
If 2 segments do not intersect, than minimal distance between them is on at least one segment end point. Because of that, in your case, it is enough to test if pair of segments intersect or some segment end point is near other segment.
First test is standard in Bentley-Ottmann algorithm, second part can be done in adding and removing segment from sweep line. When segment is added to SL (left endpoint) than it is enough to test segments on SL that are near left endpoint and segments that ended on given distance from SL to left. Similar when segment is removed from SL.
I think, because of symmetry, that is enough to test only one side, e.g. adding of segment to SL.
Since end points are sorted, this search should be fast. If there is some guaranty that segments are not dense regarding tolerance, than this change doesn't change n log n running time of original algorithm.

Resources