Intersection point between ray and plane is not correct

Hi Cesium Team,

This is Hiroshi

It has been great using Cesium SDK.

However, I encountered an issue in that I cannot get the intersection point between ray and plane correctly.

Here is the whole code.

Sandcastle

The issue is here.

It looks like a bug to me but it might be just my misunderstanding.

handler.setInputAction(function(event) {
var clickedPoint = viewer.scene.pickPosition(event.position);

if(!clickedPoint) return;

console.log(clickedPoint);
const ray = viewer.camera.getPickRay(clickedPoint);
const projectedPoint = Cesium.IntersectionTests.rayPlane(ray, plane);
viewer.entities.add({
position: projectedPoint,
point: {
color: Cesium.Color.BLUE,
pixelSize: 100
}
});

Best regards,

Hiroshi

I think that there are two issues:


1: The camera.getPickRay function expects the window position (and not the clicked position) as its argument. So the line for computing the picking ray should be

const ray = viewer.camera.getPickRay(event.position);

An aside: When trying to visualize the clicked point, note that scene.pickPosition already does return the world position. So you could just visualize that:

  viewer.entities.add({
    position: clickedPoint, // Use clickedPoint here
    point: {
      color: Cesium.Color.BLUE,
      pixelSize: 10,
    },
  });

But your goal seemed to be to actually compute the intersection manually.


2: When you want to compute the intersection between the picking ray and the plane, you have to take the position of the plane into account. Note that the plane object itself is only a mathematical description of the plane. It is not the object that you see on the screen. The object that you see on the screen is the entity that is created by calling

viewer.entities.add({
  position: planePosition,
  plane: {
    plane: plane,
...

And this entity uses the planePosition to compute the visual representation of the plane, oriented properly for that position on the globe.

Or to put it that way: When you compute the ray, then this refers to what you see on the screen. And one could think that this ray intersects the plane. But it does not really intersect the plane, but only the visual representation of that plane.

There are different ways to handle this. Generally, you have to make sure that the intersection test that is done with IntersectionTests.rayPlane takes place in the right space or coordinate system.

One possible solution is:

  1. Transform the ray into the space of the actual plane object
  2. Perform the intersection test
  3. Transform the intersection point back into the space of the visual representation of the plane

I have added this in the following sandcastle. But with a disclaimer: I did not follow all the computations that you did there (and I think that adding the planePosition and the worldNormal does not seem to make much sense). And there are certainly easier and more elegant solutions for this. As I said: Maybe you can just use the clickedPoint directly. You could also try to move the plane object to the desired space, and add the plane entity at a position of (0,0,0). But this sandcasle shows the solution that I described abve, just to illustrate the maths, and the point of bringing the ray and the plane object into the same space.

1 Like

@Marco13 Thank you so much for the solution!
I can do one of the thing what I wanted to do.
Changing the coordinate system of ray object was completely out of mind.
I have also tried a Cesium.Plane.projectPointOntoPlane to get the cartesian of the point on the Plane but I haven’t been able to be successful. I probably missed the concept of moving the plane to world coordinate system?

Anyway, my ultimate goal is to change the classification color on the CesiumTileset object withing the selected vertical area. Just like below but it is not changed actually:

image

https://sandcastle.cesium.com/index.html#c=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
I want to make it like this by selecting vertical area dynamically.
image

I know polygon entity can change the classification type of the surrounded area of CesiumTileset horizontally.
However, I do not know how to do that vertically in polygon.
I can think of applying the box entity or like ClassificationPrimitive.
example below:

This question here has the similar objective as mine.

I hope my additional information is not too irrelevant to consult it with you in this post. I can also post it newly if needed.
I am hoping to have your support more.

Best regards,
Hiroshi

Just a short note: I’ll try to allocate some time to look closer into your problem description (from a quick glance, it looks like it’s not entirely trivial, so I cannot promise that I’ll be able to provide a helpful answer). But to avoid duplication, this should further be discussed in the other thread that you opened at Cannot change the classification type by polygon vertically and dynamically

1 Like

Thanks for your reply.
It would be great if you can give me advice there as well.