2012-01-10 99 views
3

黑。正在製作一款遊戲,並且只在三維空間中尋找到正方形或矩形的射線交叉點。有搜索網絡,發現了很多解決方案,但沒有我能理解的在2D中有一個線條和線段交集腳本,但我無法弄清楚必須使它3D。 它與正方形或矩形相交的哪一側並不重要,但它必須能夠檢測交點矢量的點,以便稍後可以測試距離,如果它發生在相同射線交點上的其他交點之前或之後。3D中的光線和正方形/矩形交點

在Python或其他類似的腳本語言的所有示例將不勝感激

編輯:不知道有修改2D顯示的的exaple但提出了新的發佈都。

//this is the exaple it test a ray onto a plane then look to se if that point is in the rectangle and saves it to test for distanse later 
list Faces; //triangle faces 
list Points; // 

vector FindPoint(){ 
    //calcute the point of intersection onto the plane and returns it 
    //if it can intersect 
    //else return ZERO_VECTOR 
} 

integer point-in-quadrilateral(){ 
    //return 1 if the point is in the rectangular on the plane 
    //else return 0 
} 

default{ 

    state_entry(){ 
     integer n = (Faces != []); //return number of elements 
     integer x = 0; 
     while(x < n){ 
      vector intersection = FindPoint(FromList(Faces, x)); //take  out a element and runs it trough the function 
      if(intersection != ZERO_VECTOR){ 
       integer test = point-in-quadrilateral(FromList(Faces,  x)); //find out if the point is in rectangular 
       if(test == 1){ //if so 
        Points += intersection; //save the point 
       } 
      } 
      ++x; 
     } 

     float first; //the distanse to the box intersection 
     integer l = (Points != []); 
     integer d; 
     while(d < l){ 
      if(Dist(FromList(Points, d)) < first) //if the new distanse  is less then first 
       return 0; //then end script 
      ++d; 
     } 
    } 

} 


//this is the 2D version 
vector lineIntersection(vector one, vector two, vector three, vector four){ 
float bx = two.x - one.x; 
float by = two.y - one.y; 
float dx = four.x - three.x; 
float dy = four.y - three.y; 
float b_dot_d_perp = bx*dy - by*dx; 
if(b_dot_d_perp == 0.0) { 
    return ZERO_VECTOR; 
} 
float cx = three.x-one.x; 
float cy = three.y-one.y; 
float t = (cx*dy - cy*dx)/b_dot_d_perp; 
if(LineSeg){ //if true tests for line segment 
    if((t < 0.0) || (t > 1.0)){ 
     return ZERO_VECTOR; 
    } 
    float u = (cx * by - cy * bx)/b_dot_d_perp; 
    if((u < 0.0) || (u > 1.0)) { 
     return ZERO_VECTOR; 
    } 
} 

return <one.x+t*bx, one.y+t*by, 0.0>; 

}

回答

3

在R3中爲一條線創建一個向量方程,然後求解該矩形平面中您正在對其進行測試的那條線的交點。在那之後,它足夠簡單地測試解決方案的這一點是否在範圍之內。

t = (a * (x0 - rx) + b * (y0 - ry) + c * (x0 - rz))/(a * vx + b * vy + c * vz) 

其中:

a(x - x0) + b(y - y0) + c(z - z0) = 0 

是您的矩形位於

和平面方程:

解決方案的參數t可以找到

<x, y, z> = <rx + vx * t, ry + vy * t, rz + vz * t> 

是有問題的線的矢量方程。

注意的是:

<rx, ry, rz> 

是矢量方程式的初始點,並

<vx, vy, vz> 

是上述等式

之後的方向矢量,堵塞參數t進入你的矢量方程將給你點測試距離。

enter image description here

+0

感謝您的回覆。你能解釋一下它的一部分嗎? 「x0 y0 z0」是否等於x,y和z使得第二個方程等於零?如果有的話如何計算每個人的價值? – TeaWave 2012-01-11 18:02:36

+0

本質上,是的。x0,y0和z0是與您的矩形位於同一平面上的SOME點(可以是任意點)的值。至於該方程中的x,y和z,可以插入上面列出的線方程(r_ + v_ * t)的值。你能更具體地說明你打算編寫代碼的方式嗎?也許你說你能解決的二維版本的例子?我可能能夠更好地解釋這種方式。 – 2012-01-13 02:27:10

+0

編輯了一個實例和2D版本的主要帖子。如果a,b和c是飛機的單位矢量,是否已經做了更多的創建和纏繞?並且是x0,y0和z0的線性方程?已經運行了多種組合,但可以將其設置爲等於零。 – TeaWave 2012-01-14 12:58:21

1

你不說在3D正方形/長方形是否與座標軸或不對齊。 假設三維矩形R在空間任意取向,這裏是一種方法。 首先將您的光線r與包含R的平面相區分。這可以通過要求一個 比例因子小號乘以- [R並將其放置在- [R的平面中,並求解小號來完成。這給你一個點在飛機上的點p。現在投影平面,[Rp,到協調 平面之一{XYYZZX}。你只需要避免垂直投射到飛機的法向矢量,這總是可能的。然後解決投影平面中的四邊形問題。

在開始之前,檢查您的線段是否位於R的3D平面中,如果是,請分開處理。

+0

感謝您的回覆。正方形和矩形可以以任何方式旋轉成3D。所以,如果我正確地理解了你所寫的部分'首先將你的光線r與包含R的平面相區分。這可以通過要求比例因子s乘以r並將其放在R的平面上來解決,並且s'是由Joel Carnett給出的解決方案,然後我使用從中給出的交點矢量,並用四邊形中的點求解以找出它是否在邊界內。 – TeaWave 2012-01-11 17:42:07

+0

是的,你理解它。我顯然在太高的水平上回答,但喬爾基本上用散文描述了我所描述的方程式。 – 2012-01-13 02:13:53

6

的解決方案是很容易在定義與點(=載體)的光線和方向矢量,並且矩形與點(=矢量)和代表側上的兩個矢量。

假設射線定義爲R0 + t * D,其中R0是光線的原點,D是表示其方向和t一個單位矢量是它的長度。

矩形可以用一個角點P0和兩個表示方向(S1S2)來表示,它們應該表示邊(它們的長度等於邊的長度)。你將需要另一矢量N垂直於它的表面,其等於沿着S1S2叉積的單位向量。

現在,假設該射線相交的矩形的P。然後,光線的方向D必須與正常的N形成非零角度。這可以通過檢查D.N < 0來驗證。

要查找的交點,假設P = R0 + a * D(點必須在射線)。您需要立即查找a的值。查找矢量P0P。這必須垂直於N,這意味着P0P.N = 0減少到a = ((P0 - R0).N)/(D.N)

現在你需要檢查,如果該點位於矩形內與否。要做到這一點,採取P0P投影Q1沿S1和沿S2P0PQ2。點內的條件是0 <= length(Q1) <= length(S1)0 <= length(Q2) <= length(S2)

此方法適用於任何類型的平行四邊形的,不僅爲矩形。

+0

感謝您的好帖子。你的文章幫助三角化問題並解決問題 – TeaWave 2012-01-15 21:56:06

+0

這很棒。謝謝! – Mikaelblomkvistsson 2016-10-07 22:47:18