Point in polygon on Earth globe - algorithm

I have a list of coordinates (latitude, longitude) that define a polygon. Its edges are created by connecting two points with the arc that is the shortest path between those points.
My problem is to determine whether another point (let's call it U) lays in or out of the polygon. I've been searching web for hours looking for an algorithm that will be complete and won't have any flaws. Here's what I want my algorithm to support and what to accept (in terms of possible weaknesses):
The Earth may be treated as a perfect sphere (from what I've read it results in 0.3% precision loss that I'm fine with).
It must correctly handle polygons that cross International Date Line.
It must correctly handle polygons that span over the North Pole and South Pole.
I've decided to implement the following approach (as a modification of ray casting algorithm that works for 2D scenario).
I want to pick the point S (latitude, longitude) that is outside of the polygon.
For each pair of vertices that define a single edge, I want to calculate the great circle (let's call it G).
I want to calculate the great circle for pair of points S and U.
For each great circle defined in point 2, I want to calculate whether this great circle intersects with G. If so, I'll check if the intersection point lays on the edge of the polygon.
I will count how many intersections there are, and based on that (even/odd) I'll decide if point U is inside/outside of the polygon.
I know how to implement the calculations from points 2 to 5, but I don't have a clue how to pick a starting point S. It's not that obvious as on 2D plane, since I can't just pick a point that is to the left of the leftmost point.
Any ideas on how can I pick this point (S) and if my approach makes sense and is optimal?
Thanks for any input!

If your polygons are local, you can just take the plane tangent to the earth sphere at the point B, and then calculate the projection of the polygon vertices on that plane, so that the problem becomes reduced to a 2D one.
This method introduces a small error as you are approximating the spherical arcs with straight lines in the projection. If your polygons are small it would probably be insignificant, otherwise, you can add intermediate points along the arcs when doing the projection.
You should also take into account the polygons on the antipodes of B, but those could be discarded taking into account the polygons orientation, or checking the distance between B and some polygon vertex.
Finally, if you have to query too many points for that, you may like to pick some fixed projection planes (for instance, those forming an octahedron wrapping the sphere) and precalculate the projection of the polygons on then. You could even create some 2d indexing structure as a quadtree for every one in order to speed up the lookup.

The biggest issue is to define what we mean by 'inside the polygon'.
On a sphere, every polygon (as long as the lines are not intersecting) defines two regions of the sphere. Both regions are equally qualified to be called the inside of the polygon.
Consider a simple, 1-meter on a side, yellow square around the south pole.
You can think of the yellow area to be the inside of the square OR you can think of the square enclosing everything north of each line (the rest of the earth).
So, technically, any point on the sphere 'validly' inside the polygon.
The only way to disambiguate is to select which side of the polygon you want. For example, define the interior to always be the area to the right of each edge.

Related

How to compute the set of polygons from a set of overlapping circles?

This question is an extension on some computation details of this question.
Suppose one has a set of (potentially overlapping) circles, and one wishes to compute the area this set of circles covers. (For simplicity, one can assume some precomputation steps have been made, such as getting rid of circles included entirely in other circles, as well as that the circles induce one connected component.)
One way to do this is mentioned in Ants Aasma's and Timothy's Shields' answers, being that the area of overlapping circles is just a collection of circle slices and polygons, both of which the area is easy to compute.
The trouble I'm encountering however is the computation of these polygons. The nodes of the polygons (consisting of circle centers and "outer" intersection points) are easy enough to compute:
And at first I thought a simple algorithm of picking a random node and visiting neighbors in clockwise order would be sufficient, but this can result in the following "outer" polygon to be constructed, which is not part of the correct polygons.
So I thought of different approaches. A Breadth First Search to compute minimal cycles, but I think the previous counterexample can easily be modified so that this approach results in the "inner" polygon containing the hole (and which is thus not a correct polygon).
I was thinking of maybe running a Las Vegas style algorithm, taking random points and if said point is in an intersection of circles, try to compute the corresponding polygon. If such a polygon exists, remove circle centers and intersection points composing said polygon. Repeat until no circle centers or intersection points remain.
This would avoid ending up computing the "outer" polygon or the "inner" polygon, but would introduce new problems (outside of the potentially high running time) e.g. more than 2 circles intersecting in a single intersection point could remove said intersection point when computing one polygon, but would be necessary still for the next.
Ultimately, my question is: How to compute such polygons?
PS: As a bonus question for after having computed the polygons, how to know which angle to consider when computing the area of some circle slice, between theta and 2PI - theta?
Once we have the points of the polygons in the right order, computing the area is a not too difficult.
The way to achieve that is by exploiting planar duality. See the Wikipedia article on the doubly connected edge list representation for diagrams, but the gist is, given an oriented edge whose right face is inside a polygon, the next oriented edge in that polygon is the reverse direction of the previous oriented edge with the same head in clockwise order.
Hence we've reduced the problem to finding the oriented edges of the polygonal union and determining the correct order with respect to each head. We actually solve the latter problem first. Each intersection of disks gives rise to a quadrilateral. Let's call the centers C and D and the intersections A and B. Assume without loss of generality that the disk centered at C is not smaller than the disk centered at D. The interior angle formed by A→C←B is less than 180 degrees, so the signed area of that triangle is negative if and only if A→C precedes B→C in clockwise order around C, in turn if and only if B→D precedes A→D in clockwise order around D.
Now we determine which edges are actually polygon boundaries. For a particular disk, we have a bunch of angle intervals around its center from before (each sweeping out the clockwise sector from the first endpoint to the second). What we need amounts to a more complicated version of the common interview question of computing the union of segments. The usual sweep line algorithm that increases the cover count whenever it scans an opening endpoint and decreases the cover count whenever it scans a closing endpoint can be made to work here, with the adjustment that we need to initialize the count not to 0 but to the proper cover count of the starting angle.
There's a way to do all of this with no trigonometry, just subtraction and determinants and comparisons.

Shifting Polygon inside Polygon

I'm having troubles figuring out an algorithm to solve the following problem:
I want the user to be able to snap the rectangle (Could be any type of polygon) to the 4 corners of the polygon such that it's as far inside the polygon as it can be.
What I'm trying so far:
Allow user to get the object.
Find the nearest vertice on the polygon to the rectangle.
Find the furthest vertice on the rectangle to the polygon's nearest vertice.
Use a plane to find the first intersection point with the furthest rectangle's point to the polygon's point.
Shift up or down using the corresponding x/y plane based on whether the furthest point is further in the x/y coordinate.
Keep repeating the steps above until everything is inside.
As long as the enclosing polygon is convex, you can write this as a linear programming problem and then apply https://en.wikipedia.org/wiki/Simplex_algorithm to find the answer. The smaller polygon you are putting inside can be as complicated as you want.
Your inequalities are all of the conditions to make sure that each vertex of the smaller polygon is inside of the larger. You don't have to be clever here, there is no cost to extra inequalities that don't come into play.
The function to optimize is constructed as follows. Look at the interior angle of the vertex you are trying to get close to. Draw a coordinate system at that point with one axis pointing directly into the polygon (call that axis y) and the other at right angles to the first (call that axis x). You want to minimize the y value of the nearest vertex on the polygon you are putting in. (Just put the polygon you are putting in in the middle, and search for the nearest vertex. Use that.
The solution that you find will be the one that puts the two vertices as close together as possible subject to the condition that the smaller polygon has to be inside of the larger.

Getting the boundary of a hole in a 3d plane

I have a set of 3d points that lie in a plane. Somewhere on the plane, there will be a hole (which is represented by the lack of points), as in this picture:
I am trying to find the contour of this hole. Other solutions out there involve finding convex/concave hulls but those apply to the outer boundaries, rather than an inner one.
Is there an algorithm that does this?
If you know the plane (which you could determine by PCA), you can project all points into this plane and continue with the 2D coordinates. Thus, your problem reduces to finding boundary points in a 2D data set.
Your data looks as if it might be uniformly sampled (independently per axis). Then, a very simple check might be sufficient: Calculate the centroid of the - let's say 30 - nearest neighbors of a point. If the centroid is very far away from the original point, you are very likely on a boundary.
A second approach might be recording the directions in which you have neighbors. I.e. keep something like a bit field for the discretized directions (e.g. angles in 10° steps, which will give you 36 entries). Then, for every neighbor, calculate its direction and mark that direction, including a few of the adjacent directions, as occupied. E.g. if your neighbor is in the direction of 27.4°, you could mark the direction bits 1, 2, and 3 as occupied. This additional surrounding space will influence how fine-grained the result will be. You might also want to make it depend on the distance of the neighbor (i.e. treat the neighbors as circles and find the angular range that is spanned by the circle). Finally, check if all directions are occupied. If not, you are on a boundary.
Alpha shapes can give you both the inner and outer boundaries.
convert to 2D by projecting the points onto your plane
see related QA dealing with this:
C++ plane interpolation from a set of points
find holes in 2D point set
simply apply this related QA:
Finding holes in 2d point sets?
project found holes back to 3D
again see the link in #1
Sorry for almost link only answer but booth links are here on SO/SE and deals exactly with your issue when combined. I was struggling first to flag your question as duplicate and leave this in a comment but this is more readable.

Subdivided icosahedron - how to find the nearest vertex to an arbitrary point

I have an application that creates an approximation to sphere by subdividing an icosahedron. The Cartesian vertex coordinates are converted to spherical coordinates so that all vertices sit on the surface of a unit sphere.
What I need to do next is find the nearest vertex to an arbitrary point on the surface of the sphere. I have come up with two simple algorithms...
Brute force search - will be OK for a small number of vertices, but will be excessive for finer subdivisions.
Sorted / Indexed search - sort the vertices into some form of order by azimuth and inclination and then create a rough index to speed up a brute force search by limiting its scope.
I was wondering if there was a more subtle, and hopefully higher performing algorithm that I can use instead of one of the two above.
Update 1: I have just recalled that for another part of the application the vertices store information about their neighbours. My new algorithm is
Pick an arbitrary start vertex. Find which of its neighbours has a smaller distance to the point to locate. Use this neighbour as the new start vertex. Repeat until none of the vertex's neighbours has a smaller distance to the point. This vertex is the closest to the point.
Scanning through the responses, I think I may be off base, but what you're after is simple. I think.
Since you're dealing with just points that sit on the sphere, you can just drop a line from the vertex to the center of the sphere, drop another line from the arbitrary point to the center and solve for the angle created between them. Smaller is better. The easiest and cheapest way I think would be the dot product. The angle basically falls out of it. Here's a link about it: http://www.kynd.info/library/mathandphysics/dotProduct_01/
For testing them, I would suggest picking a vertex, testing it, then testing its neighbors. It SHOULD always be in the direction of the smallest neighbor (angle should always decrease as you get closer to the vertex you're after)
Anyhow, I hope that's what you're after.
Oh, and I came across this page while looking for your subdivision algorithm. Hard to find; if you could post a link to it I think it would help out a lot more than just myself.
One of possible solutions is to build BSP tree for vertices: http://en.wikipedia.org/wiki/Binary_space_partitioning
If the icosahedron has one vertex at the north pole and the opposite vertex at the south pole then there are 2 groups each of 5 vertices which are in planes parallel to the equator. With a little geometry I figure that these planes are at N/S 57.3056° (decimals, not dd.mmss). This divides your icosahedron into 4 latitude zones;
anything north (south) of 28.6528° is closest to the vertex at the nearer pole;
anything between the equator and north (south) 28.6528° is closer to one of the 5 vertices in that zone.
I'm working this as a navigator would, arcs measured in degrees and denoted north and south; if you prefer a more mathematical convention you can translate this all to your version of spherical coordinates quite easily.
I suspect, though I haven't coded it, that checking the distance to 5 vertices and selecting the nearest will be quicker than more sophisticated approaches based on partitioning the surface of the sphere into the projections of the faces of the icosahedron, or projecting the points on the sphere back onto the icosahedron and working the problem in that coordinate system.
For example, the approach you suggest in your update 1 will require the computation of the distance to 6 vertices (the first, arbitrarily chosen one and its 5 neighbours) at least.
It doesn't matter (if you only want to know which vertex is nearest) whether you calculate distances in Cartesian or spherical coordinates. However, calculation in Cartesian coordinates avoids a lot of calls to trigonometric functions.
If, on the other hand, you haven't arranged your icosahedron with vertices at the poles of your sphere, well, you should have !

Finding a stable placement of an irregular (non-convex) shape

Given an image of a 2-dimensional irregular (non-convex) shape, how would I able to compute all the ways in which it could lie stable on a flat surface? For example, if the shape is a perfect square rectangle, then it will surely have 4 ways in which it is stable. A circle on the other hand either has no stable orientation or every point is a stable orientation.
EDIT: There's this nice little game called Splitter (Beware, addictive game ahead) that seems close to what I want. Noticed that you cut a piece of the wood out it would fall to the ground and lay in a stable manner.
EDIT: In the end, the approach I took is to compute center of mass (of the shape) and compute the convex hull (using OpenCV), and then loop through every pair of vertices. If the center of mass falls on top of the line formed by the 2 vertices, it is deemed stable, else, no.
First find its center of mass (CM). A stable position is one in which the CM will be higher if you make a slight rotation. Now look at the hull, the smallest convex region that encloses the shape:
(source: walkytalky.net)
If the hull is a polygon, then a stable position is one in which the shape is resting on one of the sides, and the CM is directly over that side (not necessarily over the midpoint of the side, just somewhere over it.
If the hull has curves (that is, if the shape has curves which touch the hull), they must be give special treatment. The shape will be stable when resting on a curved edge iff the CM is directly above the lowest point of the curve, and the radius of the curve at that point is greater than the height of the CM.
Examples:
A rectangle. The hull is simply the rectangle, and the CM is at the center. The shape is stable on each of the four sides.
A rectangle with the sides hollowed, but the corners still intact. The hull is still the original rectangle, and the CM is close to where it used to be. All four sides of the hull are still stable (that is, you can still rest the shape on any two corners).
A circle. The CM is in the center, the hull is the circle. There are no stable positions, since the radius of the curve is always equal to the height of the CM. Give it a slight touch, and it will roll.
An ellipse. The CM is at the center, the hull is the shape. Now there are two stable positions.
A semicircle. The CM is somewhere on the axis of symmetry, the hull is the shape. Two stable positions.
A narrow semicircular crescent. The hull is a semicircle, the CM is outside the shape (but inside the hull). Two stable positions.
(source: walkytalky.net)
(The ellipse position marked with an X is unstable, because the curvature is smaller than the distance to the centre of mass.)
note: this answer assumes your shape is a proper polygon.
For our purposes, we'll define an equilibrium position as one where the Center of Mass is directly above a point that is between the leftmost and rightmost ground-contact points of the object (assuming the ground is a flat surface perpendicular to the force of gravity). This will work in all cases, for all shapes.
Note that, this is actually the physical definition of rotational equilibrium, as a consequence of Newtonian Rotational Kinematics.
For a proper polygon, if we eliminate cases where they stand on a sole vertex, this definition is equivalent to a stable position.
So, if you have a straight downward gravity, first find the left-most and right-most parts of it that are touching the ground.
Then, calculate your Center of Mass. For a polygon with known vertices and uniform density, this problem is reduced to finding the Centroid (relevant section).
Afterwards, drop a line from your CoM; if the intersection of the CoM and the ground is between those two x values, it's at equilibrium.
If your leftmost point and rightmost point match (ie, in a round object), this will still hold; just remember to be careful with your floating point comparisms.
Note that this can also be used to measure "how stable" an object is -- this measure is the maximum y-distance the Center of Mass can move before it is no longer within the range of the two contact points.
EDIT: nifty diagram made hastily
So, how can you use this to find all the ways it can sit on a table? See:
EDIT
The programmable approach
Instead of the computationally expensive task of rotating the shape, try this instead.
Your shape's representation in your program should probably have a list of all vertices.
Find the vertices of your shape's convex hull (basically, your shape, but with all concave vertices -- vertices that are "pushed in" -- eliminated).
Then Iterate through each of pair of adjacent vertices on your convex hull (ie, if I had vertices A, B, C, D, I'd iterate through AB, BC, CD, DA)
Do this test:
Draw a line A through the two vertices being tested
Draw a line perpendicular to A, going through CoM C.
Find the intersection of the two lines (simple algebra)
If the intersection's y value is in between the y value of the two vertices, it stable. If the y values are all equal, compare the x values.
That should do the trick.
Here is an example of the test being running on one pair of vertices:
If your shape is not represented by its vertices in your data structure, then you should try to convert them. If it's something like a circle or an ellipse, you may use heuristics to guess the answer (a circle has infinite equilibrium positions; an ellipse 4, albeit only two "stable" points). If it's a curved wobbly irregular shape, you're going to have to supply your data structure for me be able to help in a program-related way, instead of just providing case-by-case heuristics.
I'm sure this is not the most efficient algorithm, but it's an idea.
If you can order the verticles of the polygon (assuming it has a finite number of vertices), then just iterate over adjacent pairs of vertices and record the angle it rests at through some form of simulation. There will be duplicate orientations for it to sit on in the case of weird shapes, like stars, but you can accomodate for that by keeping track of the resting rotation.

Resources