Find intersection and ETA - math

I have 2 coordinate points A,B and I want to know the formula to calculate the intersection point if that exist.
Let's say I have an airplane at Lat: 42.68543 Lon: 16.9880 moving at 196 deg with 430km/h and another one at Lat: 36.72348 Lon: 20.76236 moving at 269 deg with 670km/h
1) I want to calculate the intersection point (if exist)
2) If intersection exist I need to know the estimate time that each craft needs and the distance to the intersection point
Can you help me with a Java example on how can I find it?

If you have position vectors A=(xa,ya) and B=(xb,yb) and corresponding velocities Va and Vb, you are trying to solve A+s*Va=B+t*Vb. This is the solution for any coordinate system, but first you have to choose a coordinate system.
Let's solve it first for Euclidian space...
Write this out for each component x and y. You now have two simultaneous equations in two variables and can solve for both s and t. They will collide if s==t (or is 'close'). Watch out for divide-by-zero when Va and Vb are parallel, and numerical instabilities.
For a spherical solution, consider two points moving on the circumferences of circles, the equations are the same form although A and B will be angles and Va and Vb will be angular velocities. To get the circles, calculate Euclidian Va and Vb instantaneously at any time, this taken with the Euclidian A and B (assuming Earth is centred at 0) tell you what plane you're working in, project into this plane to get a 2D problem for each plane separately.

Related

Average height of a point based on nearby points

I have a situation in my game. I am experimenting with terrain generation.
I have a bunch of peaks, whose position and elevation i know.
I have a point which is surrounded by all these peaks. I know its position. I am trying to calculate the elevation of this point.
I would like to calculate the height of this point, based on how close/far it is to each of these peaks, and the elevation of each of these peaks.
Example:
Peak 1 is at (0,0), with an elevation of 500
Peak 2 is at (100,100), with an elevation of 1000
Peak 3 is at (0,100), with an elevation of 750
If my point is at (99,99), i want the elevation of this point to be as close to 1000.
What is the name of this problem?
If you already have a solution to this, that too will be much appreciated.
Note: In addition, it will be helpful if the formula/equation also allows me to generate negative elevations. for example, a point midway between all the peaks could as well be under sea level. Any formula i can menatally think of usually gives me just positive results. I assume some kind of 'Slope' must be considered to allow this.
One equation i though of so far is
P1.height * (Sum of all distances - distance from P1)/(Sum of all distances) +
P2.height * (Sum of all distances - distance from P2)/(Sum of all distances) +
... Pn.height * (Sum of all distances - distance from Pn)/(Sum of all distances)
Thank you.
To draw the peaks your game needs to convert the coordinates of the peaks to screen coordinates.
Such calculation is usually done by multiplying a matrix with the vector containing the coordinates (in java AWT such matrix would be called a transform).
What you need is the inverse of that matrix so that you can apply it to your screen coordinates.
So the solution is:
get the matrix that is used for rendering the terrain
calculate the inverse matrix
apply it to your screen coordinates
And it might even be more efficient not to use the original matrix to calculate the inverse matrix but use the parameters (zero point, scale factors and rotation angle) which were used to calculate the original matrix. The same parameters can be used to calculate the inverse matrix.

Find all 4 possible normals to an ellipse

Given a point p exterior to an axially aligned, origin centered ellipse E, find the (upto) four unique normals to E passing through p.
This is not a Mathematica question. Direct computation is too slow; I am willing to sacrifice precision and accuracy for speed.
I have searched the web, but all I found involved overly complex calculations which if implemented directly appear to lack the performance I need. Is there a more "programmatical" way to do this, like using matrices or scaling the ellipse into a circle?
Let's assume the ellipse E is in "standard position", center at the origin and axes parallel to the coordinate axes:
(x/a)^2 + (y/b)^2 = 1 where a > b > 0
The boundary cases a=b are circles, where the normal lines are simply ones that pass through the center (origin) and are thus easy to find. So we omit discussion of these cases.
The slope of the tangent to the ellipse at any point (x,y) may be found by implicit differentiation:
dy/dx = -(b^2 x)/(a^2 y)
For the line passing through (x,y) and a specified point p = (u,v) not on the ellipse, that is normal to ellipse E when its slope is the negative reciprocal of dy/dx:
(y-v)/(x-u) * (-b^2 x)/(a^2 y) = -1 (N)
which simplifies to:
(x - (1+g)u) * (y + gv) = -g(1+g)uv where g = b^2/(a^2 - b^2)
In this form we recognize it is the equation for a right rectangular hyperbola. Depending on how many points of intersection there are between the ellipse and the hyperbola (2,3,4), we have that many normals to E passing through p.
By reflected symmetry, if p is assumed exterior to E, we may take p to be in the first quadrant:
(u/a)^2 + (v/b)^2 > 1 (exterior to E)
u,v > 0 (1'st quadrant)
We could have boundary cases where u=0 or v=0, i.e. point p lies on an axis of E, but these cases may be reduced to solving a quadratic, because two normals are the (coinciding) lines through the endpoints of that axis. We defer further discussion of these special cases for the moment.
Here's an illustration with a=u=5,b=v=3 in which only one branch of the hyperbola intersects E, and there will be only two normals:
If the system of two equations in two unknowns (x,y) is reduced to one equation in one unknown, the simplest root-finding method to code is a bisection method, but knowing something about the possible locations of roots/intersections will expedite our search. The intersection in the first quadrant is the nearest point of E to p, and likewise the intersection in the third quadrant is the farthest point of E from p. If the point p were a good bit closer to the upper endpoint of the minor axis, the branches of the hyperbola would shift together enough to create up to two more points of intersection in the fourth quadrant.
One approach would be to parameterize E by points of intersection with the x-axis. The lines from p normal to the ellipse must intersect the major axis which is a finite interval [-a,+a]. We can test both the upper and lower points of intersection q=(x,y) of a line passing through p=(u,v) and (z,0) as z sweeps from -a to +a, looking for places where the ellipse and hyperbola intersect.
In more detail:
1. Find the upper and lower points `q` of intersection of E with the
line through `p` and `(z,0)` (amounts to solving a quadratic)
3. Check the sign of a^2 y(x-u) - b^2 x(y-v) at `q=(x,y)`, because it
is zero if and only `q` is a point of normal intersection
Once a subinterval is detected (either for upper or lower portion) where the sign changes, it can be refined to get the desired accuracy. If only modest accuracy is needed, there may be no need to use faster root finding methods, but even if they are needed, having a short subinterval that isolates a root (or root pair in the fourth quadrant) will be useful.
** more to come comparing convergence of various methods **
I had to solve a problem similar to this, for GPS initialization. The question is: what is the latitude of a point interior to the Earth, especially near the center, and is it single-valued? There are lots of methods for converting ECEF cartesian coordinates to geodetic latitude, longitude and altitude (look up "ECEF to Geodetic"). We use a fast one with only one divide and sqrt per iteration, instead of several trig evaluations like most methods, but since I can't find it in the wild, I can't give it to you here. I would start with Lin and Wang's method, since it only uses divisions in its iterations. Here is a plot of the ellipsoid surface normals to points within 100 km of Earth's center (North is up in the diagram, which is really ECEF Z, not Y):
The star-shaped "caustic" in the figure center traces the center of curvature of the WGS-84 ellipsoid as latitude is varied from pole to equator. Note that the center of curvature at the poles is on the opposite side of the equator, due to polar flattening, and that the center of curvature at the equator is nearer to the surface than the axis of rotation.
Wherever lines cross, there is more than one latitude for that cartesian position. The green circle shows where our algorithm was struggling. If you consider that I cut off these normal vectors where they reach the axis, you would have even more normals for a given position for the problem considered in this SO thread. You would have 4 latitudes / normals inside the caustic, and 2 outside.
The problem can be expressed as the solution of a cubic equation which
gives 1, 2, or 3 real roots. For the derivation and closed form
solution see Appendix B of Geodesics on an ellipsoid of revolution. The boundary between 1 and 3 solutions is an astroid.

compute angle of rotation between two orthographic projections

I Have the orthographic projection of a unit cube with one of its vertex at origin as shown above. I have the x,y (no z) co ordinates of the projections. I would like to compute the angle of rotation of the plane to get the second orthographic projection from the first one (maybe euler angles??)
Is there any other easy way to compute this?
UPDATE:
Could I use this rotation matrix to get a system of equations in cos, sin angles and the x,y and x',y' and solve them easily? Or is there any easier way to get the angles back? (Am I on the right direction to solve this? )
First method
Use this idea to generate equations:
a1, a2 and a3 are coordinates in the original system, x y are the coordinates you get from the end-result and z is a coordinate you don’t know. This generates 2 equations for every point of the cube. E.g for point 0 with coordinates (-1, -1, 1) these are:
Do this for the 4 front points of the cube and you get 8 equations. Now add the fact that this is a rotation matrix -> the determinant is 1 and you have 9 equations. Solve these with any of the usual algorithms for solving equation systems and you have the transformation matrix. Getting the axis and angle from that is easy via google: http://www.euclideanspace.com/maths/geometry/rotations/conversions/matrixToAngle/
Second method
Naming your points 0, 1, 2, 3 a, b, c, d respectively, you can get the z coordinates of the vectors between them (e.g. b-a) with this idea:
you will still have to sort out if b3-a3 is positive, though. One way to do that is to use the centermost point as b (calculate distance from the center for all points, use the one with the minimal distance). Then you know for sure that b3-a3 is positive (if z is positive towards you).
Now assume that a is (0,0,0) in your transformed space and you can calculate all the point positions by adding the appropriate vectors to that.
To get the rotation you use the fact that you know where b-a did point in your origin space (e.g. (1,0,0)). You get the rotation angle via dot product of b-a and (1,0,0) and the rotation axis via cross product between those vectors.

Draw a path around a globe?

So basically I would like to:
Draw a path between two positions in Earth, with longitude and latitude coordinates
Be able to render this path with multiple straight lines (e.g. with OpenGL)
Specify an altitude, and bonus points for being able to arc over the sphere (e.g. a flight path)
Doesn't really matter which language it's in. I can translate :)
There is the "great-circle" distance formula, but I'm not sure how I would apply it into this problem.
All right, here's my approach. If any of the steps are unclear, tell me and I'll elaborate.
We're going from A to B.
We normalize these vectors, a = A/|A|, b = B/|B|.
(The magnitudes |A| and |B| will be the radius of the Earth if we're staying on the ground.)
We take the cross-product, c = a x b.
We will rotate around this vector, c, to carry A to B, and the magnitude of c is the cosine of the angle between A and B: theta = acos(|c|). Pretty cool, huh?
We don't want to make the trip in one jump, we want n small steps, so we divide theta up. We start at A, then at each step we rotate around c by an angle theta/n.
That gives a path along the ground. To get an arc (maybe starting/ending at some altitude), we decide how much altitude to add at each step (very easy in spherical coordinates-- in Cartesian we must scale the vector).

How do you calculate the reflex angle given two vectors in 3D space?

I want to calculate the angle between two vectors a and b. Lets assume these are at the origin. This can be done with
theta = arccos(a . b / |a| * |b|)
However arccos gives you the angle in [0, pi], i.e. it will never give you an angle greater than 180 degrees, which is what I want. So how do you find out when the vectors have gone past the 180 degree mark? In 2D I would simply let the sign of the y-component on one of the vectors determine what quadrant the vector is in. But what is the easiest way to do it in 3D?
EDIT: I wanted to keep the question general but here we go. I'm programming this in c and the code I use to get the angle is theta = acos(dot(a, b)/mag(a)*mag(b)) so how would you programmatically determine the orientation?
This works in 2D because you have a plane defined in which you define the rotation.
If you want to do this in 3D, there is no such implicit 2D plane. You could transform your 3D coordinates to a 2D plane going through all three points, and do your calculation inside this plane.
But, there are of course two possible orientations for the plane, and that will affect which angles will be > 180 or smaller.
I came up with the following solution that takes advantage of the direction change of the cross product of the two vectors:
Make a vector n = a X b and normalize it. This vector is normal to the plane spanned by a and b.
Whenever a new angle is calculated compare it with the old normal. In the comparison, treat the old and the current normals as points and compute the distance between them. If this distance is 2 the normal (i.e. the cross product a X b has flipped).
You might want to have a threshold for the distance as the distance after a flip might be shorter than 2, depending on how the vectors a and b are oriented and how often you update the angle.
One solution that you could use:
What you effectively need to do is create a plane that one of the vectors is coplanar to.
Getting the cross product of both vectors will create a plane, then is you get the normal of this plane, you can get the angle between this and the vector you need to get the signed angle for, and you can use the angle to determine the sign.
If the angle is greater than 90 degrees, then it is below the created plane; less than 90 degrees, and it is above.
Depending on cost of calculations, the dot product can be used at this stage instead of the angle.
Just make sure that you always calculate the normals by the same order of vectors.
This is useable more easily if you're using the XYZ axes, and that's what you're comparing against, since you already have the vectors needed for the plane.
There are possbly more efficient solutions, but this is one I came up with.
Edit: clarification of created vectors
a X b = p. This is perpendicular to both a and b.
Then, do either:
a X p or b X p to create another vector that is the normal to the plane created by the 2 vectors. Choice of vector depends on which you're trying to find the angle for.
Strictly speaking, two 3D vectors always have two angles between them - one below or equal to 180, the other over or equal to 180. Arccos gives you one of them, you can get the other by subtracting from 360. Think of it that way: imagine two lines intersect. You have 4 angles there - 2 of one value, 2 of another. What's the angle between the lines? No single answer. Same here. Without some kind of extra criteria, you can not, in theory, tell which of the two angle values should be taken into account.
EDIT: So what you really need is an arbitrary example of fixing an orientation. Here's one: we look from the positive Z direction. If the plane between the two vectors contains the Z axis, we look from the positive Y direction. If the plane is YZ, we look from the positive X direction. I'll think how to express this in coordinate form, then edit again.

Resources