點三角測試技術

2021-09-23 15:21:21 字數 3091 閱讀 4214

判斷三維空間中的點是否在乙個三角形中,最簡單的方法就是進行向量叉積運算,怎麼,沒懂?那就接著往下看,假設空間中由這樣乙個三角形,黃色區域代表三角形內部,如何判斷空間中的任意一點是否在黃色區域中呢?

或許你還沒有想到比較簡單快速的方法,再來看看下面的這張圖,或許你會豁然開朗:

以上圖為例,取三角形外的一點p,向量p-a與向量b-a的叉積的方向指向螢幕外;取三角形內的一點p』,向量p』-a與向量b-a的叉積方向指向螢幕,由此我們得出直線ab上方的點的向量,與向量b-a的叉積指向螢幕外,而直線ab下方的點的向量,得到的叉積指向螢幕,這樣我們利用叉積就能確定平面上的點位於直線ab的哪一側。但是一般情況下,我們如何確定叉積應該指向那個方向呢,這時,我們發現點c還沒用到,如果點p』再三角形的內部,那麼p』與c應該位於直線ab的同側,也就是兩個點分別與向量b-a的叉積大方向是同乙個方向。同樣的方法,如果我們判斷出點p』與a位於直線bc的同一側,點p』與b位於直線ac的同一側,那麼就能保證點p』位於黃色區域內部,即位於三角形內部。**實現也很簡單:

function sameside(p1,p2,a,b)

cp1 = crossproduct(ba,p1-a)

cp2 = crossproduct(ba,p2-a)

if dotproduct(cp1,cp2)> = 0

return true

else return false

function pointin********( p,a,b,c)

if sameside(p,a,b,c)and sameside(p,b,a,c ) and sameside(p,c,a,b)

return true

else return false

對向量叉積知識不熟悉的同學,我在這裡補充一下:

兩向量a,b的叉積表示為axb,但要跟數學中的乘法區分開來!其表示式為:

兩向量叉積axb同時垂直a,b:

這種重心方法簡單有效,沒有其他多餘的運算。

上面的方法核心就是確保點需要位於線的同一側即可,它確實相當簡單了。但是這就足夠了嗎,下面的重心技術不僅簡單,而且執行速度更快!

我們都知道三角形的三個點在空間中定義了乙個平面,選擇其中任意乙個點,我們可以將平面上所有其他位置視為相對於該點。若選擇點a為起點,以向量(c-a)和向量(b-a)作為基礎向量,就可以表示平面上的任意一點,只需要從點a開始沿著(c-a)走一段距離,再沿著(b-a)走一段距離即可。

這樣,平面上的任意一點的位置就可以描述為:

p = a + u *(c  -  a)+ v *(b  -  a)
這裡需要注意的是,u和v應該大於0,當u <0或v <0時,表示我們走錯了方向,這個點位於三角形之外;如果u >1或v >1,表示我們沿著乙個方向走向了三角形之外;最後,如果u+v>1,我們再次越過了邊緣bc離開三角形。

給定u和v,我們就可以很輕鬆的用上面的方程計算出點p,但是如何能根據給定的點p計算出u和v呢,我們接著往下看:

p = a + u *(c  -  a)+ v *(b  -  a)//原方程

(p - a)= u *(c - a)+ v *(b - a)//兩者邊同時減去a

v2 = u * v0 + v * v1 //替換v0,v1,v2以減少寫入

//我們有兩個未知數(u和v)所以我們需要兩個方程來解它們。在方程兩邊同時點乘v0得到第乙個方程,然後在方程兩邊同時點乘v1得到第二個方程

(v2) . v0 = (u * v0 + v * v1) . v0

(v2) . v1 = (u * v0 + v * v1) . v1

//分配v0和v1

v2 . v0 = u * (v0 . v0) + v * (v1 . v0)

v2 . v1 = u * (v0 . v1) + v * (v1 . v1)

//現在我們有兩個方程和兩個未知數,可以解出乙個變數並替換為另乙個變數

求解 [v2.v0 == , ]

演算法表示為:

// compute vectors        

v0 = c - a

v1 = b - a

v2 = p - a

// compute dot products

dot00 = dot(v0, v0)

dot01 = dot(v0, v1)

dot02 = dot(v0, v2)

dot11 = dot(v1, v1)

dot12 = dot(v1, v2)

// compute barycentric coordinates

invdenom = 1 / (dot00 * dot11 - dot01 * dot01)

u = (dot11 * dot02 - dot01 * dot12) * invdenom

v = (dot00 * dot12 - dot01 * dot02) * invdenom

// check if point is in ********

return (u >= 0) && (v >= 0) && (u + v < 1)

point in ******** test

向量點積(dot product),向量叉積(cross product)

上三角矩陣下三角矩陣

要求給定矩陣,輸出其上三角矩陣或下三角矩陣 源 如下 include include include include const int m 5 void proc int array m m void main printf n proc a printf result array is n fo...

python楊輝三角 楊輝三角I II

給定乙個非負整數 numrows,生成楊輝三角的前 numrows 行。在楊輝三角中,每個數是它左上方和右上方的數的和。示例 輸入 5 輸出 1 1,1 1,2,1 1,3,3,1 1,4,6,4,1 可以一行一行錯位加,當然這裡提供更簡便的方法。任取一行描述 1,2,1 如何得到 1,3,3,1 ...

sicp練習1 12 帕斯卡三角(楊輝三角)

楊輝三角以前在學習c語言時候,用迴圈很容易實現。由於剛剛接觸函式式語言,遞迴和迭代方式實現迴圈還沒深入我心。下意思的想用鍊錶來實現,但發現自己對scheme的鍊錶操作太不熟悉,總會出現這樣那樣子的無法自我解釋的問題。最後參考了 dennis zane 的pascal實現,dennis zane 是把...