2011-02-08 38 views
5

我有兩個空間點,L1和L2定義了一條線上的兩個點。基於點的線/平面相交

我有三個空間點,P1,P2和P3,三點在飛機上。

因此,給定這些輸入,線在哪一點與飛機相交?

Fx。平面方程A * x + B * y + C * z + D = 0是:

A = p1.Y * (p2.Z - p3.Z) + p2.Y * (p3.Z - p1.Z) + p3.Y * (p1.Z - p2.Z) 
B = p1.Z * (p2.X - p3.X) + p2.Z * (p3.X - p1.X) + p3.Z * (p1.X - p2.X) 
C = p1.X * (p2.Y - p3.Y) + p2.X * (p3.Y - p1.Y) + p3.X * (p1.Y - p2.Y) 
D = -(p1.X * (p2.Y * p3.Z - p3.Y * p2.Z) + p2.X * (p3.Y * p1.Z - p1.Y * p3.Z) + p3.X * (p1.Y * p2.Z - p2.Y * p1.Z)) 

但其餘的呢?

回答

8

解決這個最簡單的(和非常普及)的方式是說,

L1 + x*(L2 - L1) = (P1 + y*(P2 - P1)) + (P1 + z*(P3 - P1)) 

,讓你在3個變量3個方程。求解x,y和z,然後將其替換回原始方程中以獲得答案。這可以推廣到做複雜的事情,比如找到四維中兩個平面的交點。

對於另一種方法,(P2-P1)(P3-P1)的叉積N是一個與平面成直角的向量。這意味着該平面可以定義爲點集P,使得點積爲PNP1N的點積。求解x,這樣(L1 + x*(L2 - L1)) dot N是這個常數給你一個方程在一個易於解決的變量。如果你要與這架飛機相交很多線路,這種方法絕對是值得的。

寫出明確這給:

N = cross(P2-P1, P3 - P1) 
Answer = L1 + (dot(N, P1 - L1)/dot(N, L2 - L1)) * (L2 - L1) 

其中

cross([x, y, z], [u, v, w]) = x*u + y*w + z*u - x*w - y*u - z*v 
dot([x, y, z], [u, v, w]) = x*u + y*v + z*w 

注意,跨產品的把戲作品在3個維度,只爲你一個平面的特定問題和線。

+0

網絡已經爲此散佈了方程,但並不是您找到x,y,z所需的實際「最終」方程。我需要的是獲得結果的x,y,z的簡單公式的最終實際集合。這個答案仍然需要一個「解決」方程,所以它只是答案的一小部分。我要求回答如下: x = [基於P1.X,P1.Y,P1.Z,P2.X ...等的公式] 以及y和z的相似。 – 2011-02-09 00:59:12

+0

@Morten Nielsen:其原因是「最終方程」是可怕的,不可能理解,並且保證被錯誤地輸入到你的程序中。特別是因爲我不知道你是如何代表你的觀點的。但是我會編輯我的節點,使交叉產品公式更加明確。 – btilly 2011-02-09 02:55:09

1

這就是我在代碼中完成它的過程。幸運的是,一個代碼庫(XNA)只有我需要的一半,剩下的很簡單。

var lv = L2-L1; 
var ray = new Microsoft.Xna.Framework.Ray(L1,lv); 
var plane = new Microsoft.Xna.Framework.Plane(P1, P2, P3); 

var t = ray.Intersects(plane); //Distance along line from L1 
///Result: 
var x = L1.X + t * lv.X; 
var y = L1.Y + t * lv.Y; 
var z = L1.Z + t * lv.Z; 

當然,我寧願只是簡單的公式發生在XNA的封面下。