Set box geometry position and orientation from 3 points

I am representing a plane with box geometry (BoxGeometry(width, height, planeThickness)) where plane thickness is much smaller than width and height.

I am aligning the box with a plane created from three points by applying a matrix to the mesh. I want to accomplish this my applying a single matrix to the mesh, rather that to the mesh and to the geometry, because I need to use the same calculation in other functions.

And the function below successfully places the box representation of the plane through the three points. But the rotation about the plane normal and the position along the plane does not represent the location of the three points. I want to rotate and offset the box along the plane to align it with the two remaining points. But I have not been able to figure out how to do that.

const getMatrixFor3PointPlane = () => {
    const points = getPointsForPlane();
    const point1 = points[0].clone();
    const point2 = points[1].clone();
    const point3 = points[2].clone();
    const plane = new Plane();
    plane.setFromCoplanarPoints(point1, point2, point3);

    const center = point1;
    const focalPoint = center.clone().add(plane.normal);
    const matrix = new Matrix4();
    matrix.lookAt(center, focalPoint, new Object3D().up);
    matrix.setPosition(center);
    return matrix;
};

Screenshot 2023-12-11 at 6.03.47 AM

You can simply apply to your mesh a quaternion which represents rotation from up vector (0, 1, 0) and plain normal, which is a сross product of vectors from point1 to point2 and point3

mesh.applyQuaternion(new THREE.Quaternion().setFromUnitVectors(
    new THREE.Vector3(0,1,0),
    point2.clone().sub(point1).cross(point3.clone().sub(point1)).normalize()
))

Thanks @trueshko. But I need it all in the matrix.

But I tried adding…

    const quatMatrix = new Matrix4();
    quatMatrix.makeRotationFromQuaternion(
        new Quaternion().setFromUnitVectors(
            new Vector3(0, 1, 0),
            point2.clone().sub(point1).cross(point3.clone().sub(point1)).normalize(),
        ),
    );

    matrix.multiply(quatMatrix);

You don’t need multiple matrices, you can apply rotation to your existing matrice:

matrix.makeRotationFromQuaternion(
        new Quaternion().setFromUnitVectors(
            new Vector3(0, 1, 0),
            point2.clone().sub(point1).cross(point3.clone().sub(point1)).normalize(),
        )
).setPosition(center)

`

Thanks @trueshko. Maybe I am misunderstanding. But if I do the following…

export const getMatrixFor3PointPlane = () => {
    const points = getPointsForPlane();
    const point1 = points[0].clone();
    const point2 = points[1].clone();
    const point3 = points[2].clone();

    const center = point1;
    const matrix = new Matrix4();
    matrix
        .makeRotationFromQuaternion(
            new Quaternion().setFromUnitVectors(
                new Vector3(0, 1, 0),
                point2.clone().sub(point1).cross(point3.clone().sub(point1)).normalize(),
            ),
        )
        .setPosition(center);

    return matrix;
};

I get a box that is not through the three points. Using the previous method, the box was aligned with the three points on the plane they created, just not within the plane.

I’m just curious what does this mean:

Assuming the box (blue rectangle) is in the plane of the three points (black), and box’s center is one of the points, then what does “align” mean? The next illustration is most likely not-aligned. How would it look like when the box is aligned?

image

Thanks @PavelBoytchev. Good question. I guess technically it would be the smallest rectangle by area that would go through all three points. But it is not critical. It just has to go through all the points and not have too much overhang. For example. In the first image below, I could just make the rectangle larger until it extended through each point, but that would be too large. That box is the correct size, but it needs to be rotated and translated to go through all three points. The second image is more like what I want.


I see.

Could you tell me the coordinates of the three points from the snapshot. I made some Q-n-D code that may produce plausible results (not guaranteed to be minimal area). I want to try it with your data. Here is what I get with random points:

2 Likes

Yes. Thanks @PavelBoytchev . That is great.

"points": [
    {
     "x": 25.881325015111123,
     "y": -54.843221018845696,
     "z": 1005.6995636272433
    },
    {
     "x": -19.933612712994144,
     "y": -47.000350482003206,
     "z": 583.9372101709666
    },
    {
     "x": -40.457901562441855,
     "y": -48.85426306392774,
     "z": 588.8611391499182
    }
   ]

These points make a perfect fit:

image

The code is here (point coordinates are in lines 68-70):

https://codepen.io/boytchev/full/GRzagBW

2 Likes

Thank you @PavelBoytchev . Sincerely. I have been messing with this for a while now.

1 Like