【问题标题】:Ray and square/rectangle intersection in 3D3D 中的射线和正方形/矩形相交
【发布时间】:2012-01-10 23:26:08
【问题描述】:

嘿嘿。正在制作游戏,并且正在寻找仅在 3D 空间中与正方形或矩形相交的光线。在网上搜索并找到了许多解决方案,但我无法理解在 2D 中具有线段和线段相交脚本,但我无法弄清楚必须将其设为 3D。 它从哪一侧与正方形或矩形相交并不重要,但它必须能够检索交点矢量,以便稍后可以测试它是否发生在同一光线交点上的其他交点之前或之后的距离。

非常感谢任何 Python 或其他类似脚本语言的示例

编辑:不知道必须修改 2D 以显示示例,但制作了新的并发布了两者。

//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>; 

}

【问题讨论】:

    标签: python graphics geometry intersection


    【解决方案1】:

    当你用一个点(=向量)和一个方向向量定义一条射线,用一个点(=向量)和两个向量表示边的矩形时,解决方案非常简单。

    假设射线定义为R0 + t * D,其中R0是射线的原点,D是表示其方向的单位向量,t是其长度。

    矩形可以用一个角点P0 和两个向量S1S2 来表示,它们应该表示边(它们的长度等于边的长度)。您将需要另一个垂直于其表面的向量N,它等于沿S1S2 叉积的单位向量。

    现在,假设射线在P 与矩形相交。然后,射线的方向D 必须与法线N 形成一个非零角度。这可以通过检查D.N &lt; 0来验证。

    要找到交点,假设P = R0 + a * D(该点必须在射线上)。您现在需要找到a 的值。找到向量P0P。这必须垂直于N,这意味着P0P.N = 0 减少为a = ((P0 - R0).N) / (D.N)

    现在您需要检查该点是否在矩形内。为此,请沿S1P0PP0P 沿S2 进行投影Q1P0P。点在里面的条件是0 &lt;= length(Q1) &lt;= length(S1)0 &lt;= length(Q2) &lt;= length(S2)

    此方法适用于任何类型的平行四边形,不仅适用于矩形。

    【讨论】:

    • 感谢您的好帖子。您的帖子帮助对问题进行了三角测量并解决了问题
    • 太棒了。谢谢!
    • 从我的五分钟绘图中,使用投影的结束条件 Q1Q2 不适用于所有平行四边形中的所有点。我错过了什么?
    • 提到的绘图,有一个额外的P0而不是Pimgur.com/a/Dt6ZvIV
    【解决方案2】:

    为 R3 中的一条线创建一个矢量方程,然后求解该线在您测试它的矩形平面中的交点。之后,就可以很简单地测试该解点是否在边界内。

    解决方案的参数 t 可以通过以下方式找到:

    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
    

    是你的矩形所在平面的方程

    和:

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

    是相关直线的矢量方程。

    注意:

    <rx, ry, rz>
    

    是向量方程的初始点,并且

    <vx, vy, vz>
    

    是上式的方向向量

    之后,将参数 t 插入向量方程将为您提供测试距离的点。

    【讨论】:

    • 感谢您的回复。你能解释它的一部分吗? “x0 y0 z0”是否是等于 x、y 和 z 的均衡器,以使第二个方程等于零?如果是这样,如何计算他们每个人的价值?
    • 基本上,是的。 x0、y0 和 z0 是与矩形位于同一平面上的某个点(可以是任何点)的值。至于该方程中的 x、y 和 z,您将插入上面列出的线方程 (r_ + v_ * t) 的值。您能否更具体地说明您计划如何编写代码?也许你说你能够锻炼的二维版本的例子?那样我也许能更好地解释。
    • 已经编辑了示例和 2D 版本的主要帖子。如果a,b和c是平面的单位向量,是否已经做了更多的发现并且正在缠绕? x0、y0 和 z0 是直线方程吗?已经运行了多个组合,但可以使其等于零。
    • 我编辑了帖子以包含一张图片以供澄清。无论如何,我给出的第二个等式并不重要。您真正想要的是将值插入第一个等式以获得参数“t”。之后,您将“t”插入直线的矢量方程(您正在追踪的光线——顺便说一句,这是第三个方程)。
    • 感谢您一直以来的帮助。现在想通了吗:)
    【解决方案3】:

    您没有说 3D 中的正方形/矩形是否与坐标轴对齐。 假设 3D 矩形 R 在空间中是任意方向的,这里有一种方法。 首先将你的射线 r 与包含 R 的平面相交。这可以通过要求一个 比例因子 s 乘以 r 并将其放置在 R 的平面上,并求解 s。这会在平面上为您提供一个点 p。现在将平面和 Rp 投影到坐标之一 平面 {xyyzzx}。您只需要避免垂直于平面的法线向量投影,这始终是可能的。进而求解投影平面内的四边形点问题。

    开始之前,检查你的线段是否在R的3D平面上,如果是,单独处理。

    【讨论】:

    • 感谢您的回复。正方形和矩形可以在 3D 中以任何方式旋转。所以如果我理解正确,你写的部分'首先将你的光线 r 与包含 R 的平面相交。这可以通过要求比例因子 s 来将 r 相乘并将其放在 R 的平面上,然后求解 s' 是Joel Carnett 给出的解决方案,然后我使用从中给出的交点向量并用四边形中的点求解它,以确定它是否在边界内。
    • 是的,你明白了。我显然回答得太高了,但乔尔基本上是在用方程式表达我在散文中描述的内容。
    猜你喜欢
    • 2015-08-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-12-31
    • 1970-01-01
    • 2012-02-26
    相关资源
    最近更新 更多