Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Polyline Intersection With Terrain in Cesium

I am using Cesium, and am trying to detect where a polyline intersects with the terrain on the Earth. I have a polyline that begins at some point in the air and is drawn towards the Earth at a certain angle.

Right now I am calculating the end point just using a set distance, so I have a start and endPoint. I want to detect where this polyline first hits the Earth's surface and stop drawing it at that point. For example, if there is a tall mountain, I don't want the line to continue on the other side of the mountain.

I've tried a few different approaches using IntersectionTests, specifically the grazingAltitudeLocation and rayEllipsoid but have not had any luck. I have been creating a ray with the start and end points of my polyline and then using the viewer.scene.globe.ellipsoid as the ellipsoid in the functions. I keep getting the starting point returned as the intersection point.

Does anyone have any idea what I am doing wrong, or suggestions on a different way to do this? Any help would be greatly appreciated.

EDIT: This is edited/added content

Here is the code I used, grazingAltitudeLocation returns the start point and rayEllipsoid returns undefined.

var viewer = new Cesium.Viewer('cesiumContainer');
var scene = viewer.scene;
var globe = scene.globe;
var ellipsoid = scene.globe.ellipsoid;
var primitives = scene.primitives;

globe.depthTestAgainstTerrain = true;

var cesiumTerrainProviderMeshes = new Cesium.CesiumTerrainProvider({url : '//cesiumjs.org/stk-terrain/tilesets/world/tiles'});
scene.terrainProvider = cesiumTerrainProviderMeshes;

var startLon = -117.69;
var startLat = 35.69;
var startElv = 20000;
var endLon = -120.0417;
var endLat = 39.0917;
var endElv = 0;

var startCart = Cesium.Cartographic.fromDegrees(startLon, startLat, startElv);
var start = ellipsoid.cartographicToCartesian(startCart);

var endCart = Cesium.Cartographic.fromDegrees(endLon, endLat, endElv);
var end = ellipsoid.cartographicToCartesian(endCart);

var ray = new Cesium.Ray(start, end);

var intersection = Cesium.IntersectionTests.grazingAltitudeLocation(ray, ellipsoid);

var intersection2 = Cesium.IntersectionTests.rayEllipsoid(ray, ellipsoid);
var point = Cesium.Ray.getPoint(ray, intersection2.start);
like image 488
user3613162 Avatar asked Aug 18 '14 22:08

user3613162


1 Answers

I think you should do picking on Globe, not on the Ellipsoid. Hope this would help:

function pickGlobeIntersection(viewer, p0, p1) {
      //all positions are in Cartesian3
      var direction = new Cesium.Cartesian3();
      Cesium.Cartesian3.subtract(p1, p0, direction);
      Cesium.Cartesian3.normalize(direction, direction);

      var ray = new Cesium.Ray(p0, direction);
      var hitPos = viewer.scene.globe.pick(ray, viewer.scene);

      if ((hitPos !== undefined) && (hitPos !== null)) {
        return hitPos;
      } else {
        return null;
      }
}

Regards

like image 114
jojo Avatar answered Jan 03 '23 14:01

jojo