Create a point from a startingPoint, a position and a direction

49 Views Asked by At

I am making path generation on a map and I have a little question :

Data=>

  1. Point A => start Position (Cartographic Position {latitude, longitude; altitude})
  2. Direction B => direction from A (Heading Pitch Roll {heading, pitch, roll})
  3. Distance C => in meters

I would like =>

From the above information, create a point D based on starting position, at distance C in the direction B

What I do =>

My Data is in different format, so I need to move them in a similar format. since I am using CesiumJs, there is no way to convert automatically in a default format.

so I converted all to Cartesian3 From now I think I should use something like

resultPoint = startPoint + direction * distance

Problem =>

Right now, My HeadingPitchRoll is on purepose always clamped so that only Heading is used

my HeadingPitchRoll can be

[{0,0,0} to {360,0,0}]

If I apply the above formula. when my heading is {0,0,0} I have the following

resultPoint = {10,10,10} + {0,0,0} * 1000 so resultPoint = {10,10,10}

but this is wrong, {0,0,0} is also a direction so it should return me a point that is not the same one. I am probably missing something like a reference axis ?

1

There are 1 best solutions below

0
On BEST ANSWER

Since your map is on a roughly spherical surface, convert the distance to be travelled to angle. Let $C$ be the distance in meters, and $r$ the radius (half the diameter) of the sphere (planet) in meters. Then, the angle is $\theta$, $$\theta = \frac{C}{2 \pi r}$$

Let $\vec{p}$ be the starting position in the 3D Cartesian coordinate system, and $\vec{d}$ the direction the travel starts, tangent to the surface. Note that you can make direction $\vec{u}$ tangent to the surface using $$\vec{d} = \vec{u} - \vec{u}\frac{\vec{p}\cdot\vec{u}}{\left\lVert\vec{p}\right\rVert \left\lVert\vec{u}\right\rVert}$$ where $\left\lVert\vec{a}\right\rVert = \sqrt{ a_x^2 + a_y^2 + a_z^2 }$ (Euclidean distance), and $\vec{p} \cdot \vec{u} = p_x u_x + p_y u_y + p_z u_z$ (3D dot product), if we use $\vec{p} = ( p_x , p_y , p_z )$ and $\vec{u} = ( u_x , u_y , u_z )$.

The travel is essentially a rotation of the starting position $\vec{p}$ by angle $\theta$ around axis $\hat{a}$ that is perpendicular to both the position (with respect to the center of the planet) and the initial direction of travel $\vec{d}$: $$\vec{a} = \vec{p} \times \vec{d}$$ $$\hat{a} = \frac{\vec{a}}{\left\lVert\vec{a}\right\rVert}$$ where $\vec{p} \times \vec{d} = ( p_y d_z - p_z d_y ,~ p_z d_x - p_x d_z ,~ p_x d_y - p_y d_x )$ (the cross product).

To find out the 3D Cartesian coordinates $\vec{s}$ where the travel ends, use Rodrigues' rotation formula: $$\vec{s} = \vec{p} \cos \theta + (\hat{a} \times \vec{p}) \sin \theta + \hat{a} ( \hat{a} \cdot \vec{p})(1 - \cos \theta)$$ Note that this rotation retains the altitude. To change the altitude, use $$\vec{s}_\text{new} = \frac{r + \text{altitude}_\text{new} }{r + \text{altitude}_\text{old} } \vec{s}$$

If you want the end point in cartographic coordinates, use the inverse of the transformation you used to get the 3D Cartesian coordinates. For example, if $$\begin{array}{rl} d ~ ~ = & r + \text{altitude} \\ x ~ ~ = & d \cos(\text{longitude}) \sin(\text{latitude}) \\ y ~ ~ = & d \sin(\text{longitude}) \sin(\text{latitude}) \\ z ~ ~ = & d \cos(\text{latitude}) \\ \end{array}$$ then $$\begin{array}{rl} d ~ ~ = & \sqrt{x^2 + y^2 + z^2} \\ \text{altitude} ~ ~ = & d - r \\ \text{latitude} ~ ~ = & \operatorname{arcsin}\left(\frac{z}{d}\right) \\ \text{longitude} ~ ~ = & \operatorname{arctan2}\left(y, x\right) \end{array}$$ where $\operatorname{arctan2}$ is the 2-argument arctan function (i.e, like $\operatorname{arctan}(y/x)$, except it takes the signs of $x$ and $y$ into account).