Given a cube with 8 vertex in 3D space. How could I determine the myPoint
is inside or outside the cube?
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);
I am trying to implement this data filter technique in 3D
Special Case #1 (Axis Aligned Cube):
As maxim1000's answer shows, you can simply check if X, Y, Z coordinates of the point in consideration lie in the minimum and maximum of the X, Y, Z coordinates of the Cube.
X_min <= X <= X_max and Y_min <= Y <= Y_max and Z_min <= Z <= Z_max
If the aforementioned condition is satisfied then, the point lies inside the cube, otherwise it does not.
General Case (Oriented Cube):
There are two approaches to solve this. First one brings the point in the local coordinate system of the cube and apply the aforementioned Special Case. Second case works on the concept of the projection of the vector. First case is little more complex than the second as you need to calculate the rotation matrix which transforms the point from the world coordinate system into the Cube's local coordinate system. Consider the cube as show in the following figure.
For both the approaches we would need to derive some basic information from the cube representation. Let us fix origin in the local coordinate system of the cube at the bottom left corner of the cube; in this case, it is Point D. Now calculate the unit direction vectors in three dimensions and extent of the cube in those directions. It can be done as follows.
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.
Now lets get back to solving the problem.
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.
Using the rotation Matrix R, you can bring the point in the local coordinate system and then apply the special case of axis aligned cube.
Approach #2:
Construct the direction vector from the cube center to the point in consideration and project it onto each local axis and check if the projection spans beyond the extent of the cube along that axis. If the projection lies inside the extent along each axis, then point is inside, otherwise it is outside of the cube.
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.
Now the point P is inside the cube only if all of the following conditions are satisfied.
Here's the quick implementation in python for the approach #2.
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) )
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With