如何检查棱镜之间是否有一条线

How to check if a line lies between a prism

如果我在 3d 中有 2 个点 space 我如何确定直角棱镜是否位于这 2 个点之间?另外,关于直角棱镜,我所掌握的唯一信息是它的最小和最大 x、y 和 z 值。我知道我可以沿着这 2 个点之间的线进行迭代,检查该点是否在直角棱镜内,但这似乎非常耗费资源。我真正需要的是一种检查线段是否与棱镜相交的方法,但我不确定该怎么做,有什么想法吗?

我发现这两个资源与我的问题相似 https://math.stackexchange.com/questions/2134505/how-to-check-if-an-infinite-line-intersects-a-rectangular-prism-in-3d-space

How to check if an infinite line intersects a rectangular prism in 3d space?

看那个底部 link 它只是简单地说要找到与直角棱镜相交的参数 t 这很明显,但问题是我不知道该怎么做,有什么想法吗?

将您的线点和棱镜边缘投影到垂直于您的线的二维平面上。 在二维平面上,直线的两点只是一个点,棱柱的边只是一串相连的顶点,形成一个封闭区域。检查一个点是否在封闭区域内,这对于 2D 很容易做到。

如果你的点在 3D 中,那么直线与棱镜相交,如果不在,则不相交。

现在有一种情况是两端不接触棱镜的线段。在这种情况下,您只需检查点到棱镜表面的距离,有一个方程式。

设线段由(X1, Y1)(X2, Y2)两点定义。 让框由范围 xmin..xmaxymin..ymaxzmin..zmax.

定义

我们可以为线段写参数方程,其中t在范围0..1:

X = X1 + t * (X2 - X1)
Y = Y1 + t * (Y2 - Y1)
Z = Z1 + t * (Z2 - Z1)

盒子有 6 个面。让第一个在 xmin。我们可以在第一个等式中替换 xmin 并找到参数 t,其中线与该面相交。

xmin = X1 + t1 * (X2 - X1)
t1 = (xmin - X1) / (X2 - X1)

现在检查 t1 是否在 0..1 范围内。如果是,将此 t1 值代入第二个和第三个等式

Y = Y1 + t1 * (Y2 - Y1)
Z = Z1 + t1 * (Z2 - Z1)

并检查结果 Y 和 Z 是否分别位于 ymin..ymaxzmin..zmax 范围内。
如果是 - 线段确实与框相交

如果没有,对其他面重复xmaxymin等。

P.S。您还可以考虑线段完全在框内的特殊情况(只需检查 X1、Y1、Z1 是否在框范围内)

P.P.S。当线平行于某个坐标平面时,不检查与相应面的交点(例如,如果 X2-X1==0,你不能除以零,但你不需要检查 xminxmax 脸)

Quick-made Python-like伪代码供参考:

def DoesSegmentIntersectBox(x1,y1,z1,x2,y2,z2,xmin,xmax,yin,ymax,zmin,zmax):
    if zmin<=z1<=zmax and ymin<=y1<=ymax and xmin<=x1<=xmax:
        return True  #end inside the box

    if (x2-x1):
        t = (xmin-x1) / (x2-x1)
        if 0<=t<=1:    #line intersects plane in segment range
            y = y1+t*(y2-y1)
            if ymin<=y<=ymax:    #segment intersects face in y range
                z = z1+t*(z2-z1)
                if zmin<=z<=zmax:   #segment intersects face in z range
                    return True     #segment does intersect face xmin
        t = (xmax-x1) / (x2-x1)
            #same 6 lines

    if (y2-y1):
        t = (ymin-y1) / (y2-y1)
        if 0<=t<=1:
            x = x1+t*(x2-x1)
            if xmin<=x<=xmax:
                z = z1+t*(z2-z1)
                if zmin<=z<=zmax:
                    return True
        t = (ymax-y1) / (y2-y1)
            #same 6 lines

    if (z2-z1):
        t = (zmin-z1) / (z2-z1)
        if 0<=t<=1:
            x = x1+t*(x2-x1)
            if xmin<=x<=xmax:
                y = y1+t*(y2-y1)
                if ymin<=y<=ymax:
                    return True
        t = (zmax-z1) / (z2-z1)
            #same 6 lines

    return False