Screen coordinates makes no sense

Hi everyone,

I have an environment with several meshes that are supposed to relate to each other. In particular, one rectangle mesh is supposed to be be checked foe whether another mesh is located on it or whether it crosses over its borders. So I am currently aiming to determine whether or not something is within the borders of the rectangle mesh. So I got this function to check if a certain position is within the rectangle.

By the way, I am a novice both to using Three.js and to practically applying Computer Graphics concepts, so my mistake might be really basic.

function clickToCheckOnRectangle(position, rectangle, camera, screen_width,screen_height, devicePixelRatio){


    rectangle.updateMatrixWorld();

    let rectWorld = new THREE.Vector3();
    rectWorld = rectangle.getWorldPosition(rectWorld);

    const rectPos = worldCoordinatesToScreenCoordinates(rectWorld,camera, screen_width,screen_height);
    console.log(rectPos);
    const rectWidth = rectangle.geometry.parameters.width;
    const rectHeight = rectangle.geometry.parameters.height;

    const rectLeft = rectPos.x - rectWidth / 2;
    const rectRight = rectPos.x + rectWidth / 2;
    const rectTop = rectPos.y + rectHeight / 2;
    const rectBottom = rectPos.y - rectHeight / 2;

    const isOutside = (position.x < rectLeft || position.x > rectRight || 
        position.y < rectBottom || position.y > rectTop);

}

I am currently using the following function to convert screen coordinates into world coordinates

function worldCoordinatesToScreenCoordinates(worldCoordinateVector, camera, screen_width, screen_height, devicePixelRatio){

    camera.updateMatrixWorld();
    camera.updateProjectionMatrix();

    let projectedVector = worldCoordinateVector.project(camera);

    projectedVector.x = (projectedVector.x+1)* screen_width/2;
    projectedVector.y = -(projectedVector.y -1) * screen_height/2;

    projectedVector.z = 0;

    return projectedVector;
};

In order to be able to relate the meshes to their position, I also have a function that prints the position of the mouse on clicking, which also triggers clickToCheckOnRectangle:

window.addEventListener("click", function(event){
            let event_position = {x:event.clientX, y: event.clientY }
       
            clickToCheckOnRectangle(event_position, stencilBuffer, camera, window.innerWidth, window.innerHeight, window.devicePixelRatio);

            console.log(`x position: ${event.clientX}, y position: ${event.clientY}`);

        });

So now I am using my function clickToCheckOnRectangle to check if clicking on the rectangle gets correctly registered. Currently, when I print rectLeft, rectRight, rectTop and RectBottom to the console (in this order), I get the following values (please note that the viewport has a size of 1280 horizontally and 273 vertically, at least when the Firefox Developer tools are open):
image

image

Besides the negative value that does not make sense as these are screen coordinates that are not negative, this data belongs to this rectangle (which is usually covered by other meshes in the program ):

So the data output does not make sense for such a small rectangle. When I click to use the checking function, the covered area where isOutside is false seems to be much bigger than this rectangle, so something is going wrong there somewhere. The input for the function should match the rectangle is showed you.

Do you have any idea what could cause this weirdness? Did I mess up some coordinate system conversion? If you need more code of the program (I tried to limit myself to stuff that seemed relevant), just tell me.

Thanks in advance!

  1. Don’t work with pixel values in the 3D scene, pixels don’t mean much there.
  2. You can use Box3.containsPoint to check whether specific bounding box contains a point. To check whether a specific bounding box contains another mesh - just use Box3.expandByObject - if the box doesn’t expand at all, it means object is contained entirely within the bounding box. For any more fancy intersection calculations I’d personally use a Raycaster / three-mesh-bvh - avoid using explicit math, it’s quite error prone.
1 Like

Hi mjurczyk,

thank you for the quick reply.

  1. By pixel values, you mean the values for window.innerwidth and window.innerheight or just all screen coordinate values in general? Does this count for the 3D scene even though all z values of objects in my program are 0 except for the camera and I do not really use the third dimension?

  2. I was hesitant to use bounding boxes because I did some research about them earlier where I found out that Three.js’s bounding boxes are not that accurate to the actual objects and as I need to check whether a certain border is crossed I feared that the calculation might not be accurate using the bounding box. The functions I saw about correcting the accuracy did not work as well for me as I wanted.

I will try if bounding boxes works for my purpose, now. I will get back to this thread if I have any issues.

Thank you for the feedback.