You have given N points in 2D plane ,i need to find out the smallest radius of a circle that contain at least M points .
Approach I am using :-
I will do binary search on radius of circle .
Pick an arbitrary point P from the given set. We rotate a circle C with radius R using P as the "axis of rotation" (by convention, in the counter-clockwise direction), i.e. we keep C to touch P any time during the rotation. While C is being rotated, we maintain a counter to count the number of points C encloses.
Note that this counter only changes when some point Q enters (or leaves) the region of the circle C. Our goal is to come up with an algorithm that will increment (or decrement) this counter, whenever some other point Q ≠ P enters (or leaves) the region of C.
The state of the (rotating) circle C can be described by a single parameter θθ, where (r,θ) are the polar coordinates of the center of the circle C, if we pick P as the fixed point of the polar coordinate system. With this system, rotating C means increasing θ.
For each other point Q (≠ P), we can actually compute the range of θ for which C covers Q. Put more formally, C encloses Q whenever (iff) θ∈[α,β].
So, up to this point, the original problem has been reduced to:
What is an optimal value of θ that lies in the most number of [α,β] intervals?
The reduced problem can be solved with a pretty standard O(NlogN) algorithm.[3] This reduced problem has to be solved N times (one for each point P), hence the time complexity O(N2logN).
I am able to get the how to do this step :
For each other point Q (≠ P), we can actually compute the range of θ for which C covers Q. Put more formally, C encloses Q whenever (iff) θ∈[α,β].
So, up to this point, the original problem has been reduced to:
What is an optimal value of θ that lies in the most number of [α,β]intervals?
can you please suggest how to implement that part .
When Q enters or leaves the circle C (with radius R):
The distance between P and C's center is R (because it always is); and
The distance between Q and C's center is also R
So, if you draw a circle of radius R around Q, and a circle of radius R around P. The two points at which they intersect are the centers of C when Q enters or leaves.
Let ±θ be the angles between those centers of C and line PQ. If you draw it out you can easily see that |PQ|/2R = cos(θ), which makes it pretty easy to find the angles you're looking for.
Related
Assume you have a convex polygon P(defined by an array of points p), and a set of points S(all of them outside of P), how do you choose a point s in S such that it increases the most the area of P.
Example
I have a O(|P|) formula to calculate the area of the polygon, but I can't do this for every point in S given that
3 ≤ |P|, |S| ≤ 10^5
The big dots are the points in S
No 3 points in P u S are collinear
Given fixed points p = (px, py), q = (qx, qy) and a variable point s = (sx, sy), the signed area of the triangle ∆pqs is
|px py 1|
½ |qx qy 1|
|sx sy 1| ,
which is a linear polynomial in sx, sy.
One approach is to compute cumulative sums of these polynomials where p, q are the edges in clockwise order. Use binary search to find the sublist of edges that remain in the convex hull with a given point s, add the polynomials, and evaluate for s.
You have a method to calculate the exact area that is added by a point n (and David Eisenstat posted another), but their complexity depends on the number of sides of the polygon. Ideally you'd have a method that can quickly approximate the additional area, and you'd only have to run the exact method for a limited number of points.
As Paul pointed out in a comment, such an approximation should give a result that is consistently larger than the real value; this way, if the approximation tells you that a point adds less area than the current maximum (and with randomly ordered input this will be true for a large majority of points), you can discard it without needing the exact method.
The simplest method would be one where you only measure the distance from each point to one point in the polygon; this could be done e.g. like this:
Start by calculating the area of the polygon, and then find the smallest circle that contains the whole polygon, with center point c and radius r.
Then for each point n, calculate the distance d from n to c, and approximate the additional area as:
the triangle with area r × (d - r)
plus the rectangle with area 2 × r 2 (pre-calculated)
plus the half circle with area r × π (pre-calculated)
minus the area of the polygon (pre-calculated)
This area is indicated in blue on the image below, with the real additional area slightly darker and the excess area added by the approximation slightly lighter:
So for each point, you need to calculate a distance using √ ((xn - xc)2 + (yn - yc)2) and then multiply this distance by a constant and add a constant.
Of course, the precision of this approximation depends on how irregular the shape of the polygon is; if it does not resemble a circle at all, you may be better off creating a larger simple polygon (like a triangle or rectangle) that contains the original polygon, and use the precise method on the larger polygon as an approximation.
UPDATE
In a simple test where the polygon is a 1x1 square in the middle of a 100x100 square space, with 100,000 points randomly placed around it, the method described above reduces the number of calls to the precise measuring function from 100,000 to between 150 and 200, and between 10 and 20 of these calls result in a new maximum.
While writing the precise measuring function for the square I used in the test, I realised that using an axis-aligned rectangle instead of a circle around the polygon leads to a much simpler approximation method:
Create a rectangle around the polygon, with sides A and B and center point c, and calculate the areas of the rectangle and the polygon. Then, for each point n, the approximation of the additional area is the sum of:
the triangle with base A and height abs(yn - yc) - B/2
the triangle with base B and height abs(xn - xc) - A/2
the area of the rectangle minus the area of the polygon
(If the point is above, below or next to the rectangle, then one of the triangles has a height < 0, and only the other triangle is added.)
So the steps needed for the approximation are:
abs(xn - xc) × X + abs(yn - yc) × Y + Z
where X, Y and Z are constants, i.e. 2 subtractions, 2 additions, 2 multiplications and 2 absolute values. This is even simpler than the circle method, and a rectangle is also better suited for oblong polygons. The reduction in the number of calls to the precise measuring function should be similar to the test results mentioned above.
Task
Calculate the distance d in meters between a query-point q and a polygon P.
The query-point q is defined as tuple (latitudeq, longitudeq), the polygon P as ordered list of tuples [(latitude1, longitude1), ..., (latituden, longituden)].
Problem
I can't handle latitude and longitude as if they were x- and y-coordinates of a plane as this leads to huge errors if the polygon is not small and not near (0, 0).
Tools
I know how to calculate the distance between two points given each points latitude and longitude. I do also know how to calculate the distance between a point and a great circle. But for this task I'd need to know how to calculate the distance dist(q, 1—2) between a point q and and part of a great-circle 1—2. The distance of q would be simply min(dist(q, a—b)) ∀ a—b in P.
Question
Can you provide me a formula how to calculate the distance between a query-point q defined by a tuple (latitudeq, longitudeq) and a great-circle-arc defined by pair of latitude-longitude-tuples [(latitude1, longitude1),(latitude2, longitude2)]?
Example
If you had code to compute the distance between one point x and a geodesic line
segment s, you could repeat this for each edge of your geodesic polygon.
Let s=(a,b). s is an arc of a great circle. Rotate the sphere so that
s lies on the equator, and x follows along with the sphere rotation.
Then the latitude of x essentially tells you the distance to s: It is either
the distance from x to a, or x to b, or, if x lies in the sector above/below s, it is a simple factor (2 π r) times the latitude.
So lets imagine that I have a grid of 10x10 (can be any size, but just for the sake of example say 10), and with that grid there is 3 points marking vertexes of a triangle (again can be any amount of points delimiting any arbitrary shape).
So my question is.. Is there a way given just this information to determine programatically if any given coordinate is within that shape?
Lest say the coordinates are 3,2-7,3-5,5. Can I while iterating over the given grid pick out the cells that fall within these points?
Call P the point that you are checking, and S1,S2,...,Sn the n vertices of the shape.
Assume that P ≠ Si for all i.
Is P on the boundary?
If 1 is no, then randomly choose a line L that passes through P
Pick a point F that you know is outside the polygon
Follow the sequence of intersections of L with the shape from F until you hit P (Call the Sequence F, ..., P)
Count the sequence F, ..., P, store the value in M
If M is even, then P is in the polygon, Otherwise P is not in the polygon
NOTE: By introducing the starting point F, we change the parity mentioned in the point in polygon algorithm description on wikipedia
Recently I have started doing some research on the SAT (Separating Axis Theorem) for collision detection in a game I am making. I understand how the algorithm works and why it works, what I'm puzzled about is how it expects one to be able to so easily calculate the projection of the shape onto different axes.
I assume the projection of a polygon onto a vector is represented by line segment from point A to point B, so my best guess to find points A and B would be to find the angle of the line being projected onto and calculate the min and max x-values of the coordinates when the shape is rotated to the angle of the projection (i.e. such that it is parallel to the x-axis and the min and max values are simply the min and max values along the x-axis). But to do this for every projection would be a costly operation. Do any of you guys know a better solution, or could at least point me to a paper or document where a better solution is described?
Simple way to calculate the projection of the polygon on line is to calculate projection of all vertex onto the line and get the coordinates with min-max values like you suggested but you dont need to rotate the polygon to do so.
Here is algorithm to find projection of point on line :-
line : y = mx + c
point : (x1,y1)
projection is intersection of line perpendicular to given line and passing through (x1,y1)
perdenicular line :- y-y1 = -1/m(x-x1) slope of perpendicular line is -1/m
y = -1/m(x-x1) + y1
To find point of intersection solve the equation simultaneously :-
y = mx + c , y = -1/m(x-x1) + y1
mx + c = -1/m(x-x1) + y1
m^2*x + mc = x1-x + my1
(m^2+1)x = x1 + my1 - mc
x = (x1-my1 - mc)/(m^2+1)
y = mx + c = m(x1-my1-mc)/(m^2+1) + c
Time complexity : For each vertex it takes O(1) time so it is O(V) where V is no of vertex in the polygon
If your polygon is not convex, compute its convex hull first.
Given a convex polygon with n vertices, you can find its rotated minimum and maximum x-coordinate in n log n by binary search. You can always test whether a vertex is a minimum or a maximum by rotating an comparing it and the two adjacent vertices. Depending on the results of the comparison, you know whether to jump clockwise or counterclockwise. Jump by k vertices, each time decreasing k by half (at the start k=n/2).
This may or may not bring real speed improvement. If your typical polygon has a dozen or so vertices, it may make little sense to use binary search.
And also i shouldn't assume that the polygon is non-intersecting
I know that a convex polygon is a non intersecting polygon with the property that all the angles are less than PI in another words , the orientation is always clockwise or anticlockwise.
So i am thinking to run the graham scan which is known to be a linear time algorithm and modify it .
SO here is my algorithm
we sort the vertices by orientation (using determinants)
Select the right most vertex in the Polygon P (call it r)
Let q and p be the next and second next vertex of Polygon P (based on orientation)
while(there is a vertex in the Polygon P)
if orientation(p, q, r) == CW (clock wise , that means we changed directions)
return false
else
r = p
p = q
q = next vertex
return true
is that algorithm accurate (returns false means its not convex)
Indeed, a check whether an angle is less or more than PI can be done in constant time using determinants.
This totals to O (N).
If all the angles have the same orientation, we should still check whether the polygon is also not self-intersecting.
Here, it will suffice to add up all supplementary angles and check whether the sum is 2 * PI.
It will be fine to use floating point and check for approximate equality.
This is also O (N).
However, we should visit the vertices in the order they follow on the polygon border.
If you are given a polygon, you perhaps have that order already.
On the other hand, if you are given just a set of points on the plane, a polygon with vertices in these points is not unique in the general case.
So, there is no need to sort the vertices by anything: not only it is O (N log N), but we also lose important order information by doing so.
We can start from any vertex.
your algorithm does not work
(e.g. if the polygonal chain turns twice around the origin)
see http://hal.inria.fr/inria-00413179/en