Calculate elevation angle between two points

Hi,

I have two points consisting of long/lat/height. I’d like to calculate the elevation angle between them, as though we were standing at the first point.

If I’ve researched it correctly, we have to place both points on the one plane that is tangent to the surface of the earth at point 1. Then we can use normal vector math to calculate the elevation angle. Is there a gist that shows me how I can do this? I’m confused as to whether I should use eastNorthUpToFixedFrame or geodeticSurfaceNormalCartographic.

Here is the gist I’m trying to calculate the elevation angle for.

Thank you,

Fidel

Hi Fidel,

Calculating the angle between two vector is a well documented linear algebra problem: https://gamedev.stackexchange.com/questions/69475/how-do-i-use-the-dot-product-to-get-an-angle-between-two-vectors

Essentially, what you’ll want to do is take the dot product of your given vector (obtained by taking the difference of the end points), and the surface normal (which you can obtain by normalizing the starting point position, since the surface normal is just the vector that points from the world origin to that point), then take the arccos of the result.

Hope that helps,

  • Rachel

Thanks Rachel,

Following your steps, I’ve come up with this. But it gives a dotProduct of 1…

var Cesium = require(‘cesium’);

var startPoint = new Cesium.Cartesian3.fromDegrees(-107, 30, 3000);
var endPoint = new Cesium.Cartesian3.fromDegrees(-112, 25, 1000000);

//Obtain vector by taking difference of the end points
var scratch = new Cesium.Cartesian3();
var difference = Cesium.Cartesian3.subtract(startPoint, endPoint, scratch);
console.log("Difference: " + difference)

//Obtain surface normal by normalizing the starting point position
var surfaceNormal = Cesium.Cartesian3.normalize(startPoint, scratch);
console.log("Surface normal: " + surfaceNormal)

//Take the dot product of your given vector and the surface normal
var dotProduct = Cesium.Cartesian3.dot(difference, surfaceNormal)
console.log("Dot product: " + dotProduct)

//Arcos the result
var angle = Math.acos(dotProduct)
console.log("Angle: " + angle)

``

Hi Fidel,

There were a couple of issues

  1. Need to normalize the difference vector

  2. Difference vector should be end - start to get a vector pointing towards the end point

  3. Use more than one scratch vector – the difference vector was getting overwritten since scratch was used to store the normal also (which is why you were getting a dot product of one)

  4. Use 90 - result to get the angle from the ground since this computation gets the angle between the difference vector and the surface normal.

Here’s the code with the fixes: http://cesiumjs.org/Cesium/Apps/Sandcastle/?src=Hello%20World.html&label=Showcases&gist=fad75b393e2f4ada2f09870d8ce8957b

I didn’t get a chance to test it thoroughly, but give it a try.

Hope that helps,

  • Rachel

Thanks Rachel, much appreciated.

I think something must be wrong because it’s calculating 89 degrees but the line looks more like 60 degrees:

Hi Fidel,

There was one last bug, arccos returns results in radians. Here’s the working version: http://cesiumjs.org/Cesium/Apps/Sandcastle/?src=Hello%20World.html&label=Showcases&gist=d917ac40dfb225cb9899a84403b0c719

Best,

  • Rachel

You need to convert radians to degrees, giving 47.7 degrees.

Superb, I can’t thank you enough. This is really good

Add property arcType: Cesium.ArcType.NONE, to polyline to get a straight line.

1 Like

@jumpjack

Thank you for adding this here - it’s great advice! I will point community members to this thread if similar questions arise in the future.

-Sam

Hi, I want to calculate angle between two lines, which means first line would be used as reference for elevation instead of terrain or ground level. How can i create two lines and then perform similar measurements as applied on a single line here?