Unity平面连续点组成的多边形的网格化

来源:互联网 发布:易语言表白源码999 编辑:程序博客网 时间:2024/06/05 11:41

网格化类的使用

伪代码

List<Vector3> points;//空间点的集合Triangulator triangulator = new Triangulator(points);List<int> trigs =  new List<int>(triangulator.Triangulate());List<Vector3> finalp = new List<Vector3>(points.ToArray());mesh.vertices =  finalp.ToArray();mesh.triangles =  trigs.ToArray();

网格化类的实现 Triangulator.cs

using System.Collections.Generic;using UnityEngine;public class Triangulator {    private List<Vector2> m_points = new List<Vector2>();    public Triangulator(List<Vector2> points)    {        initTriangulator(points.ToArray());    }    public Triangulator(List<Vector3> points)    {        m_points.Clear();        for (int i = 0; i < points.Count; i++)        {            m_points.Add(new Vector2(points[i].x,points[i].y));        }    }    public void initTriangulator (Vector2[] points) {        m_points = new List<Vector2>(points);    }    public int[] Triangulate() {        List<int> indices = new List<int>();        int n = m_points.Count;        if (n < 3)            return indices.ToArray();        int[] V = new int[n];        if (Area() > 0)         {            for (int v = 0; v < n; v++)            V[v] = v;        }        else {            for (int v = 0; v < n; v++)                V[v] = (n - 1) - v;        }        int nv = n;        int count = 2 * nv;        var m=0;        for (int v = nv - 1; nv > 2; )         {            if ((count--) <= 0)                return indices.ToArray();            int u = v;            if (nv <= u)                u = 0;            v = u + 1;            if (nv <= v)                v = 0;            int w = v + 1;            if (nv <= w)                w = 0;            if (Snip(u, v, w, nv, V))             {                int a,b,c,s,t;                a = V[u];                b = V[v];                c = V[w];                indices.Add(a);                indices.Add(b);                indices.Add(c);                m++;                s = v;                for (t = v + 1; t < nv; t++)                {                    V[s] = V[t];                    s++;                }                nv--;                count = 2 * nv;            }        }        indices.Reverse();        return indices.ToArray();    }    private float Area () {        int n = m_points.Count;        float A = 0.0f;        int q=0;        for (int p = n - 1; q < n; p = q++) {            Vector2 pval = m_points[p];            Vector2 qval = m_points[q];            A += pval.x * qval.y - qval.x * pval.y;        }        return (A * 0.5f);    }    private bool Snip (int u, int v, int w, int n, int[] V) {        int p;        Vector2 A = m_points[V[u]];        Vector2 B = m_points[V[v]];        Vector2 C = m_points[V[w]];        if (Mathf.Epsilon > (((B.x - A.x) * (C.y - A.y)) - ((B.y - A.y) * (C.x - A.x))))            return false;        for (p = 0; p < n; p++) {            if ((p == u) || (p == v) || (p == w))                continue;            Vector2 P = m_points[V[p]];            if (InsideTriangle(A, B, C, P))                return false;        }        return true;    }    private bool InsideTriangle (Vector2 A, Vector2 B, Vector2 C, Vector2 P) {        float ax,ay,bx,by,cx,cy,apx,apy,bpx,bpy,cpx,cpy,cCROSSap,bCROSScp,aCROSSbp;        ax = C.x - B.x; ay = C.y - B.y;        bx = A.x - C.x; by = A.y - C.y;        cx = B.x - A.x; cy = B.y - A.y;        apx = P.x - A.x; apy = P.y - A.y;        bpx = P.x - B.x; bpy = P.y - B.y;        cpx = P.x - C.x; cpy = P.y - C.y;        aCROSSbp = ax * bpy - ay * bpx;        cCROSSap = cx * apy - cy * apx;        bCROSScp = bx * cpy - by * cpx;        return ((aCROSSbp >= 0) && (bCROSScp >= 0) && (cCROSSap >= 0));    }}
原创粉丝点击