Hi all,
I apologise if this is worded incorrectly, or the code style of my sample is poor, I am brand new to Cesium and trying to learn the ropes. The code provided can be copy-pasted directly into sandcastle, which should illustrate my problem.
What I am trying to achieve:
I want to create a plane, than can be manipulated (position and normal), which will be used to slice a set of points. Points on 1 side of the plane should be coloured red, while points on the other side should be coloured yellow.
I’m having trouble getting a plane to slice a set of points in the correct orientation. The plane I create seems to be perpendicular to the ground (which would be the correct initial state), however the slicing seems to be happening at an angle. I have attempted to draw a line that Illustrates what is being sliced, however I cannot match the line to the plane. It is critical that the plane can be moved, rotated and angled in any direction, and will slice according to its position and normal direction.
I have created a sample application that can be pasted into sandcastle that demonstrates the problem I am having, and would greatly appreciate any help anyone can provide. I’ve spent close to 3 days trying to solve this problem, so this really is my last resort. I have read a lot of documentation and threads, and my understanding is still quite low, so if possible, I would really appreciate some code snippets rather than “you need to do X” advise.
Bonus points if you can integrate some sliders or controls to manipulate the plain in sandcastle for me to test.
Thanks,
Pete
const viewer = new Cesium.Viewer("cesiumContainer");
const degrees = [-107.0, 40.0, 300000.0];
const planeNormal = Cesium.Cartesian3.UNIT_Y;
const planeDimensions = [400000.0, 300000.0];
// Calculate the end point of the line in the direction of the plane's normal
const lineLength = 500000.0;
const scaledNormal = Cesium.Cartesian3.multiplyByScalar(planeNormal, lineLength, new Cesium.Cartesian3());
const redPlanePosition = Cesium.Cartesian3.fromDegrees(...degrees);
const lineEndPoint = Cesium.Cartesian3.add(redPlanePosition, scaledNormal, new Cesium.Cartesian3());
function createPlaneFromPositionNormal(position, normal) {
const distance = Cesium.Cartesian3.dot(normal, position);
return new Cesium.Plane(normal, -distance);
}
// This is where the slicing is calculated from (i think??) Help!
const redPlane = viewer.entities.add({
name: "Red plane with black outline",
position: Cesium.Cartesian3.fromDegrees(...degrees),
plane: {
plane: createPlaneFromPositionNormal(Cesium.Cartesian3.fromDegrees(...degrees), planeNormal),
dimensions: new Cesium.Cartesian2(...planeDimensions),
material: Cesium.Color.RED.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.BLACK,
},
});
// This is where I want the plane to be (but not the correct angle)
const greenPlane = viewer.entities.add({
name: "Green plane with black outline",
position: Cesium.Cartesian3.fromDegrees(...degrees),
plane: {
plane: new Cesium.Plane(planeNormal, 0.0),
dimensions: new Cesium.Cartesian2(...planeDimensions),
material: Cesium.Color.GREEN.withAlpha(0.5),
outline: true,
outlineColor: Cesium.Color.BLACK,
},
});
// Add the line to the viewer
const normalLine = viewer.entities.add({
name: "Normal Line",
polyline: {
positions: [redPlanePosition, lineEndPoint],
width: 5,
material: Cesium.Color.BLUE,
},
});
const pointStyle = {
pixelSize: 10,
color: Cesium.Color.YELLOW,
};
const points = [
viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-107.0, 41.0, 200000.0), point: pointStyle }),
viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-107.0, 39.0, 200000.0), point: pointStyle }),
viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-105.0, 41.0, 200000.0), point: pointStyle }),
viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-105.0, 39.0, 200000.0), point: pointStyle }),
viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-107.0, 41.0, 400000.0), point: pointStyle }),
viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-107.0, 39.0, 400000.0), point: pointStyle }),
viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-105.0, 41.0, 400000.0), point: pointStyle }),
viewer.entities.add({ position: Cesium.Cartesian3.fromDegrees(-105.0, 39.0, 400000.0), point: pointStyle }),
];
// All points *in front of* the plane, should be coloured yellow, while ones behind, red.
for (let point of points) {
const pointPosition = point.position.getValue(viewer.clock.currentTime);
const redPlanePosition = redPlane.position.getValue(viewer.clock.currentTime);
const redPlaneEquation = createPlaneFromPositionNormal(redPlanePosition, planeNormal);
const distance = Cesium.Plane.getPointDistance(redPlaneEquation, pointPosition);
if (distance <= 0) {
point.point.color = Cesium.Color.RED;
}
}
viewer.zoomTo(viewer.entities);