如何将所有在同一平面上的3D点的维数降低到Unity中的2D?

问题描述 投票:1回答:1

我有一个四个3D点(Vector3[])的数组,它们都在同一个平面上。我正在使用UnityC#,目的是使用2D Traingulator这4点。

using UnityEngine;

Vector3[] vertices3D = new Vector3[] {
    new Vector3(0,10,0),
    new Vector3(50,20,0),
    new Vector3(0,10,30),
    new Vector3(50,20,30)
};

由于Triangulator仅用于2D并且所有点都在同一平面上,因此方法应该是计算基准向量或平面的主要成分,但我找不到如何。我想将点的维数降低到2D,以便将生成的三角形放在平面上的方式使用Triangulator

所以我想要的输出只是三角形。

Triangulator的源代码在here中,我的目标是为给定的点创建一个网格,但是当你看到下面的sample code时,三角测量器的输入点应该是2D:

using UnityEngine;

public class PolygonTester : MonoBehaviour {
    void Start () {
        // Create Vector2 vertices
        Vector2[] vertices2D = new Vector2[] {
            new Vector2(0,0),
            new Vector2(0,50),
            new Vector2(50,50),
            new Vector2(50,100)
        };

        // Use the triangulator to get indices for creating triangles
        Triangulator tr = new Triangulator(vertices2D);
        int[] indices = tr.Triangulate();

        // Create the Vector3 vertices
        Vector3[] vertices = new Vector3[vertices2D.Length];
        for (int i=0; i<vertices.Length; i++) {
            vertices[i] = new Vector3(vertices2D[i].x, vertices2D[i].y, 0);
        }

        // Create the mesh
        Mesh msh = new Mesh();
        msh.vertices = vertices;
        msh.triangles = indices;
        msh.RecalculateNormals();
        msh.RecalculateBounds();

        // Set up game object with mesh;
        gameObject.AddComponent(typeof(MeshRenderer));
        MeshFilter filter = gameObject.AddComponent(typeof(MeshFilter)) as MeshFilter;
        filter.mesh = msh;
    }
}
c# algorithm unity3d geometry triangulation
1个回答
1
投票

解决方案1 ​​ - 琐碎

如果四边形是凸的并且您知道顶点的排序,请使用indices = new double[6]{0,1,2,0,2,3};

解决方案2 - 手动三角测量

如果四边形是凸的,但您不确定排序,请测试方向并调整索引。

edge1 = vertices3D[1] - vertices3D[0];
edge2 = vertices3D[2] - vertices3D[0];
edge3 = vertices3D[3] - vertices3D[0];
normal12 = Vector3.Cross(edge1, edge2);
normal23 = Vector3.Cross(edge2, edge3);
if (Vector3.Dot(normal12, normal23) > 0)
   indices = new double[6]{0,1,2,0,2,3};
else
   indices = new double[6]{0,1,3,0,3,2};

解决方案3 - 使用Triangulator

如果四边形不是凸面或者你真的必须使用库Triangulator,则转换所有顶点,使它们位于XY平面上,第一个顶点位于(0,0,0)

edge1 = vertices3D[1] - vertices3D[0];
edge2 = vertices3D[2] - vertices3D[0];
normal = Vector3.Cross(edge1, edge2).normalized;
rotation = Quaternion.FromToRotation(normal, new Vector3(0,0,1));
Vector2[] vertices2D = new Vector2[vertices3D.Length];
for (int i=0; i<vertices3D.Length; i++) {
    rotatedVertex = rotation * (vertices3D[i]-vertices3D[0]);
    vertices2D[i] = new Vector2(rotatedVertex.x, rotatedVertex.y);
}

我建议不要仅使用Triangulator 4个点来形成墙壁。但是,对于复杂多边形和非凸形状,它应该变得很方便。

© www.soinside.com 2019 - 2024. All rights reserved.