0
\$\begingroup\$

I'm trying to find to obtain if a point, let's call it "v" is inside a cuboid which every corner position named P1 to P8

I am trying to achieve this and in fact found some answers in some other stacks, i'll place them here:

https://math.stackexchange.com/questions/923932/test-if-a-point-is-inside-a-3d-cuboid?rq=1

https://math.stackexchange.com/questions/4497343/point-in-irregular-3d-cuboid?noredirect=1&lq=1

https://math.stackexchange.com/questions/1472049/check-if-a-point-is-inside-a-rectangular-shaped-area-3d?rq=1

The thing is, i'm not too keen in mathematics so i'm kinda lost in this one, could some of you answer me which one of those is better and how to write it code-wise?

Any languaje will do, but csharp would be appreciated, i'm trying to learning to read this ecuations but i'm kinda lost and i don't know where to start, i also apreciate if you take the time to explain in human terms what that maths are doing.

I also found this question: fast 3d point -> cuboid volume intersection test

But i'm kinda looking for something more practical than doesn't vanish in the future of the internet to have here, in the StackExchange for future reference.

If this exist somewhere in this stack or somewhere else, i would love to hear where.

Thank you

\$\endgroup\$
4
  • 2
    \$\begingroup\$ Are all points P1-P8 the basic format the cuboid is represented in or is there another representation format you could work with? -- 8 points doesn't always define a cuboid, points have to be checked if they're coplanar for some side it, etc. It's possibly more complicated because of the format you're starting from. The planes that make up the sides, or the transformation from a unit cube to get your cuboid may be much more useful. \$\endgroup\$
    – Romen
    Nov 13 at 21:59
  • \$\begingroup\$ You may use this image as reference if it's make the things easier i.stack.imgur.com/iizbo.jpg However, if you see there is cases of detection than require certain specific conditions, or certain limit cases than a determinate way to operate will not work for them, please by any means make that know in the comment/answer too. \$\endgroup\$
    – user57129
    Nov 13 at 22:07
  • \$\begingroup\$ The visualization does not answer my question. How are you getting these 8 points? Are you calculating them? Do you have guarantees that they construct a cuboid at all? \$\endgroup\$
    – Romen
    Nov 13 at 22:11
  • \$\begingroup\$ I can guarantee that it is a cuboid and that it have that shape, that is at least one of the cases and the others are at least similar, nothing to much weirder than that, for instance, maybie height, weight or deep will vary but if you are worring about something like too far from the cubed-like shape, forget your worrys. \$\endgroup\$
    – user57129
    Nov 15 at 20:50

1 Answer 1

0
\$\begingroup\$

If you can guarantee that the 8 points form a prism with pairs of opposite faces parallel (even if the corners aren't perpendicular), then we can simplify this significantly.

We'll construct a transformation matrix that maps a standardized cube to this prism, then invert that matrix, and check if the test point transformed by that matrix lies inside the standard cube.

We'll make a 3x3 matrix M whose columns are:

  • P4 - P1 (width)
  • P5 - P1 (height)
  • P2 - P1 (depth)

You can confirm that taking any point in the cube formed by three coordinates in the range 0...1 and multiplying it by this matrix then adding P1 gives you a point in your original prism.

Then we can invert the matrix (use the matrix inverse function of whatever C# vector library you're using) and multiply your test point minus P1 by this inverse. If the test point were inside the prism, the output will have all three coordinates in the range 0...1 (with 0 and 1 being the outer faces). Otherwise, the point is outside the prism.

The advantage of this route is you can compute the inverse just once each time the prism is transformed, then re-use it to test many points against it cheaply. Each test is just one vector subtraction, three dot products, and six float comparisons.

Here's a C#-style example, assuming a sufficiently friendly vector math and matrix API:

public struct Cuboid {

    Matrix3x3 _matrix;
    Matrix3x3 _inverse;
    Vector3 _corner;

    // You can use 8 named arguments instead of an array, 
    // I just got tired of typing on my phone.
    public Cuboid(Vector3[] points) {
       _corner = points[0];
       _matrix = new Matrix3x3(
                   points[3] - points[0], // left column
                   points[4] - points[0], // middle column
                   points[1] - points[0]  // right column
        );
        _inverse = _matrix.inverse;
    }

    public bool Contains(Vector3 point) {
        // Remap point into "standard cube space".
        Vector3 standard = _inverse * (point - _corner);

        // Check if the remapped point lands inside
        // the 0...1 range of the standard cube.
        return (standard.x >= 0) & (standard.x <= 1)
             & (standard.y >= 0) & (standard.y <= 1)
             & (standard.z >= 0) & (standard.z <= 1);
    }

}

Note that even storing the matrix and inverse (for scale/rotation/skew) plus a corner (for translation), this data structure is still more compact (21 floats) than storing all 8 corner points (24 floats) and you can still extract all 8 corner points on demand. E.g. point[1] = _corner + _matrix.columns[1]

This method does not work if your 8-vertex object is not an affine transformation of a cube (i.e. if one of its faces is not a plane quadrilateral / not parallel to its opposite face).

\$\endgroup\$
4
  • \$\begingroup\$ Seems promesing, any librarys you can recommend for having things like Matrix Inverse? i don't know one in .Net that have one, although granted, i don't know all the math librarys out there, however that, i'll search for a way to make a matrix inverse, can i ask you for that function too? in any case, i will try to sort this issue and then test the whole code and mark it as solve if it works, otherwise i'll leave a message, thank you for your attempt. \$\endgroup\$
    – user57129
    Nov 15 at 20:45
  • 1
    \$\begingroup\$ I get some very promising results on the first page when I search for these keywords. Where have you run into trouble using existing guides here? \$\endgroup\$
    – DMGregory
    Nov 15 at 21:05
  • \$\begingroup\$ DMGregory, i manage to make an inverse matrix function based on what you bring here, and i give you an upvote for that, thanks for that, however another doubt now come to me, Given than the points are called P1 - P8, how should they be position in the Matrix3x3? i ask this because i don't understand what you mean with what you write in the constructor, i mean, is correlative?, there is a special order? how does that work, should i just start P1 - P3 in the M11 - M33 for instance? or how does that work?. \$\endgroup\$
    – user57129
    Nov 20 at 18:49
  • \$\begingroup\$ One column should be the difference between vertices along an edge spanning the width of the box. One column should be the difference along an edge spanning the height. One column should be the difference spanning the depth. \$\endgroup\$
    – DMGregory
    Nov 20 at 20:01

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .