Polylines curving with the shape of the earth

I am currently working with the polylines component and noticed that the polyline does not curve with the shape of the earth. I noticed that when I draw a line across the United States, Cesium just draws a straight line from point A to point B.

Does Cesium have a component that curves with the surface of the earth? I noticed that polylineGeometry has this capability (through the Sandcastle demo), but it's rendered through a series of polylines?

Thank you,

Hi Lydia,

You can compute a curve with EllipsoidGeodesic and pass the points to the polyline.


Hi Lydia,

For a polyline with several points, yes, you would compute a curve between each adjacent pair of points and then combine these into one array. There isn’t a helper for this yet.

As for LEFT_CLICK not firing, I am not the best person to ask, but it could be a bug. Does the following example work? It uses LEFT_DOWN.




Actually, I think the function PolylinePipeline.scaleToSurface would work for a polyline with several points. It takes an array of Cartesian3 points and uses EllipsoidGeodesic to raise them to the surface.


Patrick, I'm a bit confused. I have created the curves using EllipsoidGeodesic. Which points do I now pass into the polyline?

Hannah, does that method just raise the points or the polyline? My points are currently on the surface of the earth, but the line is going through the globe. For example, when I place a marker in California and another in Washington DC. The points are visible on the surface, but the polyline, when zoomed in, is not.

Thank you both!

Hi Patrick,

I don’t mean to rush you, but are you able to answer the questions mentioned in my last post? After creating the curves using EllipsoidGeodesic, how do I pass them into the polyline?



Hello Lydia,

Yes, PolylinePipeline.scaleToSurface will raise the points of the polyline to the surface if it goes through the globe. It uses the EllipsoidGeodesic Patrick mentioned to find the subpositions.

I just realized that it returns a list of numbers instead of a list of Cartesian3s though. I re-worked the functions you need below so that it returns a list of Cartesian3s instead. Send your original positions to the scaleToSurfaceCartesian function, then use the returned list as your position input when you create a polyline.

function generateCartesianArcCartartesian(p1, p2, granularity, ellipsoid) {

var first = ellipsoid.scaleToGeodeticSurface(p1, scaleFirst);

var last = ellipsoid.scaleToGeodeticSurface(p2, scaleLast);

var separationAngle = Cartesian3.angleBetween(first, last);

var numPoints = Math.ceil(separationAngle/granularity);

var result = ;

var start = ellipsoid.cartesianToCartographic(first, carto1);

var end = ellipsoid.cartesianToCartographic(last, carto2);

ellipsoidGeodesic.setEndPoints(start, end);

var surfaceDistanceBetweenPoints = ellipsoidGeodesic.getSurfaceDistance() / (numPoints);

start.height = 0;

var cart = ellipsoid.cartographicToCartesian(start);


for (var i = 1; i < numPoints; i++) {

var carto = ellipsoidGeodesic.interpolateUsingSurfaceDistance(i * surfaceDistanceBetweenPoints, carto2);

cart = ellipsoid.cartographicToCartesian(carto);



return result;


funciton scaleToSurfaceCartesian(positions, granularity, ellipsoid) {

if (!defined(positions)) {

throw new DeveloperError(‘positions is required’);


granularity = defaultValue(granularity, CesiumMath.RADIANS_PER_DEGREE);

ellipsoid = defaultValue(ellipsoid, Ellipsoid.WGS84);

var length = positions.length;

var newPositions = ;

for (var i = 0; i < length - 1; i++) {

var p0 = positions[i];

var p1 = positions[i+1];

newPositions = newPositions.concat(generateCartesianArcCartartesian(p0, p1, granularity, ellipsoid));


var lastPoint = positions[length-1];

var carto = ellipsoid.cartesianToCartographic(lastPoint, carto1);

carto.height = 0;

var cart = ellipsoid.cartographicToCartesian(carto, cartesian);


return newPositions;


Best Regards,


Thanks, Hannah. I'll try to implement this! :slight_smile: