如何确定一个点是在立方体内部还是外部?

jhy*_*yap 2 c# geometry

给定一个在3D空间中具有8个顶点的立方体.我如何确定myPoint立方体内部或外部?

cube[0] = (x0, y0, z0);
cube[1] = (x1, y1, z1);
cube[2] = (x2, y2, z2);
cube[3] = (x3, y3, z3);
cube[4] = (x4, y4, z4);
cube[5] = (x5, y5, z5);
cube[6] = (x6, y6, z6);
cube[7] = (x7, y7, z7);

myPoint = (x, y, z);
Run Code Online (Sandbox Code Playgroud)

我试图在3D中实现这种数据过滤技术

Mar*_*man 5

可能最简单的方法是计算绑定立方体的6个平面中的每个平面的平面方程,将点插入每个平面并确保结果标记为正(或者为负,取决于您是否计算平面到面向内或向外).平面方程是p*normal + k = 0,通过取两个边之间的叉积来计算法线,然后将其中一个点插入平面方程中得到k.

更高级的方法是想象定义X,Y和Z轴的立方体和偏移(由立方体[0]定义)并将它们插入矩阵以转换两个空间之间的点.通过此矩阵的逆转换您的点将其置于"立方体空间"中,其中立方体与X/Y/Z轴对齐,因此您可以仅对边进行幅度比较.


max*_*000 5

如果你想从链接的帖子实现想法,考虑轴对齐的立方体(实际上是平行六面体)是有意义的.在那种情况下,支票是xmin<=x<=xmax && ymin<=y<=ymax && zmin<=z<=zmax.


bhu*_*han 5

特例1(轴对齐立方体)

maxim1000的答案所示,您可以简单地检查所考虑点的X,Y,Z坐标是否位于多维数据集的X,Y,Z坐标的最小值和最大值中。

X_min <= X <= X_max and Y_min <= Y <= Y_max  and Z_min <= Z <= Z_max
Run Code Online (Sandbox Code Playgroud)

如果满足上述条件,则该点位于立方体内部,否则不存在。

一般案例(定向多维数据集)

有两种解决方法。首先,将点引入立方体的局部坐标系并应用上述特殊情况。第二种情况是关于向量投影的概念。第一种情况比第二种情况稍微复杂一点,因为您需要计算旋转矩阵,该矩阵将点从世界坐标系转换为多维数据集的局部坐标系。考虑下图所示的多维数据集。

在此处输入图片说明

对于这两种方法,我们都需要从多维数据集表示中获取一些基本信息。让我们将原点固定在立方体左下角的立方体的局部坐标系中;在这种情况下,它是点D。现在,在三个维度上计算单位方向矢量,并计算这些方向上的立方体范围。可以如下进行。

在此处输入图片说明

X 局部,Y 局部和Z 局部在图中以蓝色,红色,绿色示出。X 长度,Y 长度和Z 长度是沿轴的范围。

现在让我们重新解决问题。

方法1:在多维数据集的局部坐标系中考虑点。为此,我们需要估算旋转矩阵。在这种情况下,旋转矩阵是3 x 3的矩阵,其中X 局部,Y 局部和Z 局部作为列。

在此处输入图片说明

使用旋转矩阵R,可以将点带入局部坐标系,然后应用轴对齐立方体的特殊情况。

方法2

构造从立方体中心到所考虑点的方向向量,并将其投影到每个局部轴上,并检查投影是否沿该轴跨越了立方体的范围。如果投影位于沿每个轴的范围内,则点在内部,否则在立方体的外部。

在此处输入图片说明

如图所示,立方体的中心是I。从立方体中心到点P的方向向量是V。向量V在X local,Y local和Z local上的投影可以如下计算。

在此处输入图片说明

现在,只有满足以下所有条件,点P才在立方体内部。

在此处输入图片说明

这是方法2中python的快速实现。

import numpy as np

def inside_test(points , cube3d):
    """
    cube3d  =  numpy array of the shape (8,3) with coordinates in the clockwise order. first the bottom plane is considered then the top one.
    points = array of points with shape (N, 3).

    Returns the indices of the points array which are outside the cube3d
    """
    b1,b2,b3,b4,t1,t2,t3,t4 = cube3d

    dir1 = (t1-b1)
    size1 = np.linalg.norm(dir1)
    dir1 = dir1 / size1

    dir2 = (b2-b1)
    size2 = np.linalg.norm(dir2)
    dir2 = dir2 / size2

    dir3 = (b4-b1)
    size3 = np.linalg.norm(dir3)
    dir3 = dir3 / size3

    cube3d_center = (b1 + t3)/2.0

    dir_vec = points - cube3d_center

    res1 = np.where( (np.absolute(np.dot(dir_vec, dir1)) * 2) > size1 )[0]
    res2 = np.where( (np.absolute(np.dot(dir_vec, dir2)) * 2) > size2 )[0]
    res3 = np.where( (np.absolute(np.dot(dir_vec, dir3)) * 2) > size3 )[0]

    return list( set().union(res1, res2, res3) )
Run Code Online (Sandbox Code Playgroud)