TriangleNet的使用

这篇博客介绍了如何在Unity中利用预编译的DLL库进行二维图形的三角剖分。作者提供了Triangulation和TriangulatorTest两个脚本,前者实现了三角剖分的函数,后者用于测试和展示剖分效果。通过将点和孔洞列表输入到函数,可以生成和显示三角形网格。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

下载:传送门 ,提取码:4z74 
这个是我编译好的dll库,下载后直接放到新建立的Unity项目Assets下即可;

 建立Triangulation脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using TriangleNet.Geometry;

public class Triangulation : MonoBehaviour
{
    /// <summary>
    /// 三角剖分是否成功
    /// </summary>
    /// <returns></returns>
    public static bool triangulate(List<Vector2> points, List<List<Vector2>> holes, out List<int> outIndices, out List<Vector3> outVertices )
    {
        // 三角化后输出的信息
        outIndices = new List<int>();
        outVertices = new List<Vector3>();

        Polygon poly = new Polygon();

        // points and segments
        for (int i = 0; i < points.Count; i++)
        {
            poly.Add(new Vertex(points[i].x,points[i].y));

            if (i == points.Count - 1)
            {
                poly.Add(new Segment(new Vertex(points[i].x, points[i].y), new Vertex(points[0].x, points[0].y)));
            }
            else
            {
                poly.Add(new Segment(new Vertex(points[i].x,points[i].y),new Vertex(points[i+1].x,points[i+1].y)));
            }
        }
        
        // holes   
        for(int i = 0; i < holes.Count; i++)
        {
            List<Vertex> vertices = new List<Vertex>();
            for(int j = 0; j< holes[i].Count;j++)
            {
                vertices.Add(new Vertex(holes[i][j].x,holes[i][j].y));
            }
            poly.Add(new Contour(vertices), true);
        }

        var mesh = poly.Triangulate();

        foreach(ITriangle t in mesh.Triangles)
        {
            // 三个点  
            for(int j = 2; j >= 0; j--)
            {
                bool found = false;
                // 去重
                for (int k = 0; k < outVertices.Count; k++)
                {
                    if((outVertices[k].x == t.GetVertex(j).X) && (outVertices[k].z == t.GetVertex(j).Y))
                    {
                        outIndices.Add(k);
                        found = true;
                        break; 
                    }
                }
                if (!found)
                {
                    outVertices.Add(new Vector3((float)t.GetVertex(j).X, 0, (float)t.GetVertex(j).Y));
                    outIndices.Add(outVertices.Count-1);
                }
            }
        }
        return true;
    }
}

TriangulatorTest脚本:

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class TriangulatorTest : MonoBehaviour
{
  
    void Start()
    {
        GameObject go = new GameObject();
        go.name = "Cross";
        MeshFilter mf = go.AddComponent<MeshFilter>();
        MeshCollider mc = go.AddComponent<MeshCollider>();
        go.AddComponent<MeshRenderer>();

        Mesh mesh = mf.mesh;

        List<Vector2> points = new List<Vector2>();
        List<List<Vector2>> holes = new List<List<Vector2>>();
        List<int> indices = null;
        List<Vector3> vertices = null;

        // construct
        points.Add(new Vector2(10,0));
        points.Add(new Vector2(20, 0));
        points.Add(new Vector2(20, 10));
        points.Add(new Vector2(30, 10));
        points.Add(new Vector2(30, 20));
        points.Add(new Vector2(20, 20));
        points.Add(new Vector2(20, 30));
        points.Add(new Vector2(10, 30));
        points.Add(new Vector2(10, 20));
        points.Add(new Vector2(0, 20));
        points.Add(new Vector2(0, 10));
        points.Add(new Vector2(10, 10));

        List<Vector2> hole = new List<Vector2>();
        hole.Add(new Vector2(12,12));
        hole.Add(new Vector2(18, 12));
        hole.Add(new Vector2(18, 18));
        hole.Add(new Vector2(12, 18));

        holes.Add(hole);

        // 剖分
        Triangulation.triangulate(points, holes, out indices, out vertices);

        foreach(var v in vertices)
        {
            Debug.Log(v);
        }

        // 重新计算法线等信息
        mesh.Clear();
        mesh.vertices = vertices.ToArray();
        mesh.triangles = indices.ToArray();
        // 网格几何体和顶点在内部重新排序,提高渲染性能
        mesh.Optimize();
        mesh.RecalculateNormals();

        go.GetComponent<MeshCollider>().sharedMesh = mesh;

        Vector2[] uvs = new Vector2[mesh.vertices.Length];
        for(int i = 0; i < uvs.Length; i++)
        {
            uvs[i] = new Vector2(mesh.vertices[i].x,mesh.vertices[i].y);
        }
        mesh.uv = uvs;
    }   


    void Update()
    {
        
    }
}

在场景下建立空物体,命名为Triangulator,挂载TriangulatorTest脚本:

直接运行即可,运行结果:

 

 代码里面有我的简单注解,有问题的地方随时联系我讨论哈!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值