Issue
Given a cube with 8 vertex in 3D space. How could I determine the myPoint is inside 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 found a solution for this on Stack overflow(below). This sample solution returns the indexes of all points outside the cube. I tried to remake it to make the function return the indexes of the points that are inside the cube but failed. I've been sitting on this for 2 days. Is anyone able to help?
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) )
Solution
According to De Morgan's laws:
The complement of the union of two sets is the same as the intersection of their complements
The function returns the outside points, we want the inside – the complement set of points. The function returns the union
of three sets. So, in order to get the complement, according to De Morgan's law we need to compute the intersection
of the complements of these three sets.
So you need to reverse the unequality signs, and change union
to intersection
. This should work:
...
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().intersection(res1, res2, res3) )
Answered By - AndrzejO
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.