Search code examples
pythongeometrycomputational-geometry

Python code to check if a point is inside or outside a Cuboid


for a particular purpose, I have to find whether a given point is inside a cuboid or not. With help from this link ( https://math.stackexchange.com/questions/1472049/check-if-a-point-is-inside-a-rectangular-shaped-area-3d ). I have written a prototype code which can check if the points are inside a cuboid or not.

( for the mathematics of this, please refer this link.)

for this, we should define the 3 mutually perpendicular axes of the cuboid.

Here is my code

import numpy

def dot(v1, v2):
    return numpy.sqrt(numpy.square(numpy.dot(v1, v2)))

def InCuboid ( plist,pnt):
    c1 = plist[0]
    c2 = plist[1]
    c3 = plist[2]
    c4 = plist[3]
    u1 = numpy.subtract(c1, c2)
    u2 = numpy.subtract(c1, c3)
    u3 = numpy.subtract(c1, c4)
    t = pnt
    if dot(u1, c1) <= dot(u1, t) <= dot(u1, c2) and dot(u2, c1) <= dot(u2, t) <= dot(u2, c3) and dot(u3, c1) <= dot(u3,t) <= dot(u3, c4):
        return "In"
    else :
        return "Out"

c1 = [-100,1,-10]
c2 = [-50,1,-10]
c3 = [-100,3.0,-10]
c4 = [-100,1,10]

plst = [c1,c2,c3,c4]
mlst = [[0,0,0],[100,1000,1000],[-80,2,0],[-80,2,1]]

for p in mlst :
    print InCuboid(plst,p)


If the common vertex is at the origin, this is working fine. But if it's any general point, the code is not working. can anyone help me to find the problem?


Solution

  • If your cuboid is axis-aligned, such computations are overkill - it's enough to compare coordinates.

    For arbitrary orientation you have to modify code slightly. Remove strange construction

    return numpy.sqrt(numpy.square(numpy.dot(v1, v2)))
    

    Do you mean abs? I doubt that algorithm requires to omit dot product sign.

    def dot(v1, v2):
        return numpy.dot(v1, v2)
    ....
     u1 = numpy.subtract(c1, c2)
     u2 = numpy.subtract(c1, c3)
     u3 = numpy.subtract(c1, c4)
     t = pnt
     if min(dot(u1, c1), dot(u1, c2)) <= dot(u1, t) <= max(dot(u1, c1), dot(u1, c2))\
        and min(dot(u2, c1), dot(u2, c3)) <= dot(u2, t) <= max(dot(u2, c1), dot(u1, c3))\
        and min(dot(u3, c1), dot(u3, c4)) <= dot(u3, t) <= max(dot(u3, c1), dot(u3, c4)):
            return "In"
        else :
            return "Out"
    

    Returns Out Out In In for your example and In In Out Out for mine:

    c1 = [-10,-10,-10]
    c2 = [-10, -10, 10]
    c3 = [-10, 10, -10]
    c4 = [10, -10, -10]
    
    plst = [c1,c2,c3,c4]
    mlst = [[0,0,0],[1,1,1],[30,2,0],[4,-20,1]]