直線或線段與mesh網格相交的計算

2021-09-11 23:25:25 字數 1616 閱讀 7923

第一步:判斷直線是否與三角形平面平行或在三角形平面內,這一步只需做直線方向向量與三角形法向量的點積即可,不詳細敘述。

第二步:把三角形投影到二維平面上,我們可以想象一下把空間中的三角形投影到以已知直線作為法線的平面上,那麼直線在平面內的投影就只是乙個點,而三角形在該平面上還是乙個三角形,要判斷直線是否與三角形有交點只需判斷投影點與投影三角形之間的關係即可。為了方便起見,在這一步我直接把整個mesh旋轉到以所求直線為z軸的座標上,那麼只需求解三角形在xoy平面上的投影與原點之間的關係即可。

第三步:判斷平面上點與三角形位置關係,這裡我參考了

用到向量的叉乘。假設三角形的三個點按照順時針(或者逆時針)順序是a,b,c。對於某一點p,求出三個向量pa,pb,pc, 然後計算以下三個叉乘(^表示叉乘符號):

t1 = pa^pb,

t2 = pb^pc,

t3 = pc^pa,

如果t1,t2,t3同號(同正或同負),那麼p在三角形內部,否則在外部。

plucker座標用來表示由a =(px,py,pz)和b =(qx,qy,qz)組成的直線

l =(l [0],l [1],l [2],l [3],l [4],l [5])

l0 = a[0] * b[1] - b[0] * a[1]

l1 = a[0] * b[2] - b[0] * a[2]

l2 = a[0] - b[0]

l3 = a[1] * b[2] - b[1] * a[2]

l4 = a[2] - b[2]

l5 = b[1] - a[1]

side operator是乙個對plucker座標和的運算:(a,b都是plucker座標)

side(a,b) = a[0]*b[4] + a[1]*b[5] + a[2]*b[3] + a[3]*b[2] + a[4]*b[0] + a[5]*b[1]

令:s1 = side-operator(l,e1),s2 = side-operator(l,e2),s3 = side-operator(l,e3)

直線和三角形不共面且直線穿過三角形:s1, s2, s3 <0 或 s1, s2, s3 >0

直線和三角形不共面且沒有角度的:s1, s2, s2符號不相同

直線和三角形不共面且直線穿過乙個頂點:s1, s2, s2 中兩個為0

直線和三角形不共面且直線穿過一條邊:s1, s2, s2 中乙個為0且另外兩個符號相同

其他的直線和三角形共面的情況具體參見以上的參考**

POJ 3304 直線與線段相交)

題目 poj3304 給定n條線段,找出一條直線,能與所有的線段有乙個交點 可以在端點處相交 思路 如果存在這麼一條直線,必定過平面中的兩個點,所以任意窮舉兩個點所在的直線與所有線段判斷是否相交。sample input 3 21.0 2.0 3.0 4.0 4.0 5.0 6.0 7.0 30.0...

poj 3304 判斷直線與線段相交

傳送門 題意 給你一些線段,然後問你是否存在一條直線,把這些線段投影到直線上,所投影與原線段至少有1個公共點。思路 由題意可得原線段與直線符合條件的直線至少有1個公共點,所以就轉化成是否有直線與所有線段相交的問題了。列舉任意兩個不同端點作為直線上兩點確定一直線判斷是否與所有直線相交即可。吐槽 距離小...

poj3304 計算幾何 線段與直線相交

題意 給定n條線段,確定是否存在一條直線,使得這n條線段在這條直線上的射影具有公共點 可將問題轉化為是否存在一條直線經過所有的線段,證明見依然的部落格 include include include using namespace std const double eps 1e 8 const in...