Minimum area geometric cover for a set of line segments - algorithm

The problem I am trying to solve is:
Given a set of M points on a plane where circles can be centered and a set of N line segments which need to be covered by the circles, find the minimum area circle cover for the line segments. That is, find the radii of the circles and the centers (chosen from the M points) such that all the N line segments are covered and the total area of the circles is minimized.
Note that a line segment is covered if no part of it is OUTSIDE a circle.
Any pointers to papers or code or approximation algorithms would be great.

Edit: Just realized that the original approach (moved to the end) probably doesn't cover the case where a line segment is best covered by multiple circles very well. So I think it's better to iterate points instead of line segments, cutting the line segments down at the circle boundaries:
Find the "worst" point, i.e. the point requiring the largest additional circle area for its best circle center option with the corresponding line segment at least partially in the circle. Construct / extend the corresponding circle.
Remove fully covered line segments from the set and cut partially covered segments at the circle boundary.
Iterate until no more line segments remain.
The main idea is to keep doing what's necessary in any case. How are overlapping circles counted? Do the areas add up, or are they merged? When going back to step one in later iterations, some kind of cost heuristics will probably be able to improve the result...
The original suggestion was:
Find the "worst" line segment, i.e. the line segment requiring the largest circle for any of the circle center options and construct the corresponding circle.
Remove covered line segments from the set.
Iterate until no more line segments remain.

I just released some code to implement the suggested algorithm here:
https://github.com/usnistgov/esc-antenna-cover

Related

Greedy algorithm to find minimum number of lines that can intersect all circles in the plane

I have a problem from homework where I need to find an O(n.log(n))
greedy algorithm for the minimum number of lines required to intersect all circles in the plane, as shown with the example below.
The starting point of all the lines is (0,0) which is the origin point. The set C contains n circles, where each circle c_i has information about its radius r_i and its centre coordinate (x_i, y_i).
I have tried making greedy rules:
iterate over each circle in the set C and pick c_i
construct 3 lines from origin to c_i, where 2 lines are tangent lines that only intersect 1 point in the circle, and 1 line is secant line that goes through the circle via its center.
iterate over other remaining circles c_j (j != i) and look how many circles intersect with these lines
choose the line L_i and remove the circles that intersect with it from the plane.
continue until the plane is empty.
But I don't think that this greedy rule will achieve the optimum solution and its complexity won't be O(n.log(n)).
Any hints or full solution is OK. It is also mentioned in the problem sheet that greedy rules that give minimum + 1 lines is fine.
Since you can use one line more than the minimum, you may start with an arbitrary line. Continue line by line clockwise until all circles are intersected. Each new line should have the greatest possible angle to the last as long as no circle lies between them. The 2 tangent lines you found is useful to find how far you can go in each step, but it will be time consuming to check every circle for each step. See if you can figure out how to speed it up.
This problem looks like “covering segments by points”. You can google for that or look here https://medium.com/competitive/covering-segments-by-points-fc2c56c4b038 for instance. In your case instead of segments you have angles for each of your circles. And lines instead of points.
The only difference is that the segments don’t lie on a line but on a circle. That’s why you’re allowed one extra line in your response to be able to pick a starting point arbitrarily.

Algorithm to find the largest inscribed chord of a closed polyline

I'm looking for an algorithm to find the longest chord ("diameter") of a closed polyline. Unfortunately that polyline doesn't have to be convex, but the chord should lie entirely within the curve. Here's an example:
The solution I'm looking for is the dashed red segment.
Can you suggest an efficient algorithm for this? The best we've been able to achieve so far is the N² algorithm that tries all pairs of vertices, but even that seems incorrect since the chord doesn't necessarily pass through two vertices (or does it?).
I'm also interested in the related problem where we are looking for the biggest segment joining two vertices (or the longest part of that segment that lies within the curve if the segment in not fully inscribed). In that case, the N² algorithm works, but is slow for a large number of points.
I think the solution will always include at-least two vertex. So calculating a list all the lines segments between all the vertex, including the one extending to touch another of the polygon's line segment will do the trick.
To calculate if any of the line segment converted to ray will intersect with another line segment see the answer:
How do you check for intersection between a line segment and a line ray emanating from a point at an angle from horizontal?
After that check if our list of line segments are fully within the polygon. The following answer will allow you to check that, eliminating the ones going out of bounds.
determine if line segment is inside polygon
Now the longest of the remaining should be the answer.

finding boundaries of circle division by straight line

Given a circle, I add a straight line that goes through the circle and intersects it at two points as well as intersects every previous line at one point.
I want to repeat this procedure (adding one straight line at a time) and figure out the points that make up the boundaries of the sections the circle is divided into.
For example the first time I do this (first line) it divides the circle into 2 pieces:
When I add a second line it will divide each of these 2 pieces of the circle into 4 pieces:
When I add a third line it will divide the circle into 7 pieces:
What is an efficient algorithm to get these points?
Every time I add a line I can compute all the points that line intersects the circle and the other previous lines but I have to somehow figure out which regions these points are the boundary to
Not sure I completely understand the question but:
1) line/line intersection is achieved by Cramer. http://en.wikipedia.org/wiki/Line%E2%80%93line_intersection
2) line/circle intersection is achieved by solving a quadratic equation http://mathworld.wolfram.com/Circle-LineIntersection.html
3) you can classify the points per region by considering all signs obtained when injecting the point coordinates in the parametric equation of the splitting lines (in other words, is the point on the left or on the right of the line); this gives you a binary labeling of all regions (some of the labels being impossible).
You can also consider a ternary notation if you need to handle points known to be exactly on a line.

Find out how to flood fill a polygon with the smallest number of vector lines

Say I have a vector polygon with holes. I need to flood fill it by drawing connected segments. Of course, since there are holes, I can't fill it using a single continous polyline: I'll need to interrupt my path sometimes, then move to an area which was skipped and start another polyline there.
My goal is to find a set of polylines needed to fill the whole polygon. Better if I can find the smallest set (that is, the way I can fill the polygon with the minimum number of interruptions).
Bonus question: how could I do that for partial density fills? Say, I don't want to fill at 100% density but I want a 50% (this will require that fill lines, supposing they're parallel each other and have a single-unit width, are put at a distance of two units).
I couldn't find a similar question here, although there are many related to flood-fill algorithms.
Any ideas or pointers?
Update: this picture from Wikipedia shows a good hypotetical flood path. I believe I could do that using a bitmap. However I've got a vector polygon. Should I rasterize it?
I'm assuming here that the distance between lines is 1 unit.
A crude implementation, with no guarantee to find the minimum number of polyline, is:
Start with an empty set of polylines.
Determine minx and maxx of the polygon.
Loop x from xmin to xmax, with a step of 1. Line L is the vertical line at x.
Intersect vertical line L with your polygon (quick algorithm, easy to find). That will give you a set of segments: {(x,y1)-(x,y2)}.
For all polylines, and all segments, merge segment + end of polylines (see note 1 below). When you merge a segment and a polyline, append a small stretch at the end of the polyline (to joint it to the segment), and the segment itself. For all segments that you can't merge using that, add a new polyline in the global set.
At the end, try to merge again polylines if possible (ends close together).
Optimal algorithm for merging new segments to existing polylines should be easy to find (hashing on y), or a brute force algorithm may suffice:
number of new segments per line scan should not be too high if your polygons do not have zillions of holes,
number of global polylines at every step should not be too large,
you compare only with the end segment of each polylines, not the whole of it.
Added note (1): To cover the case where your polygon has nearly-vertical edges, the merge process should not look only at y-delta, but allow a merge if any two y range overlaps (that means end of polyline y-range overlap segment y-range).

Determining a mean camber line

Fellow programmers,
I know this is a little outside your juridistiction, but I was wondering perhaps if you have time, if you could help me with one "procedure". Not in view of math but what would be the best way to take.
This is an airfoil / profile. Usually, profiles are defined with two sets of data. One is the position of mean camber line, given in the form of x,y where x is usually given in percentages of chord length. Second set of data is thickness at percentages of chord length. Thickness is always drawn perpendicular to the camber line(!), and that gives the profile points.
Now, I have a reverse problem - I have points of a profile, and I need to determine the position of the camber line. Method of interpolation through points can vary, but it doesn't matter, since I can always interpolate as many points as I need, so it comes to linear in the end.
Remember, since the thinkness is drawn perpendicular to the camber line, the position of camber line is not mean between the points of upper and lower line of profile (called the back and face of profile).
Edit (how this is done on paper): Uhh, painfully and in large scale (I'm talking long A0 paper here, that is 1189x5945mm on a large drawing desk. You start by drawing a first camber line (CL) iteration through the midpoints (mean points) between the points of face and back at same x ordinates. After that you draw a lot of perpendicular lines, perpendicular to that CL, and find their midpoints between face and back (those points on face and back will no longer have same x values). Connect those, and that is your second iteration CL. After that you just repeat the second step of the procedure by drawing perpendicular lines onto that 2nd CL ... (it usually converges after 3 or 4 iterations).
2nd Edit: Replaced the picture with one which better shows how the thinkness is "drawn" onto the camber line (CL). Another way of presenting it, would be like picture no.2. If you drew a lot of circles, whoce center points are at the camber line, and whose radiuses were the amounts of thickness, then tangents to those circles would be the lines (would make up the curve) of the profile.
The camber line is not the mean line (mean between the points of face and back); it can coincide with it (therefore usually the confusion). That difference is easily seen in more cambered profiles (more bent ones).
3rd edit - to illustrate the difference dramatically (sorry it took me this long to draw it) between the mean line and camber line, here is the process of how it is usually done "on paper". This is a rather deformed profile, for the reason, that the difference between the two can be more easily shown (although profiles like this exist also).
In this picture the mean line is shown - it is a line formed by the mean values of face and back on the same x coordinates.
In this picture onto the mean line, perpendicular lines were drawn (green ones). Midpoints of those perpendicular lines make up for the 1st iteration of the camber line (red intermittent line). See how those circles fit better inside the airfoil compared to the first picture.
In the picture below the 2nd iteration of the camber line is shown, along with the mean line from the first picture as to illustrate the difference between the two. Those circles are fitting even better now inside (except that first one which flew out, but don't mind him).
From what I can gather from your diagram, the camber line is defined by it being the line whose tangent bisects the angle between the two tangents of the upper and lower edges.
In other words, your camber line is always the mean point between the two edges, but along a line of shortest distance between the top and bottom edges.
So, given the y-coordinates y=top(x) and y=bot(x), why don't you:
<pseudocode>
for each x:
find x2 where top(x)-bot(x2) is minimized
camber( mean(x,x2) ) = mean( top(x),bot(x2) )
</pseudocode>
and then interpolate etc.?
edit
Sorry! On second thought I think that should be
find x2 where ( (top(x)-bot(x2))^2 + (x-x2)^2 ) is minimised
obviously you should be minimising the length of that perpendicular line.
Is that right?
I'm new to stack overflow but this is a problem I have worked on quite a bit and thought I would post an alternate approach to the problem.
This approach uses the concept of a Voronoi diagram:
http://en.wikipedia.org/wiki/Voronoi_diagram
Essentially, a map is created which divides the space into regions containing one of the input points (x,y of your airfoil). The important part here is that any point within the region is closest to the input point in that region. The nodes created by this space division are equidistant to at least three of the input points.
Here is the interesting part: three equidistant points from a center point can be used to create a circle. As you mentioned, inscribed circle center points are used to draw the mean camber line because the inscribed circle measures the thickness.
We are close now. The nature of the voronoi diagram in this application means that any voronoi node inside of our airfoil region is the center point of one of these "thickness circles." (This runs into some issue very close to the LE and TE depending on your data. I usually apply some filtering here).
Basic Structure:
Create Voronoi Diagram
Extract Voronoi Nodes
Determine Nodes Which Lie Within Airfoil
Construct Mean Camber Line From Interior Nodes
Most of my work is in Matlab which has built in voronoi and inpolygon functions. As such, I'm not a huge help in developing those functions but they should be well documented elsewhere.
Trailing Edge/Leading Edge Issues
As I am sure you have experienced or know, it is difficult to measure thickness well when close to the LE/TE. This approach will contruct a fork in the nodes when the thickness circle is less than the edge radius. A check of the data for this fork will find the points which are false for the camber line. To construct the camber line all the way to the edge of the foil you could extrapolate your camber line (2nd or 3rd order should be fine) and find the intersection.
I think the best way for drawing the camber line of an airofoil is to load the profile in CATIA. After that in CATIA we can draw circles that are tangent to the both side of profile (suction side and pressure side. Then we can connect center of these circles and consequently we find the camber line accurately.
Is the mean camber line the set of points equidistant from the upper line and the lower line? If that's the definition, it's different from Sanjay's, or at least not obviously-to-me the same.
The most direct way to compute that: cast many rays perpendicular to the upper line, and many rays perpendicular to the lower line, and see where the rays from above intersect the rays from below. The intersections with the nearest-to-equal distances approximate the mean camber line (as defined here); interpolate them, with the differences in distance affecting the weights.
But I'll bet the iterative method you pasted from comments is easier to code, and I guess would converge to the same curve.

Resources