简体   繁体   English

从 three.js 中的 3 个顶点渲染平面

[英]Render plane from 3 vertices in three.js

I'm trying to render a plane a set of 3 vertices (as shown).我正在尝试为一个平面渲染一组 3 个顶点(如图所示)。 However every method I tried (mostly from SO or the official three.js forum) doesn't work for me.但是,我尝试过的每种方法(主要来自 SO 或官方 three.js 论坛)对我都不起作用。

// 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).我已经尝试了以下代码来计算平面的宽度和高度,但我认为它过于复杂(因为我只计算 X 和 Y 坐标,我认为如果我还添加 Z,我的代码将呈指数增长-坐标和飞机的 position 到这个逻辑)。

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.示例:我想创建一个具有 A、B 和 C 三个角的平面和一个具有 D、E 和 F 三个角的平面。

Example Video示例视频

You can use THREE.Plane.setFromCoplanarPoints() to create a plane from three coplanar points.您可以使用THREE.Plane.setFromCoplanarPoints()从三个共面点创建平面。 However, an instance of THREE.Plane is just a mathematical representation of an infinite plane dividing the 3D space in two half spaces.然而, THREE.Plane的实例只是将 3D 空间分成两个半空间的无限平面的数学表示。 If you want to visualize it, consider to use THREE.PlaneHelper .如果您想将其可视化,请考虑使用THREE.PlaneHelper Or you use the approach from the following thread to derive a plane mesh from your instance of THREE.Plane .或者您使用以下线程中的方法从您的THREE.Plane实例派生平面网格。

Three.js - PlaneGeometry from Math.Plane Three.js - 来自 Math.Plane 的 PlaneGeometry

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.最后只需从这一点创建 PlaneGeometry 并创建网格。 Code is in typescript. Code here:代码在 typescript。代码在这里:

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);
  }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM