Algorithm for finding empty areas - algorithm

does anybody know of a good algorithm for this task:
a multi polygon contains the reserved areas
find an empty position for the given polygon which is closest to its original position but does not intersect the reserved areas
I have implemented some very basic algorithm which does the job but far from optimally.
Thank You!
Edit:
my solution basically does the following:
move given polygon in all possible directions dx and dy
check wether the new intersection is less than the previous intersection
if so, use new position and make sure that you don't move your polygon back and forth at the same position
repeat these steps a maximum of N times
Example: it is intended for placing text which should not overlap with each other.

One method that immediately pops into my mind is to shoot a ray (i.e. measure a line segment) from the original position to every vertex of the polygon. Do a comparison on those distances, and then based on those comparisons, narrow it down to the minimally far away line segment of the polygon. Compute the perpendicular intersection of that line with the origin, and you'll get the minimally far away point. If the vertex comparisons don't lead you down the right path, just shoot off lines in random directions, and just stop when you're happy with the result. It doesn't sound like you require optimality.

Let's look at the original problem: making sure that one piece of text doesn't overlap another. Presumably this is for labelling a map. The way I do it is this: draw the text invisibly, checking for overlap (by using a specialised graphics context that instead of drawing a pixel, checks whether a pixel is already there) then try another position along the line on which the text is to be placed - usually a street. I try the middle of the line first, then successive positions further and further left and right of the middle. If that fails I try again with a condensed (narrower) font.

Related

How does the Even-Odd Algorithm count polygon edges?

I am wondering how the even-odd algorithm works for identifying a point in a complex polygon.
What I know right now is that it will do the horizontal search from most left to the point and count the number of edges touched.
However, what happens if the edges touched is in an intersection of 2 edges? how does it count?
Example of polygons:
The way I like to do it, which works for integer as well as floating-point coordinates, is:
for non-horizontal segments, each segment includes its bottom-most point but not its top-most point.
do not include the horizontal segments at all in the even-odd count.
This ensures that the even-odd count is correct for every point inside the polygon and every point outside, but it's not entirely consistent about points exactly on the boundary. If it matters to you, you may want to add a rule that any point that is actually on a segment is included in the polygon.
there are more ways of dealing with this problem but the safest I know of is to
Change ray direction slightly
this is numerically safe but implementation is not as easy as it sounds. Either change entire ray and compute from the start or change somewhere before the hit in question.
You need to ensure that you do not form close loops for example by zig zag pattern (so you alternate between turning CW and CCW within some cone from the original direction).
In case where ray is exactly parallel to and also touching an edge of your polygon either ignore such edge or count it twice or change the ray direction again.
Changing ray direction is always safe as it avoids singularities and numerical instabilities.
btw. This inside polygon algorithm you are using is well known by name Hit test

Algorithm for getting an area from line data (CAD fill algorithm)

I am searching for an algorithm which calculates, from a list of lines, the area a given point (P) is in. The lines are stored with x and y coordinates, the resulting area schould be stored as a polygon which may has holes in it.
Here two images to illustrate what I mean:
Many CAD applications use such algorithms to let the user hatch areas. I don't know how to call such a method so I don't really know what to search for.
Edit 1: To clearify what I'm looking for:
I don't need an algorithm to calculate the area of a polygon, I need an algorithm which returns the polygon which is formed by lines around P. If P is outside any possible polygon, the algorithm fails.
(I also edited the images)
Edit 2: I read the accepted answer of this possible duplicate and it seams I'm looking for a point location algorithm.
I also stumpled across this site which does exactly explains what I'm looking for and more important it led me to the open-source CGAL library which provides the functionality to do such things. Point 4.6 of the CGAL manual gives an example how to use this library to form a region from a bunch of line segments.
One way to do it is to imagine a line from P to infinity. For each polygon test each edge to see if it crosses the line. Count up how many lines cross. If its even then the point is outside the polygon, if its odd then the point is inside the polygon.
This is a fairly standard mathematical result. If you want to get a little deeper into the subject have a look at https://en.wikipedia.org/wiki/Winding_number.
I did a fairly similar things earlier this week Detecting Regions Described by Lines on HTML5 Canvas
this calculates a the polygon around a point given a set of lines. You can see a working example at the jsfiddle mentioned in the answer
the difference is that it uses infinite mathematical lines rather than line segments, but it could easily be modified for this example.
An outline algorithm
First construct two data-structures one of line-segments one of intersection-points of line-segments. In each record which two lines give each intersection, so you can flip from
one to the other. You can get this by pair-wise intersection of line-segments.
It might be easiest to cut the segments at the intersection points so each segment only have two solutions on it, one at each end. We assume we have done this.
Prune the data-structures, remove all line-segments with no intersections and only one segment - these cannot contribute.
Find possible starting lines. You could calculate the distance from each line to the point and take the smallest. You could check for intersections with a line from the point to infinity.
Walk around the polygon anti-clockwise. With you starting line find the most anti-clockwise end. At that point find the most anti-clockwise segment. Follow that and repeat. It may happen that closed loop is formed, in which case discard all the segments in the loop. Continue until you get back to the starting point.
Check if the polygon actually encloses the point. If so we are done. If not discard segments in the polygon and start again.

Is Point inside a polygon?

Given a list of points that represent the polygon in 2D, how can I determine if the point is inside the polygon.
Please note that the polygon can be either concave or convex. You can also make any assumptions about the order of the points.
The best approach to doing this is to draw a line in any direction from your point, and count the number of times that you cross the boundary of the object. If you hit the boundary an even number of times, you are outside the object, if an odd, you are inside. It is usually easiest to go along one of the axis to make this determination.
Essentially, you just have to find a way to determine if you cross a point. Use the slope of a line equation(m=(y1-y2)/(x1-x2), y=m*x(x-x1)+y1, and see if you cross within the boundaries that the point is valid. Given this equation for the line between the points, determine where your line crosses this line, and figure out if it is within the range of the line.
Incidentally, the same method works for any arbitrary dimension, just determining if you hit the face becomes more difficult.
To show a couple of examples, I've drawn a simple illustration, showing both what happens inside and outside, even with a weird shape.
Incidentally, if you hit a corner, it counts for the number of times you make a transition from inside to outside.
Select a point outside of the polygon. Draw a line between your´s and the point outside. If the line intersects the polygon an odd number of times, its inside, otherwise its outside. Zero intersections are also outside. However, this only workes for non overlapping polygons
It's a known problem with many solutions, just google it.
And read this :
http://en.wikipedia.org/wiki/Point_in_polygon
Take an arbitrary line from your point, to any point definitely outside your polygon (i.e. outside of the bounds). Check how many times that line intersects with one of the edges of your polygon. If the value is odd, the point is inside.
When checking, be careful of lines that go through a vertex, where your test may indicate two edge crossings.

Elegant "Left-of" test for Polyline

Given:
(X,Y) coordinate, which is the position of a vehicle.
Array of (X,Y)'s, which are vertices in a polyline. Note that the polyline consists of straight segments only, no arcs.
What I want:
To calculate whether the vehicle is to the left or to the right of the polyline (or on top, ofcourse).
My approach:
Iterate over all line-segments, and compute the distance to each segment. Then for the closest segment you do a simple left-of test (as explained here for instance).
Possible issues:
When three points form an angle smaller than 90 degrees (such as shown in the image blow), a more complicated scenario arises. When the vehicle is in the red segment as shown below, the closest segment can be either one of the two. However, the left-of test will yield right if the first segment is chosen as the closest segment, and left otherwise. We can easily see (at least, I hope), that the correct result should be that the vehicle is left of the polyline.
My question:
How can I elegantly, but mostly efficiently take care of this specific situation?
My fix so far:
Compute for both segments a point on that segment, starting from the vertex point.
Compute the distance from the vehicle to both of the points, using Euclidian distance
Keep the segment for which the computed point is the closest.
I am not very happy with this fix, because I feel like I am missing a far more elegant solution, my fix feels rather "hacky". Efficiency is key though, because it is used on a realtime embedded system.
Existing codebase is in C++, so if you want to write in a specific language, C++ has my preference.
Thanks!
[edit]
I changed my fix, from a perpendicular point to a parallel point, as I think it is easier to follow the line segment than compute the outward normal.
This topic has been inactive for so long that I believe it's dead. I have a solution though.
However, the left-of test will yield right if the first segment is
chosen as the closest segment, and left otherwise.
You've used slightly ambiguous language. I'm gonna use segments to speak of the line segments in the polyline and quadrants to speak of the areas delimited by them. So in your case, you'd have a red quadrant which seems to be on the right of one segment and on the left of the other.
If the left-of test yields different answers for different segments, you should redo the test on the segments themselves. In your case, you'd have:
The quadrant is on the RIGHT of the first segment
The quadrant is on the LEFT of the second segment
Both segments disagree on where the quadrant lies, so you do two further disambiguation tests:
The second segment is on the RIGHT of the first segment
The first segment is on the RIGHT of the second segment
This allows us to conclude that the second segment is in between the first segment and the quadrant—since each of those two lies on a different side of the second segment. Therefore, the second segment is "closer" to the quadrant than the first and it's answer to the left-right test should be used as the correct one.
(I'm almost sure you can do with only one of the two disambiguation tests, I've put both in for clarity)
For the sake of completeness: I believe this solution also accounts for your demands of efficiency and elegance, since it uses the same method you've been using from the start (the left-of test), so it meets all the conditions specified: it's elegant, it's efficient and it takes care of the problem.
Let infinity = M where M is big enough. You can consider that everything is in the square [-M,M]x[-M,M], split the square with your polyline and you have now two polygons. Then checking if the car is in a given polygon can be done very simply with angles.
I consider that your first point and your last point have M in there coordinates. You may need to add some of these points to have a polygon: (-M,-M), (M,-M), (M,M) and (-M,M).
Once you have a polygon for the left of the polyline, sum the angles OĈP where O is a fixed point, C is the car and P is a point of the polygon. If the sum is 0 then the car is outside of the polygon, else it is inside.
Just a quick idea: would it be possible to connect the last and first vertex of your polyline, so that it would become a polygon? You could then do a simple inside/outside check do determine whether the vehicle is left/right of the line (this ofcourse depends on the direction of the polygon).
However, this method does assume that the polygon is still not self-intersecting after connecting the last and first vertex.
This is a standard sort of problem from computational geometry. Since you're looking to test whether a point (x0, y0) is left-of a given surface (your polyline), you need to identify which segment to test against by its height. One easy way to do this would be to build a tree of the lower point of each segment, and search in that for the test point's predecessor. Once you have that segment, you can do your left-of test directly: if it's left of both endpoints, or between them on the appropriate side, then you return true.
I am assuming here that you guarantee that the vertical extent of your polyline is greater than where you might find your query point, and that the line doesn't overlap itself vertically. The latter assumption might be quite poor.
Expansion in response to OP's comment:
Note that the angle example in the question contradicts the first assumption - the polyline does not reach the height of the search point.
One way to conceptualize my method is by sorting your segments vertically, and then iterating through them comparing your point's y-coordinate against the segments until your point is above the lower endpoint and below the higher endpoint. Then, use the endpoints of the segment to figure out the x-intercept at the given y. If the point has a lower x-cooordinate, it's to the left, and if it has a greater x-coordinate, it's to the right.
There are two ways to improve on this explanation in a real implementation, one of which I mentioned about:
Use a balanced search tree to find the right segment instead of iterating through a sorted list, to bring the time from O(n) to O(log n)
Reconceptualize the search as finding the intersection of the polyline and the horizontal line y = y0 through the search point. Then just compare the x value of the intersection against the search point.

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