[英]3D Line Segment and Plane Intersection
我正在嘗試實現一個線段和平面相交測試,它將返回true或false,具體取決於它是否與平面相交。 它還將返回線相交的平面上的接觸點,如果線不相交,則如果線段已經是光線,則該函數仍應返回交點。 我使用了Christer Ericson的實時碰撞檢測中的信息和代碼,但我認為我沒有正確實現它。
使用的平面是從三角形的法線和頂點導出的。 找到平面上交點的位置是我想要的,無論它是否位於我用來導出平面的三角形上。
該功能的參數如下:
contact = the contact point on the plane, this is what i want calculated
ray = B - A, simply the line from A to B
rayOrigin = A, the origin of the line segement
normal = normal of the plane (normal of a triangle)
coord = a point on the plane (vertice of a triangle)
這是我使用的代碼:
bool linePlaneIntersection(Vector& contact, Vector ray, Vector rayOrigin, Vector normal, Vector coord) {
// calculate plane
float d = Dot(normal, coord);
if (Dot(normal, ray)) {
return false; // avoid divide by zero
}
// Compute the t value for the directed line ray intersecting the plane
float t = (d - Dot(normal, rayOrigin)) / Dot(normal, ray);
// scale the ray by t
Vector newRay = ray * t;
// calc contact point
contact = rayOrigin + newRay;
if (t >= 0.0f && t <= 1.0f) {
return true; // line intersects plane
}
return false; // line does not
}
在我的測試中,它永遠不會真實......任何想法?
我正在回答這個問題,因為當它被要求提供射線交集的c ++示例時,它首先出現在Google上:)
代碼總是返回false,因為您輸入if here:
if (Dot(normal, ray)) {
return false; // avoid divide by zero
}
如果向量是垂直的,則點積僅為零,這是您要避免的情況(沒有交點),並且非零數字在C中為真。
因此解決方案是否定(!)或做Dot(...)== 0。
在所有其他情況下,將有一個交叉點。
在交點計算上:平面的所有點X都遵循等式
點(N,X)= d
其中N是法線, d可以通過將平面的已知點放在等式中找到。
float d = Dot(normal, coord);
在光線上,線的所有點s可以表示為點p和給出方向D的矢量:
s = p + x * D.
因此,如果我們搜索飛機中的xs ,我們就有了
點(N,s)= d
點(N,p + x * D)= d
點積ab是轉置(a)* b 。
設置轉置(N)為Nt 。
Nt *(p + x * D)= d
Nt * p + Nt * D * x = d (x標量)
x =(d - Nt * p)/(Nt * D)
x =(d - 點(N,p))/點(N,D)
這給了我們:
float x = (d - Dot(normal, rayOrigin)) / Dot(normal, ray);
我們現在可以通過將x放在線方程中來獲得交點
s = p + x * D.
Vector intersection = rayOrigin + x*ray;
bool linePlaneIntersection(Vector& contact, Vector ray, Vector rayOrigin, Vector normal, Vector coord) { // get d value float d = Dot(normal, coord);
if (Dot(normal, ray) == 0) { return false; // No intersection, the line is parallel to the plane }
// Compute the X value for the directed line ray intersecting the plane float x = (d - Dot(normal, rayOrigin)) / Dot(normal, ray);
// output contact point *contact = rayOrigin + normalize(ray)*x; //Make sure your ray vector is normalized return true; }
我可能錯了,但代碼中有一些看似非常可疑的地方。 首先,請考慮以下這一行:
// calculate plane
float d = Dot(normal, coord);
這里,您的值d
對應於平面法線(矢量)和空間點(平面上的點)之間的點積。 這似乎是錯的。 特別是,如果您有任何平面穿過原點並使用原點作為坐標點,您將最終計算
d = Dot(normal, (0, 0, 0)) = 0
並立即返回false。 我不確定你打算在這里做什么,但我很確定這不是你的意思。
代碼中另一個似乎可疑的地方是這一行:
// Compute the t value for the directed line ray intersecting the plane
float t = (d - Dot(normal, rayOrigin)) / Dot(normal, ray);
請注意,您正在計算平面法線向量(矢量)和光線原點(空間中的點)之間的點積。 這看起來很奇怪,因為它意味着根據光線在空間中的起源,您用於光線的縮放因子會發生變化。 我建議再看一下這段代碼,看看這是不是你的意思。
希望這可以幫助!
這對我來說都很好看。 我已經獨立檢查了代數,這對我來說很好。
作為示例測試用例:
A = (0,0,1)
B = (0,0,-1)
coord = (0,0,0)
normal = (0,0,1)
這給出了:
d = Dot( (0,0,1), (0,0,0)) = 0
Dot( (0,0,1), (0,0,-2)) = -2 // so trap for the line being in the plane passes.
t = (0 - Dot( (0,0,1), (0,0,1) ) / Dot( (0,0,1), (0,0,-2)) = ( 0 - 1) / -2 = 1/2
contact = (0,0,1) + 1/2 (0,0,-2) = (0,0,0) // as expected.
因此,考慮到@ templatetypedef的答案之后的校正,我可以看到問題的唯一區域是其他操作之一的實現,無論是Dot()
還是Vector
運算符。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.