Polynom arc algorithm? - algorithm

In class we saw the followin problem but i didnt undestand the solution. Do anybody could explain me with more detail the procedure to solve this problem or give me a better solution?:
Assume that n points in the plane are given. Find a polygonal arc with n-1 sides whose vertices are given points, and whose sides do not intersect.(Adjacent sides may form a 180 angle). The number of operations shold be of order n log n.
The teacher solution was:
Sort all the points with respect to the x-coordinate; when x-coordinates are equal, take the y-coordinate into account, then connect all the vertices by line segments(in that order).

The solution of your teacher is (fortunately) good. I'll try to visualize this for you.
Just draw the points on a plot. Then you can draw a line from the leftmost point to the next point. This way, connect all points going to the right.
If all the points have different x-coordinates, that'll work out, and no lines will cross:
For the points with the same x-coordinates, we first go to the lowest (smallest y-coordinate) and then go up. No crossing there, either.

Related

Determine if Line Segment Between Polygon Vertices is "Inside" Polygon

I'm trying to find an efficient algorithm that can check if a line between two vertices in a simple (edit: simple concave) polygon contains points that lie outside the domain of the polygon. The closest question I could find is this one: https://stackoverflow.com/a/36378838/12135804
But I'm not sure the answer is quite right. It might be, in which case if someone could clarify that would be great.
The basic idea is illustrated in the below picture:
Where I would like the red line to fail and the green line to succeed. I know one can't naively test the midpoint as that wont work in every case, but finding any point on the line outside the polygon's domain should disqualify it.
I appreciate any and all help!
Edit: Forgot to include cross-post link to mathematics stack exchange:
https://math.stackexchange.com/q/4040059/892519
Let's assume that the topmost point is A and the others are named B, C ... counter-clockwise, so we know what we're talking about.
If you take the red segment B-D, the one point in between is on the left. If you take the green segment D-F, the one point in between is on the right. Now, a more interesting segment would be B-E, where C is on the left while D is on the right.
In order to determine left and right, use the vector product. The length depends on the sin function, so if you get a value less than zero it's one side and more than zero is the other side.
After a lot of googling, I finally found this answer to a stackoverflow question from ~12 years ago: https://stackoverflow.com/a/693877/12135804
Assuming the edges in the polygon follow a certain order, a simple ccw test can be created using a line's starting point (p), the next ccw point in the polygon from that starting point as an inflection point (q), and the endpoint of the line (r). For the red line BD, the test would check if B,C,D is ccw (it's not). For the green line DF, test if D,E,F is ccw (it is!). This would work even if the points are non-consecutive. However, this would fail when the order of the red-green lines is reversed. For instance, if the red line became DB, the test would check D,E,B, which would pass the ccw test.
I think a more robust solution is to search for the pair of two edges in the concave polygon that share the endpoints of the line to test. For both pairs, calculate the angle between the two edges to the x-axis. Calculate the angle of the line to the x-axis as well. If the line is within the polygon, the line's angle should lie between the max and min of the polygon edges' angles for both endpoints.
Whether to test the obtuse or acute range of angles depends on some factors, I think. The red line's angle at B w.r.t. to the x axis would be in the obtuse bound between AB and BC, and the same is true at point C. Visually, it's plain to see the acute bound is what needs to be used for the max/min test at both points. If the baseline to compute the bounds from can be chosen logically, then it can be done.
Of course, this doesn't work if the line crosses outside the polygon on the way between both endpoints, but this does handle the degenerate case for a normal line-polygon intersection test. Assuming it works in every degenerate case, that is.
I won't mark this an answer because I can't prove it.
Edit: Well, I came back to thinking about this again and decided to search for questions similar to the angular bounding I posed above, and found this: https://stackoverflow.com/a/17497339/12135804
This answer satisfies not knowing the orientation of the lines! However, it assumes the minimum bound between A and B should be tested. This doesn't work for concave vertices, when AxB is < 0. In this case, a line attached to the vertex shared by lines A and B will return true if it's pointing outside the polygon, and conversely false if it's inside. I think flipping the result based on the sign of AxB should be enough to account for this, though. (a hunch that is verified in this related answer: https://stackoverflow.com/a/43384516/12135804)

Algorithm to connect multiple points without inclusion

I am searching for an algorithm to connect multiple points without including one of the points. The requirement is that all points are connected but no points are in the interior of the resulting polygon. I was not sure what the technical term for this could be and did not find anything to solve my problem. The setting might look similar to this:
Setting
I am not looking for a convex hull algorithm since it might include some points (In the image 2,6,8). The result should be close to the convex hull (as far as possible) but satisfy the requirement of not including any points. Any suggestions?
Start with a point then go to another one in a clockwise (or counter-clockwise fashion). According to Green's Formula you should be integrating the area (in the discrete case it amounts to counting your vertices).
clockwise procedure: Say you start with the top-most point xi
from all points right side of xi, pick the nearest below xi
if not existing: from all points left side of xi, pick the nearest below xi
if your reached the bottom-most point, you go now up but with the opposite recipe (i.e. check the left side first, then the right side)
you can start with 0->1, 1->2, .. n-1 -> n, n->0
Now look at these lines and see if any of them cross over.
If line a-b crosses line c-d, delete these two lines and create two new lines, line a-c and line a-d.
Since we are removing crossings, the total length of all the lines is always decreasing, so it should converge to something with zero crossings and everything connected..

Programming puzzle related to binary search

I am trying to solve the following question which was part of a programming contest:
PROBLEM ID : CIELLAND
Chef Ciel develops a new island with her restaurants. In the island, Ciel intends to built N restaurants, and the coordinate of the i-th restaurant will be (xi, yi). In addition, Ciel is going to create K roads, whose location is not decided yet. Each road must be a infinitely long straight line.
Let di be the distance between the i-th restaurant and the nearest road from the i-th restaurant. Ciel would like to create K roads which minimize max(d1, d2, ..., dN). Your task is to calculate the minimal value of max(d1, d2, ..., dN).
Any ideas as to how I should approach it? Also, the contest editorial is out ( http://www.codechef.com/wiki/march-2012-cook-problem-editorials ) but I cannot understand the solution.
Any help regarding the approach to be followed would be much appreciated.
At a high level, they are reformulating the problem so that it is easier to solve. By casting in the light below, they limit the number of possible lines to consider.
Problem A: There are N circles. The center of the i-th circle is (xi,
yi) and all circles have the radii R. And let we can draw X lines such
that any circle intersects with at least one line. What is the minimal
X?
To explain further, lets rephrase the problem A in words: The restaurants are sticklers for rules and there is a rule that says all restaurants must agree on a single maximum distance from the road - this'll be R. The circle created by the restaurant and R represents the place where a line needs to intersect to satisfy this requirement. The new problem asks the minimum number of roads to do this.
If this is not possible in under K roads, then something has to change. We can't add roads per the original problem, but we can modify R. This is where binary search comes in, but we have to solve problem A first.
Now, let's consider solving Problem A. At first, the lines can be
limited to common tangents to two circles. Because if a line
intersects with some (at least 2) circles, we can move the line such
that a moved line intersects with the same circles, and the moved line
is one of common tangents. If a line intersects less than 2 circles,
it is useless (but be careful of the case N = 1). There are at most 4
lines that is common tangents to two circles, so we consider at most 2
* N * (N-1) lines.
The important part is this, we need to find lines that intersect more than one circle. At most four lines from each pair of circle need be considered, check the source codes for implementation.
The next big step is the dynamic programming which find the minimum number of lines to cover all the circles. The 'mask' is a bitmask indicating which circles have been hit as each line is considered.
This solves the problem, but now we have to convert back. Remember R? We can now binary search to find the minimum R such that X<=K. In terms of my reformulation of Problem A, its the smallest distance all restaurant will agree to and still be serviced by a road
Hope that helps, tricky, but interesting problem.
You should be able to solve it as k means clustering problem. Initially seed with a bunch of lines. Then iteratively update points assignment to lines and optimalline given points.

polygon union without holes

Im looking for some fairly easy (I know polygon union is NOT an easy operation but maybe someone could point me in the right direction with a relativly easy one) algorithm on merging two intersecting polygons. Polygons could be concave without holes and also output polygon should not have holes in it. Polygons are represented in counter-clockwise manner. What I mean is presented on a picture. As you can see even if there is a hole in union of polygons I dont need it in the output. Input polygons are for sure without holes. I think without holes it should be easier to do but still I dont have an idea.
Remove all the vertices of the polygons which lie inside the other polygon: http://paulbourke.net/geometry/insidepoly/
Pick a starting point that is guaranteed to be in the union polygon (one of the extremes would work)
Trace through the polygon's edges in counter-clockwise fashion. These are points in your union. Trace until you hit an intersection (note that an edge may intersect with more than one edge of the other polygon).
Find the first intersection (if there are more than one). This is a point in your Union.
Go back to step 3 with the other polygon. The next point should be the point that makes the greatest angle with the previous edge.
You can proceed as below:
First, add to your set of points all the points of intersection of your polygons.
Then I would proceed like graham scan algorithm but with one more constraint.
Instead of selecting the point that makes the highest angle with the previous line (have a look at graham scan to see what I mean (*), chose the one with the highest angle that was part of one of the previous polygon.
You will get an envellope (not convex) that will describe your shape.
Note:
It's similar to finding the convex hull of your points.
For example graham scan algorithm will help you find the convex hull of the set of points in O (N*ln (N) where N is the number of points.
Look up for convex hull algorithms, and you can find some ideas.
Remarques:
(*)From wikipedia:
The first step in this algorithm is to find the point with the lowest
y-coordinate. If the lowest y-coordinate exists in more than one point
in the set, the point with the lowest x-coordinate out of the
candidates should be chosen. Call this point P. This step takes O(n),
where n is the number of points in question.
Next, the set of points must be sorted in increasing order of the
angle they and the point P make with the x-axis. Any general-purpose
sorting algorithm is appropriate for this, for example heapsort (which
is O(n log n)). In order to speed up the calculations, it is not
necessary to calculate the actual angle these points make with the
x-axis; instead, it suffices to calculate the cosine of this angle: it
is a monotonically decreasing function in the domain in question
(which is 0 to 180 degrees, due to the first step) and may be
calculated with simple arithmetic.
In the convex hull algorithm you chose the point of the angle that makes the largest angle with the previous side.
To "stick" with your previous polygon, just add the constraint that you must select a side that previously existed.
And you take off the constraint of having angle less than 180°
I don't have a full answer but I'm about to embark on a similar problem. I think there are two step which are fairly important. First would be to find a point on some polygon which lies on the outside edge. Second would be to make a list of bounding boxes for all the vertices and see which of these overlap. This means when you iterate through vertices, you don't have to do tests for all of them, only those which you know have a chance of intersecting (bounding box problems are lightweight).
Since you now have an outside point, you can now iterate through connected points until you detect an intersection. If you know which side is inside and which outside (you may need to do some work on the first vertex to know this), you know which way to go on the intersection. Then it's merely a matter of switching polygons.
This gets a little more interesting if you want to maintain that hole (which I do) in which case, I would probably make sure I had used up all my intersecting bounding boxes. You also didn't specify what should happen if your polygons don't intersect at all. But that's either going to be leave them alone (which could potentially be a problem if you're expecting one polygon out) or return an error.

Largest triangle from a set of points [duplicate]

This question already has answers here:
Closed 12 years ago.
Possible Duplicate:
How to find largest triangle in convex hull aside from brute force search
I have a set of random points from which i want to find the largest triangle by area who's verticies are each on one of those points.
So far I have figured out that the largest triangle's verticies will only lie on the outside points of the cloud of points (or the convex hull) so i have programmed a function to do just that (using Graham scan in nlogn time).
However that's where I'm stuck. The only way I can figure out how to find the largest triangle from these points is to use brute force at n^3 time which is still acceptable in an average case as the convex hull algorithm usually kicks out the vast majority of points. However in a worst case scenario where points are on a circle, this method would fail miserably.
Dose anyone know an algorithm to do this more efficiently?
Note: I know that CGAL has this algorithm there but they do not go into any details on how its done. I don't want to use libraries, i want to learn this and program it myself (and also allow me to tweak it to exactly the way i want it to operate, just like the graham scan in which other implementations pick up collinear points that i don't want).
Don't know if this help, but if you choose two points from the convex hull and rotate all points of the hull so that the connecting line of the two points is parallel to the x-Axis, either the point with the maximum or the one with the minimum y-coordinate forms the triangle with the largest area together with the two points chosen first.
Of course once you have tested one point for all possible base lines, you can remove it from the list.
Here's a thought on how to get it down to O(n2 log n). I don't really know anything about computational geometry, so I'll mark it community wiki; please feel free to improve on this.
Preprocess the convex hull by finding for each point the range of slopes of lines through that point such that the set lies completely on one side of the line. Then invert this relationship: construct an interval tree for slopes with points in leaf nodes, such that when querying with a slope you find the points such that there is a tangent through those points.
If there are no sets of three or more collinear points on the convex hull, there are at most four points for each slope (two on each side), but in case of collinear points we can just ignore the intermediate points.
Now, iterate through all pairs of points (P,Q) on the convex hull. We want to find the point R such that triangle PQR has maximum area. Taking PQ as the base of the triangle, we want to maximize the height by finding R as far away from the line PQ as possible. The line through R parallel to PQ must be such that all points lie on one side of the line, so we can find a bounded number of candidates in time O(log n) using the preconstructed interval tree.
To improve this further in practice, do branch-and-bound in the set of pairs of points: find an upper bound for the height of any triangle (e.g. the maximum distance between two points), and discard any pair of points whose distance multiplied by this upper bound is less than the largest triangle found so far.
I think the rotating calipers method may apply here.
Off the top of my head, perhaps you could do something involving gridding/splitting the collection of points up into groups? Maybe... separating the points into three groups (not sure what the best way to do that in this case would be, though), doing something to discard those points in each group that are closer to the other two groups than other points in the same group, and then using the remaining points to find the largest triangle that can be made having one vertex in each group? This would actually make the case of all points being on a circle a lot simpler, because you'd just focus on the points that are near the center of the arcs contained within each group, as those would be the ones in each group furthest from the other two groups.
I'm not sure if this would give you the proper result for certain triangles/distributions of points, though. There may be situations where the resultant triangle isn't of optimal area, either because the grouping and/or the vertex choosing aren't/isn't optimal. Something like that.
Anyway, those are my thoughts on the problem. I hope I've at least been able to give you ideas for how to work on it.
How about dropping a point at a time from the convex hull? Starting with the convex hull, calculate the area of the triangle formed by each triple of adjacent points (p1p2p3, p2p3p4, etc.). Find the triangle with minimum area, then drop the middle of the three points that formed that triangle. (In other words, if the smallest area triangle is p3p4p5, drop P4.) Now you have a convex polygon with N-1 points. Repeat the same procedure until you are left with three points. This should take O(N^2) time.
I would not be at all surprised if there is some pathological case where this doesn't work, but I expect that it would work for the majority of cases. (In other words, I haven't proven this, and I have no source to cite.)

Resources