特殊情况#1(轴对齐立方体):
As maxim1000 的回答如图所示,您可以简单地检查所考虑点的 X、Y、Z 坐标是否位于立方体的 X、Y、Z 坐标的最小值和最大值内。
X_min <= X <= X_max and Y_min <= Y <= Y_max and Z_min <= Z <= Z_max
如果满足上述条件,则该点位于立方体内部,否则则不在立方体内部。
一般情况(定向立方体):
有两种方法可以解决这个问题。第一个将点引入立方体的局部坐标系中并应用上述特殊情况。第二种情况涉及向量投影的概念。第一种情况比第二种情况稍微复杂一些,因为您需要计算将点从世界坐标系转换到立方体的本地坐标系的旋转矩阵。考虑如下图所示的立方体。
对于这两种方法,我们都需要从立方体表示中获取一些基本信息。让我们将原点固定在立方体的左下角的立方体局部坐标系中;在本例中,它是点 D。现在计算三个维度上的单位方向向量以及立方体在这些方向上的范围。可以按如下方式完成。
The Xlocal, Ylocal, and Zlocal are illustrated in the figure with Blue, Red, Green colors. And Xlength, Ylength, and Zlength are the extents along the axes.
现在让我们回到解决问题上来。
Approach #1: Bring the point in consideration, in the local coordinate system of the Cube. To do that, we need to estimate the rotation matrix. Rotation matrix in this case is 3 x 3 matrix with Xlocal, Ylocal, and Zlocal as columns.
使用旋转矩阵 R,您可以将点置于局部坐标系中,然后应用轴对齐立方体的特殊情况。
方法#2:
构建从立方体中心到考虑点的方向向量,并将其投影到每个局部轴上,并检查投影是否超出立方体沿该轴的范围。如果投影位于沿每个轴的范围内,则点位于立方体内部,否则位于立方体外部。
The center of the cube is I, as show in the figure. The direction vector from the center of the cube to the point P is V. The projection of the vector V on Xlocal, Ylocal, and Zlocal can be calculated as follows.
现在,只有满足以下所有条件,点 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) )