Как уменьшить размерность некоторых трехмерных точек, которые находятся на одной плоскости, до 2D в Unity? - PullRequest
1 голос
/ 21 апреля 2019

У меня есть массив из четырех трехмерных точек (Vector3[]), которые все находятся в одной плоскости.Я использую Unity с C#, и цель состоит в том, чтобы использовать 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)
};

Так как Триангулятор предназначен только для 2D, и всеточки находятся на одной плоскости, подход должен состоять в том, чтобы вычислять базисные векторы или главные компоненты плоскости, но я не мог найти как.Я хочу уменьшить размерность точек до 2D, чтобы использовать для них Triangulator таким образом, чтобы получающиеся треугольники лежали на плоскости.

Таким образом, мои желаемые выходные данные - это только треугольники.

Исходный код для Triangulator находится в здесь , и моя цель - создать сетку для заданных точек, но, как вы видите следующий пример кода , точки входа триангулятора должны быть в 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;
    }
}

1 Ответ

1 голос
/ 22 апреля 2019

Раствор 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 - Использование триангулятора

Если квад не выпуклый или вам действительно нужно использовать библиотечный триангулятор, преобразуйте все вершины таким образом, чтобы они находились на плоскости 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);
}

Я не рекомендую использовать Триангулятор только для 4 точек, образующих стену. Однако это должно пригодиться для сложных многоугольников и для невыпуклых форм.

...