I know how to implement n log n closest pair of points algorithm (Shamos and Hoey) for 2D cases (x and y). However for a problem where latitude and longitude are given this approach cannot be used. The distance between two points is calculated using the haversine formula.
I would like to know if there is some way to convert these latitudes and longitudes to their respective x and y coordinates and find the closest pair of points, or if there is another technique that can be used to do it.
I would translate them to three dimensional coordinates and then use the divide and conquer approach using a plane rather than a line. This will definitely work correctly. We can be assured of this because when only examining points on the sphere, the two closest points by arc distance (distance walking over the surface) will also be the two closest by 3-d Cartesian distance. This will have running time O(nlogn).
To translate to 3-d coordinates, the easiest way is to make (0,0,0) the center of the earth and then your coordinates are (cos(lat)*cos(lon),cos(lat)*sin(lan),sin(lat)). For those purposes I'm using a scale for which the radius of the Earth is 1 in order to simplify calculations. If you want distance in some other unit, just multiply all quantities by the radius of the Earth when measured in that unit.
I should note that all this assumes that the earth is a sphere. It's not exactly one and points may actually have altitude as well, so these answers won't really be completely exact, but they will be very close to correct in almost every case.
Related
I have a spherical heightfield, defined by a function f(x, y, z) which returns the distance from the origin of the surface of the heightfield of a line which passes from the origin through (x,y,z).
(In other words, the isosurface for my heightfield is |x,y,z| = f(x,y,z).)
(Also, for the sake of discussion below, I'm going to assume that surface(x,y,z) is the location of the point on the surface directly below (x,y,z).)
When rendering this, I need to calculate the normal for any point on the heightfield. What's the cheapest way of doing this?
To calculate the normal of a point on a rectangular heightfield, the usual trick is to offset (x,y,z) slightly in two directions parallel to the nominal surface, calculate three points on the heightfield to form a triangle, and then use the cross product to calculate the triangle's normal. This is easy as the three points can simply be surface(x,y,z), surface(x+1,y,z) and surface(x,y+1,z) (or similar). But for a spherical heightfield it's a little trickier because the normal can point in any direction. Simply displacing by x and y won't do because if two of my points fall on a radius, then surface() of them will return the same location and I won't get a triangle.
In the past what I've done is to use the vector <x,y,z> as a radius from the sphere's origin; then calculate a vector perpendicular to it; then rotate this vector around <x,y,z> to give me my three points. But this is fiddly and expensive and shouldn't be necessary. There must be a cheaper way. What is it?
Calculate the surface() points and, if they are close enough to cause problems, carry out the more expensive (but accurate) calculation; otherwise, use the cheap/easy calculation.
I want to use the minkowski sum to predict the exact point of collision between two convex shapes. By my understanding the point where the velocity vector intersects with the minkowski sum is the amount I have to move my object along the vector so they just touch (I already know they will collide). Here's an example of what I mean (for simplicity reasons I just used rectangles):
I mean I could just calculate the intersection with every line of the convex hull and just use the closest but that seems horribly inefficient. My idea was to calculate the simplex closest to the vector but I have no idea how best to do it. I found a algorithm which calculates the smallest distance between to objects or to be more precise the smallest distance from the minkowski sum to the origin (http://www.codezealot.org/archives/153). One part of the algorithm tries to find the simplex closest to origin which is kinda what I want to do. I tried to change it to my needs but I wasn't successful. To me it sounds like there should be a very simple solution but I am not that good with vector math.
I hope I could make my problem clear since my english is not so good :D
You can transform the problem as follows:
1) rotate the plane so that the velocity vector becomes horizontal
2) consider the portions of the polygon outlines facing each other (these are two convex polylines); now you have to find the shortest horizontal distance between these two polylines
3) through every vertex of one of the polylines, draw an horizontal line; this will parition the plane into a set of horizontal slices
4) transform every slice using a shear transformation that brings the two vertices defining it onto the Y axis by horizontal moves; this transform preserves horizontal distances
5) while the first polyline is transformed into a straight line (the Y axis), the other polyline is transformed into another polyline; find the vertex(es) closest to the Y axis. This gives you the length of the collision vector.
As a by-product, step 2) will tell you if the polygons do collide, if the ranges of Y values overlap.
I have some GPS sample data taken from a device. What I need to do is to "move" the data to the "left" by, let's say, 1 to 5 meters. I know how to do the moving part, the only problem is that the moving is not as accurate as I want it to be.
What I currently do:
I take the GPS coordinates (latitude, longitude pairs)
I convert them using plate carrée transformation.
I scale the resulting coordinates to the longitudinal distance (distance on x) and the latitudinal distance (distance on y) - imagine the entire GPS sample data is inside a rectangle being bound by the maximum and minimum latitude/longitude. I compute these distances using the formula for the Great Circle Distance between the extreme values for longitude and latitude.
I move the points x meters in the wanted direction
I convert back to GPS coordinates
I don't really have the accuracy I want. For example moving to the left by 3 meters means less than 3 meters (around 1.8m - maybe 2).
What are the known solutions for doing such things? I need a solution that deviates at most by 0.2-0.5 meters from the real point (not 1.2 like in the current case).
LATER: Is this kind of approach good? By this kind I mean to transform the GPS coordinates into plane coordinates and back to GPS. Is there other way?
LATER2: The approach of converting to a conformal map is probably the one that will be used. In case of a small rectangle, and since there are not roads at the poles probably Mercator will be used. Opinions?
Thanks,
Iulian
PS: I'm working on small areas - so imagine the bounding rectangle I'm talking about to have the length of each side no more than 5 kilometers. (So a 5x5km rectangle is maximum).
There are two issues with your solution:
plate carrée transformation is not conformal (i.e. angles are not preserved)
you can not measure distances along lat or lon that way since that are not great circles (approximately you are off by a factor cos(lat) for your x).
Within small rectangles you may assume that lon/lat can be linearly mapped to x/y pairs but you have to keep in mind that a "square" in lon/lat maps to a rectangle with aspect ratio of approx cos(lat)/1.
I'm trying to design an implementation of Vector Quantization as a c++ template class that can handle different types and dimensions of vectors (e.g. 16 dimension vectors of bytes, or 4d vectors of doubles, etc).
I've been reading up on the algorithms, and I understand most of it:
here and here
I want to implement the Linde-Buzo-Gray (LBG) Algorithm, but I'm having difficulty figuring out the general algorithm for partitioning the clusters. I think I need to define a plane (hyperplane?) that splits the vectors in a cluster so there is an equal number on each side of the plane.
[edit to add more info]
This is an iterative process, but I think I start by finding the centroid of all the vectors, then use that centroid to define the splitting plane, get the centroid of each of the sides of the plane, continuing until I have the number of clusters needed for the VQ algorithm (iterating to optimize for less distortion along the way). The animation in the first link above shows it nicely.
My questions are:
What is an algorithm to find the plane once I have the centroid?
How can I test a vector to see if it is on either side of that plane?
If you start with one centroid, then you'll have to split it, basically by doubling it and slightly moving the points apart in an arbitrary direction. The plane is just the plane orthogonal to that direction.
But you don't need to compute that plane.
More generally, the region (i) is defined as the set of points which are closer to the centroid c_i than to any other centroid. When you have two centroids, each region is a half space, thus separated by a (hyper)plane.
How to test on a vector x to see on which side of the plane it is? (that's with two centroids)
Just compute the distance ||x-c1|| and ||x-c2||, the index of the minimum value (1 or 2) will give you which region the point x belongs to.
More generally, if you have n centroids, you would compute all the distances ||x-c_i||, and the centroid x is closest to (i.e., for which the distance is minimal) will give you the region x is belonging to.
I don't quite understand the algorithm, but the second question is easy:
Let's call V a vector which extends from any point on the plane to the point-in-question. Then the point-in-question lies on the same side of the (hyper)plane as the normal N iff V·N > 0
I am programming an algorithm where I have broken up the surface of a sphere into grid points (for simplicity I have the grid lines parallel and perpendicular to the meridians). Given a point A, I would like to be able to efficiently take any grid "square" and determine the point B in the square with the least spherical coordinate distance AB. In the degenerate case the "squares" are actually "triangles".
I am actually only using it to bound which squares I am searching, so I can also accept a lower bound if it is only a tiny bit off. For this reason, I need the algorithm to be extremely quick otherwise it would be better to just take the loss of accuracy and search a few more squares.
I decided to repost this question to Math Overflow: https://mathoverflow.net/questions/854/closest-grid-square-to-a-point-in-spherical-coordinates. More progress has been made here
For points on a sphere, the points closest in the full 3D space will also be closest when measured along the surface of the sphere. The actual distances will be different, but if you're just after the closest point it's probably easiest to minimize the 3D distance rather than worry about great circle arcs, etc.
To find the actual great-circle distance between two (latitidude, longitude) points on the sphere, you can use the first formula in this link.
A few points, for clarity.
Unless you specifically wish these squares to be square (and hence to not fit exactly in this parallel and perpendicular layout with regards to the meridians), these are not exactly squares. This is particularly visible if the dimensions of the square are big.
The question speaks of a [perfect] sphere. Matters would be somewhat different if we were considering the Earth (or other planets) with its flattened poles.
Following is a "algorithm" that would fit the bill, I doubt it is optimal, but could offer a good basis. EDIT: see Tom10's suggestion to work with the plain 3D distance between the points rather than the corresponding great cirle distance (i.e. that of the cord rather than the arc), as this will greatly reduce the complexity of the formulas.
Problem layout: (A, B and Sq as defined in the OP's question)
A : a given point the the surface of the sphere
Sq : a given "square" from the grid
B : solution to problem : point located within Sq which has the shortest
distance to A.
C : point at the center of Sq
Tentative algorithm:
Using the formulas associated with [Great Circle][1], we can:
- find the equation of the circle that includes A and C
- find the distance between A and C. See the [formula here][2] (kindly lifted
from Tom10's reply).
- find the intersect of the Great Circle arc between these points, with the
arcs of parallel or meridian defining the Sq.
There should be only one such point, unless this finds a "corner" of Sq,
or -a rarer case- if the two points are on the same diameter (see
'antipodes' below).
Then comes the more algorithmic part of this procedure (so far formulas...):
- find, by dichotomy, the point on Sq's arc/seqment which is the closest from
point A. We're at B! QED.
Optimization:
It is probably possible make a good "guess" as to the location
of B, based on the relative position of A and C, hence cutting the number of
iterations for the binary search.
Also, if the distance A and C is past a certain threshold the intersection
of the cicles' arcs is probably a good enough estimate of B. Only when A
and C are relatively close will B be found a bit further on the median or
parallel arc in these cases, projection errors between A and C (or B) are
smaller and it may be ok to work with orthogonal coordinates and their
simpler formulas.
Another approach is to calculate the distance between A and each of the 4
corners of the square and to work the dichotomic search from two of these
points (not quite sure which; could be on the meridian or parallel...)
( * ) *Antipodes case*: When points A and C happen to be diametrically
opposite to one another, all great circle lines between A and C have the same
length, that of 1/2 the circonference of the sphere, which is the maximum any
two points on the surface of a sphere may be. In this case, the point B will
be the "square"'s corner that is the furthest from C.
I hope this helps...
The lazy lower bound method is to find the distance to the center of the square, then subtract the half diagonal distance and bound using the triangle inequality. Given these aren't real squares, there will actually be two diagonal distances - we will use the greater. I suppose that it will be reasonably accurate as well.
See Math Overflow: https://mathoverflow.net/questions/854/closest-grid-square-to-a-point-in-spherical-coordinates for an exact solution