Search code examples
cesiumjs

Polyline arcs above surface in cesium


Cesium polylines follow the curvature of the earth, between two points, by default. How do I make arcs, which go above the ground, like in this example?

http://armsglobe.chromeexperiments.com/


Solution

  • Here's an example using an interpolation algorithm on Entity positions to compute the smooth arcs. Try loading this in Sandcastle.

    var viewer = new Cesium.Viewer('cesiumContainer');
    
    var numberOfArcs = 50;
    var startLon = -74;
    var startLat = 39;
    
    viewer.clock.clockRange = Cesium.ClockRange.LOOP_STOP;
    
    var startTime = viewer.clock.startTime;
    var midTime = Cesium.JulianDate.addSeconds(startTime, 43200, new Cesium.JulianDate());
    var stopTime = Cesium.JulianDate.addSeconds(startTime, 86400, new Cesium.JulianDate());
    
    for (var i = 0; i < numberOfArcs; ++i) {
        var color = Cesium.Color.fromRandom({
            alpha : 1.0
        });
        var stopLon = Cesium.Math.nextRandomNumber() * 358 - 179;
        var stopLat = Cesium.Math.nextRandomNumber() * 178 - 89;
    
        // Create a straight-line path.
        var property = new Cesium.SampledPositionProperty();
        var startPosition = Cesium.Cartesian3.fromDegrees(startLon, startLat, 0);
        property.addSample(startTime, startPosition);
        var stopPosition = Cesium.Cartesian3.fromDegrees(stopLon, stopLat, 0);
        property.addSample(stopTime, stopPosition);
    
        // Find the midpoint of the straight path, and raise its altitude.
        var midPoint = Cesium.Cartographic.fromCartesian(property.getValue(midTime));
        midPoint.height = Cesium.Math.nextRandomNumber() * 500000 + 2500000;
        var midPosition = viewer.scene.globe.ellipsoid.cartographicToCartesian(
            midPoint, new Cesium.Cartesian3());
    
        // Redo the path to be the new arc.
        property = new Cesium.SampledPositionProperty();
        property.addSample(startTime, startPosition);
        property.addSample(midTime, midPosition);
        property.addSample(stopTime, stopPosition);
    
        // Create an Entity to show the arc.
        var arcEntity = viewer.entities.add({
            position : property,
            // The point is optional, I just wanted to see it.
            point : {
                pixelSize : 8,
                color : Cesium.Color.TRANSPARENT,
                outlineColor : color,
                outlineWidth : 3
            },
            // This path shows the arc as a polyline.
            path : {
                resolution : 1200,
                material : new Cesium.PolylineGlowMaterialProperty({
                    glowPower : 0.16,
                    color : color
                }),
                width : 10,
                leadTime: 1e10,
                trailTime: 1e10
            }
        });
    
        // This is where it becomes a smooth path.
        arcEntity.position.setInterpolationOptions({
            interpolationDegree : 5,
            interpolationAlgorithm : Cesium.LagrangePolynomialApproximation
        });
    }