3D中的光线和正方形/矩形相交 [英] Ray and square/rectangle intersection in 3D

查看:191
本文介绍了3D中的光线和正方形/矩形相交的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

平。正在制作一款游戏,并且只在3D空间中寻找到正方形或长方形的射线交叉点。有搜索网络,发现了很多解决方案,但没有我能理解的在2D中有一个线条和线段交集脚本,但我无法弄清楚必须使它3D。
从它与正方形或矩形相交的哪一侧并不重要,但它必须能够回溯交点矢量的点,以便稍后可以测试距离它的距离,如果它出现在相同的交点之前或之后



任何使用python或其他类似脚本语言的例子都将不胜感激。 :不知道必须修改2D才能显示实例,但创建了新的并发布了两者。

  //这是测试射线到飞机上的实例,然后查看该点是否在矩形中,并保存它以测试以后的
列表面; //三角形面
列表Points; //

向量FindPoint(){
//调用交点到飞机上并返回
//如果它可以相交
//否则返回ZERO_VECTOR


整数四边形点(){
//如果点在飞机上的矩形中,则返回1
//否则返回0


default {

state_entry(){
integer n =(Faces!= []); //返回元素的数量
整数x = 0;
while(x vector intersection = FindPoint(FromList(Faces,x)); //取出一个元素并通过函数
运行它if(intersection!= ZERO_VECTOR){
整数测试=四边形点(FromList(Faces,x)); //找出点是否在矩形
if(test == 1){//如果是的话
Points + = intersection; //保存点
}
}
++ x;
}

先浮动; //与盒子交点的距离
integer l =(Points!= []);
整数d; (D <1){
if(Dist(FromList(Points,d))< first)//如果新的距离小于第一个
,则返回0; //然后结束脚本
++ d;
}
}

}


//这是2D版本
矢量lineIntersection(矢量一,矢量二,矢量三,矢量四){
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){//如果true测试线段
if((t <0.0)||(t> 1.0)){
return ZERO_VECTOR;
}
float u =(cx * by - cy * bx)/ b_dot_d_perp; ((u <0.0)||(u> 1.0)){
返回ZERO_VECTOR;
}
}

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

}

解决方案在R3中为一条线创建一个向量方程,然后求解该矩形平面中您正在测试的那条线的交点。之后,测试解决方案的点是否在范围内是非常简单的。



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

$ b (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插入向量方程将为您提供测试距离的点。




Hei. Are making a game and are looking for a ray intersection onto a square or a rectangle only in 3D space. Have search the web and found many solutions but nothing i can understand have a line and line segment intersection script in 2D but i cant figure out have to make it 3D. It is not important from what side it intersect the square or rectangle but it must be able to retrive the point of intersection vector so that later can be tested for distance to se if it occurred before or after other intersections on the same ray intersection.

Any examples in python or other similar scripting languages will be greatly appreciated

Edit: Dont know have to modify the 2D to show an exaple but made a new and posting both.

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

}

解决方案

Create a vector equation for a line in R3, then solve for the intersection of that line in the plane of the rectangle that you are testing it against. After that, it's simple enough to test if that point of solution lies within the bounds.

the parameter t of the solution can be found with:

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

where:

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

is the equation of the plane that your rectangle lies on

and:

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

is the vector equation of the line in question.

note that:

<rx, ry, rz>

is the initial point of the vector equation, and

<vx, vy, vz>

is the direction vector of the above equation

After that, plugging the parameter t into your vector equation will give you the point to test for distance.

这篇关于3D中的光线和正方形/矩形相交的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆