Is there a constant-time (with preprocessing) algorithm for intersecting rounded rectangle with a polygon - algorithm

I need an algorithm to quickly determine wether given 2D polygon arbitrarily translated intersects given rounded rectangle.
We're given a polygon with N vertices and dimensions of the rounded rectangle (lenghts of sides and radius of corners).
We would like to answer many question of type does the polygon with translation (dx,dy) intersect the rounded rectangle.
We're allowed to do arbitrary precomputation on the polygon.
When radius of the corners rectangle is 0, there is trivial constant time algorithm - it's enough to compute an AABB of the polygon, and then in few comparisons check if, after translation, it intersects the rectangle.
When the radius is >0 the problem seems much harder. The fact that there seems to be potentially an infinite number of "bounding rounded rectangles" suggests that there is no constant-time algorithm that can check for the intersection.
But maybe I'm missing something.
Do you know by any change any sublinear algorithm for checking if a polygon intersects a rounded rectangle?

If preprocessing of the polygon is allowed, an efficient solution is possible:
build the Minkowski sum of the polygon and rounded rectangle; this is a curvilinear polygon;
every translation of the polygon wrt the rectangle corresponds to a point wrt the Minkowski sum;
decompose the curvilinear polygon in slabs;
you can perform location of an arbitrary point in that decomposition in time O(log(N)), and this is optimal.
Below, the sum of two polygons and of a concave polygon with a disk (the loop must be excluded). This generalizes to a rounded rectangle.
To locate a point, you identify the containing slab by dichotomic search. Then inside a slab, you can identify the containing curvilinear trapezoid (delimited by line segments or circular arcs) by a second dichotomic search.
If you have few polygons, with a simple shape, you can do the preprocessing by hand. Otherwise, the Minkowski sum and slab decomposition are a little painful.

Let x1, x2, y1, y2 be the coordinates of the AABB of the rounded rectangle, with x1 < x2 and y1 < y2, and let R be the radius (of the quarter-circles).
Here is how I would handle the collision detection. Optionally, you can of course check for collision with the AABBs of both objects first, to reject early. Then, for each line in the polygon:
check for intersection with the rectangle made from the following points:
(x1, y1+R), (x1, y2-R), (x2, y1+R), (x2, y2-R)
check for intersection with the rectangle made from the following points:
(x1+R, y1), (x1+R, y2), (x2-R, y1), (x2-R, y2)
check for intersection with each of the circles in the corners, that is the circles or radius R and centers:
(x1+R, y1+R), (x1+R, y2-R), (x2-R, y1+R), (x2-R, y2-R)
If any of these three checks gives an intersection, then the polygon intersects the rounded rectangle or is completely inside. Of course, you can check whether a point of the polygon is outside the rounded rectangle using the same method (you can easily do it at the same time as the intersection checks). Because a rounded rectangle is a convex shape, this is sufficient to say that the polygon is not completely inside.
That's O(N) where N is the number of sides of your polygon. If that's the complexity you are thinking of when you say "constant-time", then I don't believe there is any kind of preprocessing that can help go below O(N) in the general case.

Related

Minimum bounding rectangle of polygon

Let's say we have a class/struct Point
class Point
{
int x;
int y;
}
and a class Polygon that contains list of Points
class Polygon
{
List<Point> points;
Path(List<Point> points)
{
//some implementation
}
}
I am interested in finding the Minimal bounding rectangle points of the Polygon(https://en.wikipedia.org/wiki/Minimum_bounding_rectangle). The found minimal bounding rectangle sides might not be parallel to both axis , so I am trying to find an algorithm written in Java,C#,C++ .Can anyone propose or link such a solution, thanks!
It is possible to construct minimal bounding box (both min-area and min-perimeter) using Rotating Calipers approach.
You can find description at this wayback archive page
The minimum area rectangle enclosing a convex polygon P has a side
collinear with an edge of the polygon.
The above result dramatically restricts the range of possible
rectangles. Not only is it not necessary to check all directions, but
only as many as the polygon's number of edges.
Illustrating the above result: the four lines of support (red), with
one coinciding with an edge, determine the enclosing rectangle (blue).
A simple algorithm would be to compute for each edge the corresponding
rectangle collinear with it. But the construction of this rectangle
would imply computing the polygon's extreme points for each edge, a
process that takes O(n) time (for n edges). The entire algorithm would
then have quadratic time complexity.
A much more efficient algorithm can be found. Instead of recomputing
the extreme points, it is possible to update them in constant time,
using the Rotating Calipers. Indeed, consider a convex polygon, with a
two pair of lines of support through all four usual extreme points in
the x and y directions. The four lines already determine an enclosing
rectangle for the polygon. But unless the polygon has a horizontal or
vertical edge, this rectangle is not a candidate for the minimum area.
However, the lines can be rotated until the above condition is
satisfied. This procedure is at the heart of the following algorithm.
The input is assumed to be a convex polygon with n vertices given in
clockwise order.
Compute all four extreme points for the polygon, and call them xminP,
xmaxP, yminP ymaxP.
Construct four lines of support for P through all four points. These
determine two sets of "calipers".
If one (or more) lines coincide with an edge, then compute the area of
the rectangle determined by the four lines, and keep as minimum.
Otherwise, consider the current minimum area to be infinite.
Rotate the lines clockwise until one of them coincides with an edge of
its polygon.
Compute the area of the new rectangle, and compare it to the current
minimum area. Update the minimum if necessary, keeping track of the
rectangle determining the minimum.
Repeat steps 4 and 5, until the lines have been rotated an angle
greater than 90 degrees. Output the minimum area enclosing rectangle.
Because two pairs of "calipers" determine an enclosing rectangle, this
algorithm considers all possible rectangles that could have the
minimum area. Furthermore, aside from the initialization, there are
only as many steps in the algorithm's main loop as there are vertices.
Thus the algorithm has linear time complexity.
You can do this as follows:
Find the convex hull of the polygon points. A popular method is the Graham scan.
For each edge of the convex hull, find the minimum bounding rectangle that must have one side overlapping with that edge, so that the convex hull's edge is a subsegment of that rectangle's side.
Find the two perpendicular sides of the rectangle by walking along the convex hull vertices, and projecting the vertex to the first side, retaining the two that have all other projections between them. The final opposite side can be found in a similar manner. The vertices that lie on the rectangle, should be the starting point for when this step is executed again for the next edge on the convex hull (step 2).
Calculate the size of these rectangles, and retain the minimal one.
The complexity of this algorithm is determined by the first step, which is O(nlogn). The second step is O(n), as you have a selection of one edge and 3 vertices that rotates around the convex hull, visiting each edge once, and each vertex 3 times.

Point of intersection between bezier curve and circle

I am aiming to create the following (a directed arrow that connects two nodes) :
At the moment I have this (a quadratic bezier curve drawn from the center point of one node to the center of another):
(Note I have drawn the bezier above the nodes to show where it begins and ends)
I need a method - heuristic or otherwise - to calculate the point of intersection (circled in red, above) between the bezier curve and the node's (ellipse) circumference.
With this, I could calculate the angle between the node center and the point of intersection to draw the arrow head lines at the correct location and angle.
As a last resort, I could use the quadratic Bézier formula to generate a list of points that lie along the curve and also generate a list of points that lie on the circumference of the circle and use one of the two coordinates that have the least euclidian distance between each other as my intersection point. I'm hoping any answers can leverage geometry or whatever else to better solve it.
The general problem is uneasy as the intersection equation is quartic ((X(t)-Xc)² + (Y(t)-Yc)²=R²), where X and Y are quadratic polynomials). If you have a quartic solver handy you can use it but you'll have to select the right root.
A more reasonable approach is just to intersect the circle with the line segment between the control points. This is approximate but probably unnoticeable if the circle radius is small.
If you want more accuracy, perform one or two Newton's iterations from this point.

Algorithm to Calculate the Number of Lattice Points in a Polygon

I'm trying to find the number of lattice points that strictly lie inside the boundary. I know Pick's theorem is
A = i + b/2 - 1
where A = the area of the polygon, i is the number of lattice points that lie inside the polygon, and b is the number of lattice points on the perimeter of the polygon.
I can easily find the area using the Shoelace formula, but I'm not sure how to get the points on the boundary.
I'm not really sure where to look for resource on this, so I'd appreciate links too.
What a pretty question...
Since you are talking about Pick's Theorem, I will assume all of the vertices have integer coordinates.
Your question reduces to determining how many lattice points lie on the line segment from (x1, y1) to (x2, y2). Since the answer stays the same under translation by an integer, this reduces to determining how many lattice points lie on the line segment from (0, 0) to (x, y) for arbitrary x and y.
If x=0 or y=0, the answer is 1D and trivial (i.e. x+1 or y+1).
Otherwise, the answer is gcd(x,y) + 1. You prove this by showing (a) that any lattice point between (0,0) and (x,y) must be a multiple of the "least" lattice point; and (b) that any lattice point must have coordinates that are factors of (x,y).
Finally, be careful not to double-count the vertices as you walk around the polygon.

A plane subdivision into non-overlapping regions by a set of polygons

Please see the example image:
There are a set of polygons (convex, non-convex, but not self-intersecting) in a plane. Polygon is defined by vertices – points (x and y coordinates, cartesian coordinate system).
Example set of polygons:
The first polygon is A, B, C.
The second polygon is D, E, F, G, H, I, J.
The third polygon is K, L, M, N.
The fourth polygon is O, P, Q.
Polygons divide a plane into regions. Some parts of polygons may be overlapping (like the first and the second polygon, the second polygon and the third polygon). This overlapping parts is seperate regions too. Some polygons may be inside others (like the fourth polygon inside the second polygon).
Example regions after subdivision: blue, pink, green, orange, brown and purple.
I imagine for simplicity that the plane is a rectangle with constant x, y coordinates.
The Goal
Detect the region (blue, pink, green, etc.) by the query point.
I am looking for algorithm and data structure for a plane subdivision with these assumptions.
First transform your set of polygons into a set of non-overlapping polygons by iteratively looking for pairwise intersections and replacing the pair of intersecting polygons with their intersection and the original polygons minus the intersection. This might be easier and faster if you first split each polygon into a set of convex polygons (the convex polygons can simply "inherit" the "color" of the original concave polygon).
You can then put the polygons into a quad-tree or a similar data structure which allows you to quickly select candidate polygons for membership tests for a given query point.
You will need to define what is happening on edges shared between multiple polygons.
I can recommend a trapezoidal decomposition http://en.wikipedia.org/wiki/Point_location#Trapezoidal_decomposition for efficient point queries in a planar subdivision.
In your case, the subdivision is defined indirectly so there is an extra step. You can try three approaches:
1) use a general polygon intersection algorithm that you will call incrementally,
2) form the trapezoidal decompositions of the polygons and perform fusions of these trapezoidal maps,
3) modify an existing trapezoidal decomposition algorithm so that it accepts as input a subdivision formed of overlapping polygons.
You will need to use some 2D Computational Geometry library... and courage.
ALTERNATIVE:
If your precision requirements are not too high, use a bitmap and fill every polygon, changing the color when pixels already painted are met.

Formula to determine whether a line form by 2 geo points (lat, lon) intersects geo region (circle)?

It does not need to be very accurate. Does anyone know a good way to do this?
any help is much appreciated.
When you say “it does not need to be very accurate” you don’t say how inaccurate a solution you’re prepared to accept. Also, you don’t say how big the geographic region under consideration is likely to be. These two criteria make a big difference to the kind of approach that needs to be taken.
With a small regions (a few kilometres, say), a flat approximation may be good enough (for example, the Mercator projection) and some of the other responses tell you how to do that. With larger regions you have to take the Earth’s sphericity into account. And if you want inaccuracy less than a percent or so, you need to take the eccentricity of Earth into account.
I’m going to assume for the purposes of this answer that a spherical approximation is good enough, and that your points are at similar enough altitudes that we don’t need to worry about their heights.
You can convert a geographical point (ψ, λ) to Cartesian Earth-centred coordinates using the transformation
(ψ, λ) → (a cos(ψ) cos(λ), a cos(ψ) sin(λ), a sin(ψ))
where a is the mean radius of the Earth (6,371 km). So let’s suppose that the two points that define your line are p₀ and p₁; then the shortest line through p₀ and p₁ is a great circle, which defines a plane that slices the Earth into two halves, with normal n = p₀ × p₁.
Now we need to find the border of the circular region. Suppose the centre of this region is at c and that the surface radius of the region is s. Then the straight-line radius of the region is r = a sin(s/a). We’ll also need the true centre of the circular region, c’ = c cos(s/a). (This point is buried deep underground!)
We’d like to intersect the two circles and solve for the points of intersection. Unfortunately, because of numerical imprecision, the chances are that this procedure will never find any solutions because the imprecise circles will miss each other in 3 dimensions. So I suggest the following procedure: intersect the planes of the two circles, getting the dotted line shown below (unless c’ × n = 0 in which case the two circles are parallel and either c’ = o, in which case they are coincident, or else they do not intersect). Then intersect the line with the circular region.
This two-step procedure reduces the problem to two dimensions, and guarantees that a solution will be found even if numerical imprecision makes the two circles miss in 3 dimensions.
If you need more accuracy than this, then you might need to use geodetic coordinates on a reference ellipsoid such as WGS 1984.
I'd say find the closest point on the line to the center of the circle, then determine whether that point is within the circle (i.e. the distance in question is less than or equal to the circle's radius).
Outline for solving the problem: assume the Earth is a sphere of radius one centered at the origin. Convert all three lat, lon points to 3D coordinates. The two points of the line plus the origin define a plane; intersect that plane with the sphere of radius d centered on the other point. If there is no plane-sphere intersection, then the answer is the line does not intersect the region. If there is a plane-sphere intersection, then the problem is simplified to intersecting the circular region defined by the plane-sphere intersection with the shortest circular arc on the plane going between the end points of the line and centered at the origin. This is a straightforward 2D problem if you convert to the coordinate system of the plane.
This question is too vague to be answered precisely. What do you mean by
a line form by 2 geo points (lat, lon)
This can be either a great circle going through them (also called orthodrome) or it a can be a linear function of spherical coordinates (loxodrome).
BTW, I assume your circle is a circle on the surface of the sphere, right?
Assuming line is formed by points (x1, y1) and (x2, y2), and circle has radius r with origin (0,0):
Calculate:
Incidence = r^2 * [(x2 - x1)^2 + (y2 - y1)^2] - (x1 * y2 - x2 * y1)^2
Then, from the value of Incidence, we can determine the following:
Incidence < 0: No intersection
Incidence = 0: Tangent (intersection at 1 point on circle)
Incidence > 0: Intersection
It's likely your circle is not at the origin (0,0), so to fix this, just add the origin coordinates from your line coordinates in the equation above. So, if the circle is at (x3, y3), x1 in the above equation would become x1 + x3. Likewise, y1 would be y1 + y3, and the same goes for x2 and y2.
For more info check out this link

Resources