loicnestler
loicnestler

Reputation: 527

Render plane from 3 vertices in three.js

I'm trying to render a plane a set of 3 vertices (as shown). However every method I tried (mostly from SO or the official three.js forum) doesn't work for me.

// example vertices
const vert1 = new THREE.Vector3(768, -512, 40)
const vert2 = new THREE.Vector3(768, -496, 40)
const vert3 = new THREE.Vector3(616, -496, 40)

I already tried the following code for calculating the width and height of the plane, but I think it's way over-complicated (as I only calculate the X and Y coords and I think my code would grow exponentially if I'd also add the Z-coordinate and the plane's position to this logic).

const width = vert1.x !== vert2.x ? Math.abs(vert1.x - vert2.x) : Math.abs(vert1.x - vert3.x)
const height = vert1.y !== vert2.y ? Math.abs(vert1.y - vert2.y) : Math.abs(vert1.y - vert3.y)

Example: I want to create a plane with 3 corners of points A, B and C and a plane with 3 corners of points D, E and F.

Example Video

Upvotes: 2

Views: 1457

Answers (2)

Vít Zadina
Vít Zadina

Reputation: 552

I create algorithm which compute mid point of longest edge of triangle. After this compute vector from point which isn't on longest edge to midpoint. On end just add computed vector to midpoint and you have coordinates of fourth point.

On end just create PlaneGeometry from this points and create mesh. Code is in typescript. Code here:

type Line = {
    startPoint: Vector3;
    startPointIdx: number;
    endPoint: Vector3;
    endPointIdx: number;
    vector: Vector3;
    length: Vector3;
}

 function createTestPlaneWithTexture(): void {
        const pointsIn = [new Vector3(28, 3, 3), new Vector3(20, 15, 20), new Vector3(1, 13, 3)]
        const lines = Array<Line>();

        for (let i = 0; i < pointsIn.length; i++) {
            let length, distVect;
            if (i <= pointsIn.length - 2) {
                distVect = new Vector3().subVectors(pointsIn[i], pointsIn[i + 1]);
                length = distVect.length()
                lines.push({ vector: distVect, startPoint: pointsIn[i], startPointIdx: i, endPoint: pointsIn[i + 1], endPointIdx: i + 1, length: length })
            } else {
                const distVect = new Vector3().subVectors(pointsIn[i], pointsIn[0]);
                length = distVect.length()
                lines.push({ vector: distVect, startPoint: pointsIn[i], startPointIdx: i, endPoint: pointsIn[0], endPointIdx: 0, length: length })
            }
        }
        // find longest edge of triangle
        let maxLine: LineType;
        lines.forEach(line => {
            if (maxLine) {
                if (line.length > maxLine.length)
                    maxLine = line;
            } else {
                maxLine = line;
            }
        })
        //get midpoint of longest edge
        const midPoint = maxLine.endPoint.clone().add(maxLine.vector.clone().multiplyScalar(0.5));
        //get idx unused point
        const idx = [0, 1, 2].filter(value => value !== maxLine.endPointIdx && value !== maxLine.startPointIdx)[0];
        //diagonal point one
        const thirdPoint = pointsIn[idx];
        const vec = new Vector3().subVectors(midPoint, thirdPoint);
        //diagonal point two diagonal === longer diagonal of reactangle
        const fourthPoint = midPoint.clone().add(vec);
        const edge1 = thirdPoint.clone().sub(maxLine.endPoint).length();
        const edge2 = fourthPoint.clone().sub(maxLine.endPoint).length();

        //const topLeft = new Vector3(bottomLeft.x, topRight.y, bottomLeft.y);
        const points = [thirdPoint, maxLine.startPoint, maxLine.endPoint, fourthPoint];
        // console.log(points)
        const geo = new PlaneGeometry().setFromPoints(points)

        const texture = new TextureLoader().load(textureImage);
        texture.wrapS = RepeatWrapping;
        texture.wrapT = RepeatWrapping;
        texture.repeat.set(edge2, edge1);
        const mat = new MeshBasicMaterial({ color: 0xFFFFFFF, side: DoubleSide, map: texture });
        const plane = new Mesh(geo, mat);
  }

Upvotes: 0

Mugen87
Mugen87

Reputation: 31026

You can use THREE.Plane.setFromCoplanarPoints() to create a plane from three coplanar points. However, an instance of THREE.Plane is just a mathematical representation of an infinite plane dividing the 3D space in two half spaces. If you want to visualize it, consider to use THREE.PlaneHelper. Or you use the approach from the following thread to derive a plane mesh from your instance of THREE.Plane.

Three.js - PlaneGeometry from Math.Plane

Upvotes: 2

Related Questions