2012-01-10 105 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