Mesh减面算法详解
本篇文章所講述如何實(shí)現(xiàn)mesh減面工具。??
思想由作者創(chuàng)建。
目錄
1、Unity Mesh對(duì)象里的數(shù)據(jù)構(gòu)成
2、智能減面詳解
Unity Mesh對(duì)象里的數(shù)據(jù)構(gòu)成
? 這里主要介紹相關(guān)的數(shù)據(jù),如下圖。
??? Triangles數(shù)組存儲(chǔ)的是所有三角形對(duì)應(yīng)于vertices數(shù)組里的頂點(diǎn),triangles從坐標(biāo)0~n依次存儲(chǔ)了每個(gè)三角形三個(gè)頂點(diǎn)在vertices下的位置,uv也是跟vertices對(duì)應(yīng)的,知道這些后我們就可以對(duì)mesh任意操作了。
智能減面詳解
減面前數(shù)據(jù)結(jié)構(gòu)準(zhǔn)備
??? 在減面之前首先要將每個(gè)頂點(diǎn)自己做管理,以便容易操作,下面是偽代碼,主要是因?yàn)檫@些數(shù)據(jù)對(duì)減面息息相關(guān)。
??? 首先要把mesh的頂點(diǎn)數(shù)據(jù)單獨(dú)輸出出來,每個(gè)頂點(diǎn)的存儲(chǔ)結(jié)構(gòu)可以是這樣:
struct Triangle{Vertice [] vert;}struct Vertice{//自身頂點(diǎn)Vector3 vert;//與自身連接的三角形List<Triangle> nearbyTri;//與自身相連的點(diǎn)List<Vector3> nearbyVerts;//是否為邊頂點(diǎn)bool border;}1、找到連接自身的三角形
??? 將mesh里的頂點(diǎn)按照順序從0~n遍歷,比如第0個(gè)下標(biāo)的頂點(diǎn),在?? ??? Triangles中依次對(duì)每個(gè)三角形的索引進(jìn)行查找,只要有一個(gè)三角形的索引是自己的下標(biāo)那么他就是連接自身的三角形。
nearbyTri里三角形的順序是圍繞著該點(diǎn)旋轉(zhuǎn)為順序存儲(chǔ),要確定,后面要用到。
??? 如圖,每個(gè)三角形都有一條邊與其他三角形共邊,如下找到1這個(gè)三角形,找到這個(gè)三角形與其他三角形共用的頂點(diǎn)除了中間的點(diǎn)外,那么會(huì)找到2這個(gè)三角形,那么2就是鄰居三角形,然后2再找其他的以此類推。竟然三角形能確定那與自身相連的點(diǎn)順序也是沒有問題的。存儲(chǔ)順序順時(shí)針,判斷順時(shí)針方法:三角形1黃邊叉乘藍(lán)邊結(jié)果為正,三角形2黃邊叉乘黑邊結(jié)果負(fù),負(fù)在左邊,所以順時(shí)針就可計(jì)算。
2、是否為邊頂點(diǎn)
??? 每個(gè)三角形都有兩條邊與其他三角形共邊那么不是邊頂點(diǎn)。
???
只要有一個(gè)三角形只有一條邊與其他三角形共邊,那么這個(gè)頂點(diǎn)就是邊頂點(diǎn)。
減面算法
??? 本次算法通過減點(diǎn)實(shí)現(xiàn)減面,不加點(diǎn)或偏移點(diǎn)的計(jì)算。
??? 在上述步驟走完后這里進(jìn)行減面,如果不想對(duì)邊操作上面也已經(jīng)標(biāo)記了邊,直接跳過就行。
??? 步驟:?
?????? 1、遍歷頂點(diǎn),對(duì)頂點(diǎn)計(jì)算是否刪除
?????? 2、頂點(diǎn)刪除位置重建三角形
??? ??? 3、迭代遍歷
1、遍歷頂點(diǎn),對(duì)頂點(diǎn)計(jì)算是否刪除
?? 遍歷每一個(gè)頂點(diǎn),處理完一個(gè)頂點(diǎn)遍歷下一個(gè)頂點(diǎn)知道遍歷完一遍。
??? 遍歷找到第一個(gè)要處理的點(diǎn)如圖所示。
??? 減點(diǎn)需要兩個(gè)條件成立:
???
所有面交叉計(jì)算法線夾角角度是否小于設(shè)定值
?????? 計(jì)算出每個(gè)三角形切線方向也就是垂直該面的正向,比如1這個(gè)三角形,順時(shí)針任意找到天邊叉乘(如黃叉藍(lán))得到一個(gè)向量。
??? 將得到的每個(gè)向量與其他向量點(diǎn)乘求出夾角,找到最大的夾角比如下圖這個(gè)(面是可以任意組合,比如2和5,這里假設(shè)找到1和2是最大夾角),假設(shè)本輪迭代所設(shè)置的減面角度小于這個(gè)30,那么這個(gè)點(diǎn)不能減,否則該條件成立。
每個(gè)三角形連接該定點(diǎn)兩條邊的差的長度是否小于設(shè)定值
?????? 假設(shè)兩條邊的插值在設(shè)定范圍內(nèi),那么條件成立。否則如下圖黃和藍(lán)兩條邊差值有0.5米,而設(shè)定是0.4,那么不成立。因?yàn)椴逯堤笥绊懙姆秶容^大,減面后出問題幾率大。
2、頂點(diǎn)刪除位置重建三角形
點(diǎn)被刪除后與這個(gè)點(diǎn)相連的其他點(diǎn)連接起來會(huì)有下圖兩種情況發(fā)生,我們通用將第二種情況處理成多個(gè)凸邊形處理。
順時(shí)和逆時(shí)針遍歷線段,只要發(fā)現(xiàn)如圖1紅色圈的這種凹拐點(diǎn)就記錄為連接點(diǎn),兩邊都確定了一個(gè)點(diǎn)就將這兩個(gè)點(diǎn)連接分為兩個(gè)部分,一個(gè)部分是凸邊形,另一部分繼續(xù)處理,如圖2又找出了兩點(diǎn)又分出一個(gè)凸邊形,以此類推直到處理完畢。判斷凸凹用叉乘。
??? 凸邊形要構(gòu)建諾干個(gè)三角形,如下圖中間的點(diǎn)被刪了,這時(shí)候要構(gòu)造三角形,怎么構(gòu)造最合適呢?
??????
? ? 那么我們就要遍歷所有組合的三角形,如下圖(1-2-6、2-9-8、3-10-6等)這些組合,計(jì)算每個(gè)三角形3條邊比值最小的那個(gè),那它基本是最接近等邊三角形的。
?????? 這里找到2-9-8最像等邊三角形,那么就連接,對(duì)應(yīng)將黑色邊上的點(diǎn)所對(duì)應(yīng)的與自身頂點(diǎn)連接三角形添加到它們的隊(duì)列,2-9-8連接好后被分出了兩個(gè)地方需要連接,這個(gè)直接遞歸,然后規(guī)則跟上面一樣處理,直到處理完畢。
?????? 這個(gè)頂點(diǎn)弄完就到下一個(gè)點(diǎn)啦,就這樣遍歷直到點(diǎn)減到設(shè)定的值。
3、迭代遍歷
?? 當(dāng)遍歷了一遍頂點(diǎn)還沒減到設(shè)定的值,那么就要就要不斷迭代,每次迭代上述兩種條件越加越大,直到點(diǎn)減到設(shè)定的值或者迭代次數(shù)結(jié)束。
參考文獻(xiàn)
總結(jié)
以上是生活随笔為你收集整理的Mesh减面算法详解的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: centos7利用docker 快速搭建
- 下一篇: 子平格局——戊癸化火格