I'm monitoring a GPS unit which is on it's way from Cape Discovery in Canada, to the North Pole. I need to keep track of the distance travelled and distance remaining each day, so I'm using the Haversine Formula, which I'm told is very accurate for smaller distances.
I'm really bad a Math, but I have a sneaking suspicion that the accuracy depends greatly on the radius of the Earth, and since the universe decided to make Earth out of an oblate spheroid, I have a choice of approximations for Earths radius to choose from.
Since I'm monitoring coordinates very close to the north pole, I'm wondering wether anyone knows which radius is going to provide the most accuracy.
Mean Equatorial: 6,378.1370km
Mean Polar: 6,356.7523
Authalic/Volumetric: 6,371km
Meridional: 6367km
Or any other kind of Radius that anyone knows about?
I'm hoping some maths or cartography whizz might know the answer to this one.
You could approximate the actual radius at the point(s) where you're measuring the distance (provided that you calculate a sequence of relative small distances).
Assuming the earth being an ellipsoid with the main axis a being the mean equatorial radius and the second axis b being the mean polar radius, you can calculate the point on the ellipse represented by these two axes by using the current latidude. The calculation is shown and explained here.
(Note: This ellipse can be thought as a cross section of the earth through the poles and the point where you want to calculate the distance)
This gives you a point q=(qx,qy), the radius at this point being r=sqrt(qx^2+qy^2). That's what I'd use for calculating the Haversine formula.
It doesn't really matter - they are all going to be wrong if you just treat the earth as a sphere. I would probably use the polar since you are mostly going north.
Related
I need to calculate the minimum distance between a 3D point (latitude, longitude, elevation) and a line (defined as two points).
The elevation is not necessary on the ground, I need to consider flying objects.
I only found an article that explains how to do that on a generic space but my points are defined with lat/lon/altitude(meters).
Thank you for pointing in the right direction, in my case I need to do that in Javascript but couldn't find any library that takes into consideration the altitude.
Point-Line Distance--3-Dimensional
If you want to compare a 3d point to a 2d line, I suppose you mean a "line" on our earth, at elevation 0. Take a look at st_distance in postgis.
If I understand you correctly, that'll give you what you want.
https://postgis.net/docs/ST_Distance.html
The iPhone gyroscope receives rotation data relative to some reference attitude and it doesn't change (unless multiplied.) Lets say I face the wall using my iPhone camera, and rotate 45 degrees left (roll += PI/4.)
Now, if I lift the phone towards the ceiling, both yaw and pitch change since the coordinate space is fixed (world coordinate space, doesn't move or rotate with the phone.) Is there a way to determine this angle (the one between the floor plane and the camera direction vector), roll, yaw and pitch given?
Edit: Instead of opening another question I'll try here. Luc's solution works. But how to get the other two angles of rotation? I've read the info on the posted link but it's been years since I studied linear algebra. This might be more math than a programming question, actually.
I don't really code for iPhone so I'll trust you on the "real world coordinates" frame.
In that case, you want the dot product between both z-axis' vectors. That'll give you the cosine of the angle you're looking for, pretty close thus. Since an angle between planes only really makes sense as a value between 0° and 90°, you actually have all the information you need in that cosine.
And there is no latex formatting here, otherwise I'd go into a bit more of detail, but read this page if you're interested, I'll just include the final result here, the rotation matrix for your three rotations :
Now the z-axis' vector of the horizontal plan is (0,0,1) (read this as a vertical vector though) and rotated with this matrix, you simply get its third column.
So we want to have the dot product between that third column and our (0,0,1) vector, so you get cos(β)cos(γ) which is cos(pitch)*cos(roll)
In conclusion, the angle between your plans is arccos(cos(pitch)*cos(roll)). This value will tell you how much your iPhone is inclined, not in which direction of course. But you can work that out from the values of the vector (rightmost column of the matrix) we spoke of.
I have to detect the pattern of 6 circles using opencv. I have detected the circles and their centroids by using thresholding and contour function in opencv.
Now I have to define the relation between these circles in a way that should be invariant to scale and rotation. With this I would be able to detect this pattern in various views. I have to use this pattern for determining the object pose.
How can I achieve scale/rotation invariance? Do you have any reference I could read about it?
To make your pattern invariant toward rotation & scale, you have to normalize the direction and the scale when detecting your pattern. Here is a simple algorithm to achieve this
detect centers and circle size (you say you have already achieved this - good!)
compute the average center using a simple mean. Express all the centers from this mean
find the farthest center using a simple norm (euclidian is good enough)
scale the center position and the circle sizes so that this maximum distance is 1.0
rotate the centers so that coordinates of the farthest one is (1.0, 0)
you're done. You are now the proud owner of a scale/rotation invariant pattern detector!! Congratulations!
Now you can find patterns, transform them as suggested, and compare center position & circle sizes.
It is not entirely clear to me if you need to find the rotation, or merely get rid of it, or detect if the circles actually form the pattern you linked. Either way, the answer is much the same.
I would start by finding the two circles that have only one neighbour. For each circle centroid calculate the distance to the closest two neighbours. If the distances differ in more than say 10%, the centroid belongs to an "end" circle (one of the top ones in your link).
Now that you have found the two end circles, rotate them so that they are horizontal to each other. If the other centroids are now above them, rotate another 180 degrees so that the pattern ends up in the orientation you want.
Now you can calculate the scaling from the average inter-centroid distance.
Hope that helps.
Your question sounds exactly like what the SURF algorithm does. It finds groups of interest and groups them together in a way invarant to rotation and scale, and can find the same object in other pictures.
Just search for OpenCV and SURF.
In my project my users can choose to be put in a random position inside a given, circular area.
I have the latitude and longitude of the center and the radius: how can I calculate the latitude and longitude of a random point inside the given area?
(I use PHP but examples in any language will fit anyway)
You need two randomly generated numbers.
Thinking about this using rectangular (Cartesian) (x,y) coordinates is somewhat unnatural for the problem space. Given a radius, it's somewhat difficult to think about how to directly compute an (Δx,Δy) delta that falls within the circle defined by the center and radius.
Better to use polar coordinates to analyze the problem - in which the dimensions are (r1, Θ). Compute one random distance, bounded by the radius. Compute a random angle, from 0 to 360 degrees. Then convert the (r,Θ) to Cartesian (Δx,Δy), where the Cartesian quantities are simply offsets from your circle center, using the simple trigonometry relations.
Δx = r * cos(Θ)
Δy = r * sin(Θ)
Then your new point is simply
xnew = x + Δx
ynew = y + Δy
This works for small r, in which case the geometry of the earth can be approximated by Euclidean (flat plane) geometry.
As r becomes larger, the curvature of the earth means that the Euclidean approximation does not match the reality of the situation. In that case you will need to use the formulas for geodesic distance, which take into account the 3d curvature of the earth. This begins to make sense, let's say, above distances of 100 km. Of course it depends on the degree of accuracy you need, but I'm assuming you have quite a bit of wiggle room.
In 3d-geometry, you once again need to compute 2 quantities - the angle and the distance. The distance is again bound by your r radius, except in this case the distance is measured on the surface of the earth, and is known as a "great circle distance". Randomly generate a number less than or equal to your r, for the first quantity.
The great-circle geometry relation
d = R Δσ
...states that d, a great-circle distance, is proportional to the radius of the sphere and the central angle subtended by two points on the surface of the sphere. "central angle" refers to an angle described by three points, with the center of the sphere at the vertex, and the other two points on the surface of the sphere.
In your problem, this d must be a random quantity bound by your original 'r'. Calculating a d then gives you the central angle, in other words Δσ , since the R for the earth is known (about 6371.01 km).
That gives you the absolute (random) distance along the great circle, away from your original lat/long. Now you need the direction, quantified by an angle, describing the N/S/E/W direction of travel from your original point. Again, use a 0-360 degree random number, where zero represents due east, if you like.
The change in latitude can be calculated by d sin(Θ) , the change in longitude by d cos(Θ). That gives the great-circle distance in the same dimensions as r (presumably km), but you want lat/long degrees, so you'll need to convert. To get from latitudinal distance to degrees is easy: it's about 111.32 km per degree regardless of latitude. The conversion from longitudinal distance to longitudinal degrees is more complicated, because the longitudinal lines are closer to each other nearer the poles. So you need to use some more complex formulae to compute the change in longitude corresponding to the selected d (great distance) and angle. Remember you may need to hop over the +/- 180° barrier. (The designers of the F22 Raptor warplane forgot this, and their airplanes nearly crashed when attempting to cross the 180th meridian.)
Because of the error that may accumulate in successive approximations, you will want to check that the new point fits your constraints. Use the formula
Δσ = arccos( cos(Δlat) - cos(lat1)*cos(lat2)*(1 - cos(Δlong) ) .
where Δlat is the change in latitude, etc.
This gives you Δσ , the central angle between the new and old lat/long points. Verify that the central angle you've calcuated here is the same as the central angle you randomly selected previously. In other words verify that the computed d (great-circle-distance) between the calculated points is the same as the great circle distance you randomly selected. If the computed d varies from your selected d, you can use numerical approximation to improve the accuracy, altering the latitude or longitude slightly until it meets your criterion.
This can simply be done by calculating a random bearing (between 0 and 2*pi) and a random distance between 0 and your desired maximum radius. Then compute the new (random) lat/lon using the random bearing/range from your given lat/lon center point. See the section 'Destination point given distance and bearing from start point' at this web site: http://www.movable-type.co.uk/scripts/latlong.html
Note: the formula given expects all angles as radians (including lat/lon). The resulting lat/lon with be in radians also so you will need to convert to degrees.
I know that most people will view this question and point me to Google Geocode - but I'm looking for a mathematical formula that allows someone to take a Lat/Lng point and see if its inside a US state (or a bounding box). Is there a way via PHP, that I can do a calculation to see if a point is in a certain Box (such as California)?
Well, there's no formula that'll tell you anything about what states is where (it would have totally been a spoiler as to the outcome of the US-Mexico war if there was!) So you'll need to get that data from somewhere.
This then turns into one of two problems, depending on the degree of accuracy you want.
If you have details of a bounding box that is rectangular when shown on a Mercator or similar projection (that is, it has degrees of latitude for north and south, and of longitude for east and west), then the formula is simply:
inBox = latitude <= north && latitude >= south && longitude <= west && longitude >= east
If you have more detail, and have a series of points that defines the border of the state (obviously, the more points, the more precision) then it becomes a variant of the point-in-polygon problem, with a guarantee of only involving simple polygons (no US state has a border that crosses itself, nor completely surrounds that used in this C code. It's possible that there would be edge cases affected by the fact that this is a 2D-plane algorithm rather than a spherical one, but I imagine you'd need to have some pretty precise data on the boundaries of the states for the imprecision from the algorithm to be greater than that caused by the data.
The simplest way I would think is using bound box for each state, that can be found from Flicker Geo API, an example for CA- https://www.flickr.com/places/info/2347563