I have a sandcastle
What I am trying to do is determine whether two polygons overlap. However, I only care if they overlap if all of the points from the polygons could be visible.
To solve this problem, my plan is to:
- project the points from the polygons to the window
- using the projected polygons, perform an easy 2D polygon intersection
- win
Projecting points from the polygons is easy using Cesium.SceneTransforms.wgs84ToWindowCoordinates
.
The problem I am having is I am not sure how to determine whether or not a point in a polygon is facing away from the window. How can I do that?
One idea I had was the following:
function testPolygon() {
source.entities.values.forEach( (entity) => {
const name = entity.properties.name?.getValue();
const positions = entity.polygon.hierarchy.valueOf().positions;
const camera = viewer.camera;
const cameraDirection = camera.direction;
const cameraFrustum = camera.frustum;
const cameraNearDistance = cameraFrustum.near;
const nearPlane = new Cesium.Plane( cameraDirection, cameraNearDistance )
const origin = new Cesium.Cartesian3()
positions.forEach( (position) => {
const windowCoordinate = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, position);
console.log( "position", position );
const positionRay = new Cesium.Ray( origin, position )
const intersection = Cesium.IntersectionTests.rayPlane( positionRay, nearPlane )
})
});
}
The idea here is to construct the near plane from the camera, create a ray from the globe origin ( (0,0,0)? ), and then do an intersection test.
However, it is not working. But, I am not sure why. I am missing something fundamental, but I am not sure what that is yet.
Hi there,
There are some great geospatial helper libraries available which can help with these kinds of calculations, for example turf.js.
Thank you. I found turf as well. Turd did help resolve this issue.
I still needed to determine whether or not a polygon was visible or not. The reason was to limit the number of polygon intersection calculations I needed to do, which I believe is a more expensive operation. For that I used the core of the solution mentioned above. I thought it was not working, but it apparently does.
I had a fixed set of polygons that weren’t going to change. For that set, created a bounding sphere for each one. I could then use:
const cullingVolume = cameraFrustum.computeCullingVolume(camera.position, camera.direction, camera.up)
cullingVolume.computeVisibility(sphere)
for an initial pass.
For that pass the cullingVolume check, I am doing one more check, but will probably get rid of it soon as it appears unnecessary.
const windowCoordinate = Cesium.SceneTransforms.wgs84ToWindowCoordinates(viewer.scene, sphere.center)
const positionRay = new Cesium.Ray(origin, sphere.center)
const intersection = Cesium.IntersectionTests.rayPlane(positionRay, nearPlane)
Then, I start using turf.intersect to check the polygons that get through both passes.
I am pretty sure I am not taking into account the curvature of the globe, but a few small errors in my calculation are acceptable.