Unity Mesh實現圖片切割(二)- 頂點計算
Unity Mesh實現圖片切割 github博客鏈接
在開始計算座標點之前線建議聲明Line
類,提供一些複用函數,爲計算提方便。
一、 計算畫的線和圖形線的交點
求交點座標直觀的數學方法,就是求出兩直線的方程,兩方程求解。
1. 求直線方程
直線方程爲y = k * x + b
,通過線段的兩個點startPos
和endPos
可求出k
和b
。
可得到公式:
k = (endPos.y - startPos.y) / (endPos.x - startPos.x); // 注意被除數爲0的情況特殊處理
b = startPos.y - k * startPos.x;
2. 求兩直線交點
y = k1 * x + b1 -> 1
y = k2 * x + b2 -> 2
1方程乘k2,2方程乘k1,再相減可消元得到方程:
y = (k2 * b1 - k1 * b2) / (k2 - k1);
x = (y - b1) / k1;
但是需要注意的是:
- 直線垂直於X軸的特殊處理,因爲垂直於X軸的直線斜率k趨近於∞,沒有截距b。
- 兩直線平行是沒有交點的,平行的依據是:1.斜率k相同;2.或者兩條直線都是垂直於X軸
通過畫的線和圖形的各個線段進行求交點,會的出有限個數的交點集
二、 將頂點和交點按照畫的線分區域(在線上、線上方、線下方)得到兩個新的點集
1. 合併、去重
上一步得到的交點集爲intersectionPointsList
,圖形頂點做標集爲vertices
,將兩個數組合併爲allPoints
。
合併後要將allPoints中點去重,此操作是爲了處理交點爲頂點,座標值相同被視爲連個點。或者爲了切割需求,將臨近點視爲同一點座標值。
2. 分區域
拿到畫的線的方程,將allPoints
中點分別跟直線對比,分爲在線上、線上方、線下方。如下圖:
0,1,2,3是圖形的頂點vertices,4,5是畫的直線和圖像邊的交點,合併的allPoints
的集合就是這6個點。畫的直線把一個圖像分成了兩部分,上半部分part1
是4,3,2,5頂點組成的四邊形,下半部分part2
是1,0,4,5組成的四邊形。其中交點是連個圖形公用的點,由此可分出連個新四邊形的頂點,爲畫mesh作準備。
計算點與直線的關係方法:將6個點的x值帶入直線方程,得出targetY
,targetY
和point.y
比較:
point.y == targetY -> 點在線上(onList)
point.y < targetY -> 點在線下方 (downList)
point.y > targetY -> 點在線上方 (upList)
將點分爲三類,上半部分的圖形的頂點集合:part1Vertices = upList + onList
,下半部分的圖形的頂點集合:part2Vertices = downList + onList
,得到兩圖形的所有頂點。
三、 分離出的點順時針排序,爲創建mesh作準備
由於mesh的興致,需要頂點順時針排序,才能在正面顯示,所以需要將part1Vertices
和part2Vertices
按照順時針排序,排序方法:
- 先找到最左邊的點,即:x最小,x相同找y最小的點
- 其餘點分別跟步驟1找到的點求正切值,按正切值從大到小排序。
爲什麼要用正切值排序?
找到最左邊的點,其餘點與這個點的夾角範圍是[-pi/2, pi/2],在tan的三角函數中此範圍內是單調遞增的,由此可判斷各店的關係。
下一遍博客將講解創建mesh並修改uv進行貼圖:
Unity Mesh實現圖片切割(三)- mesh繪製
全文鏈接: Unity Mesh實現圖片切割 - 概述