雷方交叉口

时间:2014-06-06 12:44:35

标签: java geometry 2d raycasting

在2D中,我有一个起点(x_1,y_1),一个终点(x_2,y_2),以及三个代表三个正方形顶点的点(左上,右上和右下顶点)。 / p>

我的目标是,如果源自(x_1,y_1)并经过(x_2,y_2)的光线与三个顶点给出的平面(或方形)相交,则返回true。最后,我想将其扩展为3D - 与立方体的交叉 - 这就是我目前使用3D矢量的原因。

在回顾了许多其他SO问题后,我在Java中提出了以下代码:

// Determines if a given ray intersects a given square
// R1, R2 are two points on the ray
// S1 (upper left vertex), S2 (upper right vertex), and S3 (lower left vertex)
public static boolean intersectRayWithSquare(Vector3 R1, Vector3 R2, Vector3 S1, Vector3 S2, Vector3 S3) {

    Vector3 dS21 = S2.sub(S1); // Subtract S1 from S2
    Vector3 dS31 = S3.sub(S1);
    Vector3 n = dS21.cross(dS31); // Take the cross product of two vectors
    Vector3 dR = R1.sub(R2);

    double ndotdR = n.dot(dR);

    if (Math.abs(ndotdR) < 1e-25f) {
        return false;
    }

    double t = -n.dot(R1.sub(S1)) / ndotdR;

    Vector3 M = R1.add(dR.scale(t));
    Vector3 dMS1 = M.sub(S1);

    double u = dMS1.dot(dS21);
    double v = dMS1.dot(dS31);

    return (u >= 0.0 && u <= dS21.dot(dS21)
    && v >= 0.0 && v <= dS31.dot(dS31));
}

这非常适合查找通过R1和R2的LINE是否与正方形相交。但是,请考虑以下情况:

UPDATED: More accurate picture to better demonstrate the problem

Direct link to imgur as I don't have enough rep to post images D:

如果我们两次调用此函数,每个方块一次,它们都将返回true。我需要调用(R1,R2,S1)才能返回true,但调用(R1,R2,S2)返回false。

PS:这是我的第一篇文章(但是时间很长),所以如果需要任何其他信息,或者您有任何意见可以帮助我改进我的问题,请告诉我。

2 个答案:

答案 0 :(得分:0)

基本上你的光线有一个起点,一个方向但没有终点。

您需要做的就是检查方块中的任何一点是否满足行的公式,检查方向是否正确。

即。只是简单地看x维度:

if (x1<x2) {
  points_in_square.x must be >= x1
} else if (x1>x2) {
  points_in_square.x must be <= x1 
} else {
  // line is vertical, handle this case
}

您可以查看类似事物的现有实现。例如,jMonkeyEngine是一个开源Java 3d引擎,它包含带有轴对齐边界框的光线的交叉点 - 这基本上就是您正在寻找的。我没有方便的链接,但尝试使用我刚给出的关键字进行搜索。

答案 1 :(得分:0)

因此,可以通过添加布尔语句的附加要求来解决此问题。

return (u >= 0.0 && u <= dS21.dot(dS21) && v >= 0.0 && v <= dS31.dot(dS31) && t < 0);
// t < 0 to eliminate squares behind the ray