1

I want to move a Cartesian3 position vertically up by x amount of units (e.g., meters).

I DON'T want to convert it to Cartographic, add x to the altitude and covert back to Cartesian3.

What would be the best way (performance-wise) to do this operation?

Ugnius Malūkas
  • 2,649
  • 7
  • 29
  • 42

2 Answers2

1

Super easy.

    const position = Cesium.Cartesian3.fromDegrees(129.507780, 42.9075, 0);
    const origMagnitude = Cesium.Cartesian3.magnitude(position);
    const verticalAmount = 10;
    const newMagnitude = origMagnitude + verticalAmount;
    const scalar = newMagnitude / origMagnitude;

    const newPosition = new Cesium.Cartesian3();
    Cesium.Cartesian3.multiplyByScalar(position, scalar, newPosition);

Here's Sandcastle link

ZhefengJin
  • 930
  • 8
  • 17
  • Hi @ZhefengJin, thanks! One more question. As I understand this wouldn't apply for X/Y direction. What if I want to move point X or Y direction? Can I achieve that with a similar logic? – Ugnius Malūkas Sep 07 '21 at 08:45
  • when you say x, y-direction, at which coordinate do you mean? ECEF or local coordinate? – ZhefengJin Sep 07 '21 at 12:43
1

For what it's worth, moving directly away from the center of the Earth (as shown in another answer here) is nearly up but not exactly a perfect local up. The reason is the Earth actually bulges a little around the equator due to rotation, and indeed the WGS84 ellipsoid (used by Cesium) is not a perfect sphere, it has the bulge included. Moving away from its center gives you the "Geocentric up", but not the "Geodetic up" which is the true local up. Admittedly, it's a very slight difference.

One way to find the proper local up is to ask for a local coordinate system from a given starting position. In the following example, local up (as well as local East & local North) are calculated for a known position on the surface of WGS84. A green dot is shown at the starting location, a yellow dot is shown above that, and a blue dot is shown to the East. (West would be -X, North & South are +Y and -Y in this local frame).

Sandcastle live demo

var viewer = new Cesium.Viewer("cesiumContainer");

// Get the transform from local east-north-up to Earth Fixed at a known position.
var center = Cesium.Cartesian3.fromDegrees(-79.0, 40.0);
var transform = Cesium.Transforms.eastNorthUpToFixedFrame(center);

// Green dot at center
viewer.entities.add({
  position: center,
  point: {
    color: Cesium.Color.LIME,
    pixelSize: 10
  }
});

// Yellow dot 40 meters above
var above = Cesium.Matrix4.multiplyByPoint(transform,
    new Cesium.Cartesian3(0, 0, 40.0), new Cesium.Cartesian3());

viewer.entities.add({
  position: above,
  point: {
    color: Cesium.Color.YELLOW,
    pixelSize: 10
  }
});

// Blue dot 40 meters East (straight line East of center, not following Earth curvature)
var east = Cesium.Matrix4.multiplyByPoint(transform,
    new Cesium.Cartesian3(40.0, 0, 0), new Cesium.Cartesian3());

viewer.entities.add({
  position: east,
  point: {
    color: Cesium.Color.LIGHTSKYBLUE,
    pixelSize: 10
  }
});

viewer.zoomTo(viewer.entities);
emackey
  • 11,818
  • 2
  • 38
  • 58