Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calculate elevation angle between two lat/long/alt points using cesiumjs

Using cesiumjs, I'd like to calculate the elevation angle between two points as though we were standing on a hot air balloon at the first point. The points are simple cartographic points (lat, long, altitude).

This picture sums it up nicely enter image description here

After some researching, this was a suggested approach:

To transform your target point in the Earth-fixed frame to this local horizontal plane, you can use Transforms.eastNorthUpToFixedFrame. That returns a Matrix4, which you then multiply your target point vector by, yielding a new vector. Normalize that vector, and then the elevation angle is simply asin(z) of the normalized vector.

This is the code I've put together, but it returns NaN for the multiplication. Any suggestions would be greatly appreciated.

var Cesium = require('cesium');

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

//To transform your target point in the Earth-fixed frame to this local horizontal plane, you can use Transforms.eastNorthUpToFixedFrame.
var effTarget = Cesium.Transforms.eastNorthUpToFixedFrame(endPoint)
console.log("Earth-fixed frame (target): " + effTarget);

//That returns a Matrix4, which you then multiply your target point vector by, yielding a new vector.
var multiplicationResult = new Cesium.Cartesian3();
Cesium.Cartesian3.multiplyComponents(effTarget, endPoint, multiplicationResult)
console.log("Multiplication result: " + multiplicationResult)

//Normalize that vector
var normalizationResult = new Cesium.Cartesian3();
Cesium.Cartesian3.normalize(multiplicationResult, normalizationResult);
console.log("Normalize result: " + normalizationResult)

//and then the elevation angle is simply asin(z) of the normalized vector.
var elevationAngle = Math.asin(normalizationResult.z)
console.log("Elevation angle: " + elevationAngle)
like image 599
Fidel Avatar asked Mar 16 '26 13:03

Fidel


1 Answers

Based on Rachel Hwang's answer:

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 difference = Cesium.Cartesian3.subtract(endPoint, startPoint, new Cesium.Cartesian3());
difference = Cesium.Cartesian3.normalize(difference, new Cesium.Cartesian3());
console.log("Difference: " + difference);

// Obtain surface normal by normalizing the starting point position.
var surfaceNormal = Cesium.Cartesian3.normalize(startPoint, new Cesium.Cartesian3());
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 = 90 - Cesium.Math.toDegrees(Math.acos(dotProduct));
console.log("Angle: " + angle);

Console:

Difference: (-0.696260739885982, -0.7156821634654381, -0.05495473583645852)
Surface normal: (-0.2536245226271608, -0.8295684339468393, 0.4974844871160639)
Dot product: 0.7429570007551259
Angle: 47.9839196010689
like image 70
Ugnius Malūkas Avatar answered Mar 19 '26 02:03

Ugnius Malūkas



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!