以前我寫過一篇文章,不規則圖形uv貼圖的,(http://blog.csdn.net/itolfn/article/details/17240131)當時用的三角剖分的演算法,但是那個演算法有所不完整,有一條這麼規定的:最優性:任意兩個相鄰三角形形成的凸四邊形的對角線如果可以互換的話,那麼兩個三角形六個內角中最小的角度不會變大。就是取四變形的最大化三角形內角去串連對角線,分組兩個三角形,但是有時候不是自己想要的那一個圖形,如圖:
三角剖分演算法會算出ABC和ACD這兩個三角形,但是我們需要ABD和BCD,這時候就不能用了,我研究三角剖分不深,按他的定律去算出就是取的第二個圖形,有哪位大俠知道請告訴小弟,後來我就摒棄了這個演算法,重寫了一套,使用面積劃分的演算法,這樣解決了我所有的問題,任何不規則多邊形都會使uv貼的正好
using System.Collections;using System.Collections.Generic;public class TriangleSubdivision :MonoBehaviour{///三角劃分原理///每劃分一個三角形後,判斷分割成新三角形與分割後剩餘多邊形的面積和是否等於分割前多邊形的面積,如果等於,則表示分割有效,繼續劃分,否則跳過一個頂點繼續判斷下一個三角形,迴圈到剩餘多邊形是三角形為止。public static int[] TriangulatePolygon (Vector2[] XZofVertices , bool is3D) {int VertexCount = XZofVertices.Length;List<TriangleObj> TriangleList = new List<TriangleObj>();List<Vector2> VerticesList = new List<Vector2>();for(int i=0;i<VertexCount;i++){VerticesList.Add(new Vector2(XZofVertices[i].x,XZofVertices[i].y));} if(VertexCount<3) return null;int testindex=0;while (VerticesList.Count>=3&&testindex<100){for (int i = 0; i < VerticesList.Count; i++){testindex++;//如果數組只剩餘3個節點。if(VerticesList.Count==3){TriangleObj nobj = new TriangleObj(VerticesList[0], VerticesList[1], VerticesList[2]);TriangleList.Add(nobj);VerticesList.RemoveAt(1);break;}//所有角點暫存數組List<Vector2> surplusVerticesList = new List<Vector2>();surplusVerticesList.AddRange(VerticesList);if(i+2<VerticesList.Count){//擷取3個點組成一個3角形Vector2[] trianglePoint = new Vector2[3];trianglePoint[0] = VerticesList[i];trianglePoint[1] = VerticesList[i+1];trianglePoint[2] = VerticesList[i+2];//移除三角形用到的中間點,剩餘的多邊形點集合.surplusVerticesList.RemoveAt(i+1);Vector2[] surplusPoints = new Vector2[surplusVerticesList.Count];for(int m=0;m<surplusVerticesList.Count;m++){surplusPoints[m]=surplusVerticesList[m];}//移除前多邊形點集合Vector2[] allPoints = new Vector2[VerticesList.Count];for (int n = 0; n < VerticesList.Count; n++){allPoints[n]=VerticesList[n];}bool isCrose = false;//判斷該多邊形的兩條邊是否相交for(int ii_1 = 0;ii_1<surplusPoints.Length;ii_1++){for(int ii_2 = 0;ii_2<surplusPoints.Length;ii_2++){ if(ii_1 < surplusPoints.Length - 1 && ii_2 < surplusPoints.Length - 1) { if((surplusPoints[ii_1].x == surplusPoints[ii_2].x && surplusPoints[ii_1].y == surplusPoints[ii_2].y)||(surplusPoints[ii_1+1].x == surplusPoints[ii_2].x && surplusPoints[ii_1+1].y == surplusPoints[ii_2].y)||(surplusPoints[ii_1].x == surplusPoints[ii_2+1].x && surplusPoints[ii_1].y == surplusPoints[ii_2+1].y)||(surplusPoints[ii_1+1].x == surplusPoints[ii_2+1].x && surplusPoints[ii_1+1].y == surplusPoints[ii_2+1].y)) { continue; }if(GameObject.Find("Initial").GetComponent<ShareMethods>().CheckCrose(surplusPoints[ii_1],surplusPoints[ii_1+1],surplusPoints[ii_2],surplusPoints[ii_2+1]) &&GameObject.Find("Initial").GetComponent<ShareMethods>().CheckCrose(surplusPoints[ii_2],surplusPoints[ii_2+1],surplusPoints[ii_1],surplusPoints[ii_1+1])) {isCrose = true; break; } }} if(isCrose) { break; }}//判斷分割成新三角形與分割後剩餘多邊形的面積和是否等於分割前多邊形的面積?if(Mathf.Abs(trPolygonArea(trianglePoint,is3D)+trPolygonArea(surplusPoints,is3D)-trPolygonArea(allPoints,is3D))<=0.001f&&!isCrose){ //則表示分割有效,繼續劃分TriangleObj tobj = new TriangleObj(VerticesList[i], VerticesList[i+1], VerticesList[i+2]);TriangleList.Add(tobj);VerticesList.RemoveAt(i+1);i--;break;}else{//否則跳過一個頂點繼續判斷下一個三角形.把第一個點放到數組末尾.Vector2 zeropoint = new Vector2(VerticesList[i].x,VerticesList[i].y);VerticesList.RemoveAt(i);VerticesList.Add(zeropoint);break;}}}}int[] Triangles = new int[3 * TriangleList.Count];for (int ii1 = 0; ii1 < TriangleList.Count; ii1++){TriangleObj tempobj = TriangleList[ii1];Triangles[3 * ii1 + 1] = indexofobjfromList(tempobj.p2,XZofVertices);if(is3D){Triangles[3 * ii1+2] = indexofobjfromList(tempobj.p1,XZofVertices);Triangles[3 * ii1] = indexofobjfromList(tempobj.p3,XZofVertices);}else{Triangles[3 * ii1] = indexofobjfromList(tempobj.p1,XZofVertices);Triangles[3 * ii1+2] = indexofobjfromList(tempobj.p3,XZofVertices);}}return Triangles;} /////根據點擷取多邊形面積static float trPolygonArea(Vector2[] points,bool is3D){ float area = 0; if(is3D) {area = GameObject.Find("Initial").GetComponent<ShareMethods>().PolygonArea(null,points);//面積公式演算法 } else {area = GameObject.Find("Initial").GetComponent<ShareMethods>().PolygonArea(null,points)/1000000; }return area;}static int indexofobjfromList(Vector2 point,Vector2[] points){int index = 0;for(int i=0;i<points.Length;i++){Vector2 temp=points[i];if(Mathf.Abs(point.x-temp.x)<0.001f&&Mathf.Abs(point.y-temp.y)<0.001f){index=i;break;}}return index;}}struct TriangleObj{public Vector2 p1;public Vector2 p2;public Vector2 p3;public TriangleObj(Vector2 point1, Vector2 point2, Vector2 point3){p1 = point1; p2 = point2; p3 = point3;}}這個方法沒什麼改動,只是演算法我改了一下,還是這個類,還是傳你所有的點,會返回你的 Mesh.triangles,這樣就就完美的使自己的mesh根據點貼上自己想要的圖形的uv了