# Box.Contains(Box) Check for Coincident Boxes?

**URL:** <https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642>\
**Category:** Rhino Developer\
**Tags:** rhinocommon\
**Created:** [April 4, 2018, 9:22am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642 "2018-04-04T09:22:34Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [April 4, 2018, 9:22am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/1 "2018-04-04T09:22:34Z")

</div>

Hi All,

I’m attempting to implement the [Box.Contains(Box)](http://developer.rhino3d.com/5/api/RhinoCommonWin/html/M_Rhino_Geometry_Box_Contains_2.htm) method to check for coincident boxes. The API states that this method will return:

> true if the box is on the inside of or coincident with this Box.

I might be misunderstanding what exactly is meant by coincident here, but am getting a `False` for cases like the left one here (I did try out a bunch of higher/lower Rhino document tolerances with the same result):

 ![0%20Commercial%20-%20%5BPerspective%5D](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/6/8/68c75adae250302122a7b9048ff017a443712dd6.png)  
[180404\_BoxBoxContainment\_00.gh](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/a/c/acc75f85a09bd7565190d603519ca82b0b0d4d95.gh) (6.0 KB)

Is this the expected behavior?

Best,

Anders

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [April 4, 2018, 9:44am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/2 "2018-04-04T09:44:17Z")

</div>

Oh hang on, looks like is this coincidence that is checked:

 ![0%20Commercial%20-%20%5BPerspective%5D](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/9/a/9ae7e3dcbba95eefefd53aebdc26ab38f725e458.jpg)

In which case, I might move to `BrepBrep` or `MeshMesh` intersections (which also have built-in tolerances for allowing gaps and such). But will likely be substantially slower (I’m looking at cases with many boxes), maybe an existing `BoxBox` intersection function (with tolerance) is available somewhere. Will do some digging.

---

<div class="post-metadata">

**Author:** ![qythium](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/qythium/32/84125_2.png) [@qythium](https://discourse.mcneel.com/u/qythium)\
**Post date:** [April 4, 2018, 10:02am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/3 "2018-04-04T10:02:41Z")

</div>

Hmm, that looks exactly how I would expect “Contains” to work - return True only if all the vertices of the inner box are within the bounds of the outer box? I think ‘coincident’ in this context just means that the inequality checking is non-strict… min(x\_1) \le x\_2 \le max(x\_1) and so on, such that a box is considered to contain itself.

([RTrees](http://developer.rhino3d.com/5/api/RhinoCommonWin/html/M_Rhino_Geometry_RTree_SearchOverlaps.htm) are great for intersecting tons of boxes 🙂 )

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [April 4, 2018, 10:13am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/4 "2018-04-04T10:13:21Z")

</div>

> [@qythium](#):
>
> such that a box is considered to contain itself

Which makes perfect sense, think I was overly fixated on the _coincident_ property, and not the _contain_ one 😉

> [@qythium](#):
>
> (RTrees are great for intersecting tons of boxes

I should have been more specific: I’m looking at cases where boxes are not aligned and of arbitrary height (i.e. in 3D), like these bad boys:

 ![image](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/8/f/8fe6b93c0f6013e89c4d062a557dbe55e2e08778.jpg)

Where RTrees wouldn’t work, I assume?

Looks like there’s a ton of stuff on box-box collisions for real-time graphics, so hopefully that might yield something clever. Will have a look at `MeshMesh` and `MeshClash` first though.

---

<div class="post-metadata">

**Author:** ![Dani\_Abalde](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/dani_abalde/32/759411_2.png) [@Dani\_Abalde](https://discourse.mcneel.com/u/Dani_Abalde)\
**Post date:** [April 4, 2018, 10:24am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/5 "2018-04-04T10:24:46Z")

</div>

To detect if two boxes collide, I think this works:

```
public bool BoxBoxCollide(Box A, Box B){
    foreach(Point3d p in A.GetCorners())
      if(B.Contains(p))return true;
    foreach(Point3d p in B.GetCorners())
      if(A.Contains(p))return true;
    return false;
  }
```

---

<div class="post-metadata">

**Author:** ![qythium](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/qythium/32/84125_2.png) [@qythium](https://discourse.mcneel.com/u/qythium)\
**Post date:** [April 4, 2018, 10:28am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/6 "2018-04-04T10:28:44Z")

</div>

I think an RTree would still help in that case to quickly narrow the scope of candidates to test, because 3d intersections between two objects happen if and only if their axis-aligned bounding boxes intersect.

@Dani_Abalde That logic does not work for cases like this:

 ![image](https://global.discourse-cdn.com/mcneel/original/3X/8/f/8f8e41b552483468b07e7fbe77ff8046ff282e91.png)

---

<div class="post-metadata">

**Author:** ![Dani\_Abalde](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/dani_abalde/32/759411_2.png) [@Dani\_Abalde](https://discourse.mcneel.com/u/Dani_Abalde)\
**Post date:** [April 4, 2018, 10:31am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/7 "2018-04-04T10:31:46Z")

</div>

Facepalm 🙈

```
  public bool BoxBoxCollide(Box A, Box B){
    MeshFace[] faces = new MeshFace[]{
      new MeshFace(0, 3, 2, 1), new MeshFace(0, 1, 5, 4),
      new MeshFace(1, 2, 6, 5), new MeshFace(2, 3, 7, 6),
      new MeshFace(3, 0, 4, 7), new MeshFace(4, 5, 6, 7)
      };
    Mesh MA = new Mesh(); 
    MA.Vertices.AddVertices(A.GetCorners());
    MA.Faces.AddFaces(faces);
    Mesh MB = new Mesh(); 
    MB.Vertices.AddVertices(B.GetCorners());
    MB.Faces.AddFaces(faces);
    return Rhino.Geometry.Intersect.Intersection.MeshMeshFast(MA, MB).Length > 0;
  }
```

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [April 4, 2018, 11:45am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/8 "2018-04-04T11:45:41Z")

</div>

Cheers guys. I also just tested the two MeshMesh intersections methods, and am not seeing the results I was expecting, again I may be misunderstanding their design:

 ![dk%20-%20Outlook](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/d/7/d7696b9f0ea5f03e254dca97e20fe47dab828164.png)  
[180404\_MeshMeshIntersections\_00.gh](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/a/f/af8ea2adcbb0ef94340fcebeb27d3fb6965f04fe.gh) (22.9 KB)

Notably:

1. I am not getting any intersections with `MeshMeshFast` in Case A (left).
2. I am not getting any intersections with `MeshMeshAccurate` in Case A when I lower the tolerance.
3. With a higher tolerance, I do get results, but they’re all over the place.
4. `MeshMeshFast` work as (I) expected in Case B (right).
5. `MeshMeshAccurate` returns somewhat expected results in Case B when lowering tolerance.
6. But also returns “wacky” results like Case A with a higher tolerance.

The meshes are close to the origin, and have reasonable dimensions. But perhaps this is another one of these “meshy” things?

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [April 4, 2018, 1:13pm UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/9 "2018-04-04T13:13:04Z")

</div>

Think I came up with a decent conjecture, covering my cases:

 ![0%20Commercial%20-%20%5BPerspective%5D](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/6/8/68f184cd8e8d6f6a67638dad2cf4ec63413e12fe.jpg)

 ![image](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/8/6/86e97960a3ebd3265eb53ae1df25aba5681e0afa.jpg)

 ![image](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/3/7/3703d895222ee6cb7334ab4eef4e2b4dbfe242ab.jpg)

And the full penetration one from @qythium:

 ![2018-04-04%2015_06_25-Grasshopper%20-%20180404_BoxBoxIntersection_00_](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/b/c/bc40cc2dfb6e1486f5ca88aab7afe992bce9d981.png)

Basically:

1. For all corners in BoxA (green): Find the closest point on BoxB (purple)
2. For these points on BoxB: Find the closest point on BoxA (not rendered)
3. Make a line between these points (yellow)
4. If the length of this line is zero, the two boxes intersect (I think!)

---

<div class="post-metadata">

**Author:** ![qythium](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/qythium/32/84125_2.png) [@qythium](https://discourse.mcneel.com/u/qythium)\
**Post date:** [April 4, 2018, 1:35pm UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/10 "2018-04-04T13:35:38Z")

</div>

hmm… what if one box is entirely inside the other?  
Or if only one corner is poking through a face:  
 ![image](https://global.discourse-cdn.com/mcneel/original/3X/f/9/f93bb1c31feb204034334d5364683c1bf014a8a0.png)  
You might cover everything by checking `box.Contains(point)` for all the corners, but this method is probably quite expensive due to all the ClosestPoint checks.

A bit of Googling around shows that there’s a standard algorithm called Separating Axis Theorem used for oriented bounding box (OBB) intersection checks, requiring only 15 steps to verify that two boxes do not intersect (fewer if they do, and the algorithm gets an early exit) : [http://www.jkh.me/files/tutorials/Separating%20Axis%20Theorem%20for%20Oriented%20Bounding%20Boxes.pdf](http://www.jkh.me/files/tutorials/Separating%20Axis%20Theorem%20for%20Oriented%20Bounding%20Boxes.pdf)

 ![image](https://global.discourse-cdn.com/mcneel/original/3X/1/4/1437a110f7ed7b309054b9ed037512d4ddd909e4.png)

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [April 4, 2018, 1:51pm UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/11 "2018-04-04T13:51:50Z")

</div>

> [@qythium](#):
>
> what if one box is entirely inside the other?
> 
> Or if only one corner is poking through a face:

The algorithm catches both these cases:

 ![2018-04-04%2015_41_11-Grasshopper%20-%20180404_BoxBoxIntersection_01_](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/a/5/a5e14d1b18b3db9836a6705d89a11a17c1ec7e3d.png) ![2018-04-04%2015_41_50-](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/7/b/7b84463196533138f814e22198f6b2ff207957ab.png) ![2018-04-04%2015_47_38-Grasshopper%20-%20180404_BoxBoxIntersection_01](https://global.discourse-cdn.com/mcneel/uploads/default/original/3X/5/b/5b882f4ef407a5a06cb6959a160246f110982d8f.png)

That said, I’m sure there are some cases it doesn’t. Although so far I’m surprised at how robust it appears to be. Will run some more testing before implementing it, but pretty sure it passes the smell test for our current purposes. Would love to dig into all this some more if time wasn’t a concern, thanks for the link 🙂

---

<div class="post-metadata">

**Author:** ![qythium](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/qythium/32/84125_2.png) [@qythium](https://discourse.mcneel.com/u/qythium)\
**Post date:** [April 4, 2018, 2:19pm UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/12 "2018-04-04T14:19:44Z")

</div>

Oh I see– `Box.ClosestPoint` returns the closest point in the box’s _volume_, not its surface as I had assumed (from the way Rhino works in general). That’s useful to know 😄  
(And yes, I’d actually much rather go with your simple-to-understand method versus 30 lines of dense vector calculations where typos can easily happen)

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [April 4, 2018, 2:27pm UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/13 "2018-04-04T14:27:08Z")

</div>

> [@qythium](#):
>
> returns the closest point in the box’s volume

Exactly, and with the bounce back to the starting box, I _think_ that covers most cases 🙈

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [March 3, 2021, 9:32am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/14 "2021-03-03T09:32:42Z")

</div>

Hi @AndersDeleuran ,

I was using your method for box collision, it seems very robust and lets speeding up the RTree search.  
But it cannot handle the case below. Do you have any ideas how to include this one into the box collision check you developed?

 ![Collision](https://global.discourse-cdn.com/mcneel/uploads/default/original/4X/8/8/b/88b6d29eade46cef377e2b820c4173b7cdcb42c6.png) [BoxCollision.3dm](https://discourse.mcneel.com/uploads/short-url/9U9SeQDva9hcudSVQdiq7p7AcvL.3dm) (113.5 KB)

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [March 3, 2021, 10:43am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/15 "2021-03-03T10:43:22Z")

</div>

Hmm, maybe, can you internalise the boxes in a GH file instead of breps in a Rhino file?

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [March 3, 2021, 11:42am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/16 "2021-03-03T11:42:11Z")

</div>

These are two boxes:  
[Boxes.gh](https://discourse.mcneel.com/uploads/short-url/sSyW79IDMHOzMbajXVqOBNWEjnH.gh) (5.5 KB)

---

<div class="post-metadata">

**Author:** ![AndersDeleuran](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/andersdeleuran/32/476683_2.png) [@AndersDeleuran](https://discourse.mcneel.com/u/AndersDeleuran)\
**Post date:** [March 4, 2021, 10:05am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/17 "2021-03-04T10:05:23Z")

</div>

Yes I see what you mean. I’m afraid I don’t have any immediate ideas how to improve/extend the logic I developed to catch such cases. Considering the updates to mesh intersections in Rhino 7, that might be a tree worth barking up again?

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [March 4, 2021, 10:25am UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/18 "2021-03-04T10:25:26Z")

</div>

Yup this is what I am doing now, first cheking through your code then meshmeshfast 🙂

---

<div class="post-metadata">

**Author:** ![Petras1](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras1/32/479880_2.png) [@Petras1](https://discourse.mcneel.com/u/Petras1)\
**Post date:** [August 11, 2021, 2:03pm UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/19 "2021-08-11T14:03:51Z")

</div>

This post is made quite long time ago, but I found stackoverflow method that does this correctly in C++, which could be easily understood in C# or Python as well. The magic math…

```auto
// define the operations to be used in our 3D vertices
struct vec3
{
    float x, y, z;
    vec3 operator- (const vec3& rhs) const { return{ x - rhs.x, y - rhs.y, z - rhs.z }; }
    float operator* (const vec3& rhs) const { return{ x * rhs.x + y * rhs.y + z * rhs.z }; } // DOT PRODUCT
    vec3 operator^ (const vec3& rhs) const { return{ y * rhs.z - z * rhs.y, z * rhs.x - x * rhs.z, x * rhs.y - y * rhs.x }; } // CROSS PRODUCT
    vec3 operator* (const float& rhs)const { return vec3{ x * rhs, y * rhs, z * rhs }; }
};

// set the relevant elements of our oriented bounding box
struct OBB
{
    vec3 Pos, AxisX, AxisY, AxisZ, Half_size;
};

// check if there's a separating plane in between the selected axes
inline bool getSeparatingPlane(const vec3& RPos, const vec3& Plane, const OBB& box1, const OBB& box2)
{
    return (fabs(RPos * Plane) >
        (fabs((box1.AxisX * box1.Half_size.x) * Plane) +
            fabs((box1.AxisY * box1.Half_size.y) * Plane) +
            fabs((box1.AxisZ * box1.Half_size.z) * Plane) +
            fabs((box2.AxisX * box2.Half_size.x) * Plane) +
            fabs((box2.AxisY * box2.Half_size.y) * Plane) +
            fabs((box2.AxisZ * box2.Half_size.z) * Plane)));
}

// test for separating planes in all 15 axes
inline bool getCollision(const OBB& box1, const OBB& box2)
{
    static vec3 RPos;
    RPos = box2.Pos - box1.Pos;

    return !(getSeparatingPlane(RPos, box1.AxisX, box1, box2) ||
        getSeparatingPlane(RPos, box1.AxisY, box1, box2) ||
        getSeparatingPlane(RPos, box1.AxisZ, box1, box2) ||
        getSeparatingPlane(RPos, box2.AxisX, box1, box2) ||
        getSeparatingPlane(RPos, box2.AxisY, box1, box2) ||
        getSeparatingPlane(RPos, box2.AxisZ, box1, box2) ||
        getSeparatingPlane(RPos, box1.AxisX ^ box2.AxisX, box1, box2) ||
        getSeparatingPlane(RPos, box1.AxisX ^ box2.AxisY, box1, box2) ||
        getSeparatingPlane(RPos, box1.AxisX ^ box2.AxisZ, box1, box2) ||
        getSeparatingPlane(RPos, box1.AxisY ^ box2.AxisX, box1, box2) ||
        getSeparatingPlane(RPos, box1.AxisY ^ box2.AxisY, box1, box2) ||
        getSeparatingPlane(RPos, box1.AxisY ^ box2.AxisZ, box1, box2) ||
        getSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisX, box1, box2) ||
        getSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisY, box1, box2) ||
        getSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisZ, box1, box2));
}

PINVOKE inline bool OBBCollide(
    float APosX, float APosY, float APosZ,//set the first obb's properties
    float AHalfSizeX, float AHalfSizeY, float AHalfSizeZ,//set the half size
    float AAxis0X, float AAxis0Y, float AAxis0Z,//set XAxis
    float AAxis1X, float AAxis1Y, float AAxis1Z,//set YAxis
    float AAxis2X, float AAxis2Y, float AAxis2Z,//set ZAxis

    float BPosX, float BPosY, float BPosZ,//set the first obb's properties
    float BHalfSizeX, float BHalfSizeY, float BHalfSizeZ,//set the half size
    float BAxis0X, float BAxis0Y, float BAxis0Z,//set XAxis
    float BAxis1X, float BAxis1Y, float BAxis1Z,//set YAxis
    float BAxis2X, float BAxis2Y, float BAxis2Z//set ZAxis

) {

    //Test
    // create two obbs
    OBB A, B;

    // set the first obb's properties
    A.Pos = { APosX, APosY, APosZ }; // set its center position

    // set the half size
    A.Half_size.x = AHalfSizeX;
    A.Half_size.y = AHalfSizeY;
    A.Half_size.z = AHalfSizeZ;

    // set the axes orientation
    A.AxisX = { AAxis0X, AAxis0Y, AAxis0Z };
    A.AxisY = { AAxis1X, AAxis1Y, AAxis1Z };
    A.AxisZ = { AAxis2X, AAxis2Y, AAxis2Z };

    // set the second obb's properties
    B.Pos = { BPosX, BPosY, BPosZ }; // set its center position

    // set the half size
    B.Half_size.x = BHalfSizeX;
    B.Half_size.y = BHalfSizeY;
    B.Half_size.z = BHalfSizeZ;

    // set the axes orientation
    B.AxisX = { BAxis0X, BAxis0Y, BAxis0Z };
    B.AxisY = { BAxis1X, BAxis1Y, BAxis1Z };
    B.AxisZ = { BAxis2X, BAxis2Y, BAxis2Z };

    // run the code and get the result as a message
    return getCollision(A, B);

}

```

 ![image](https://global.discourse-cdn.com/mcneel/uploads/default/original/4X/c/0/9/c094446a5b094c12a5b9b6d3181c1e24a46e8426.png)

---

<div class="post-metadata">

**Author:** ![Petras\_Vestartas](https://sea3.discourse-cdn.com/mcneel/user_avatar/discourse.mcneel.com/petras_vestartas/32/480531_2.png) [@Petras\_Vestartas](https://discourse.mcneel.com/u/Petras_Vestartas)\
**Post date:** [June 8, 2023, 2:29pm UTC](https://discourse.mcneel.com/t/box-contains-box-check-for-coincident-boxes/59642/20 "2023-06-08T14:29:41Z")

</div>

This is a conversion to C# from C++ incase some needs it, thanks to ChatGPT:

```csharp

private void RunScript(Brep x, Brep y, ref object A)
  {
  
    //example with boxes
    Box box1 = Box.Unset;
    Plane xPlane = Plane.Unset;
    x.Surfaces[0].FrameAt(0, 0, out xPlane);
    x.GetBoundingBox(xPlane, out box1);
    
    Box box2 = Box.Unset;
    Plane yPlane = Plane.Unset;
    y.Surfaces[0].FrameAt(0, 0, out yPlane);
    y.GetBoundingBox(yPlane, out box2);

    A = GetCollision(box1,box2);

    //example with bounding boxes
   // A = GetCollision(x.GetBoundingBox(true), y.GetBoundingBox(true));
  }

  // <Custom additional code> 

  // define the operations to be used in our 3D vertices
  // define the operations to be used in our 3D vertices
  public struct Vec3
  {
    public float x, y, z;

    public Vec3(float x, float y, float z){
      this.x = x;
      this.y = y;
      this.z = z;
    }

    public static Vec3 operator -(Vec3 lhs, Vec3 rhs)
    {
      return new Vec3 { x = lhs.x - rhs.x, y = lhs.y - rhs.y, z = lhs.z - rhs.z };
    }

    public static float operator *(Vec3 lhs, Vec3 rhs)
    {
      return lhs.x * rhs.x + lhs.y * rhs.y + lhs.z * rhs.z;
    }

    public static Vec3 operator ^(Vec3 lhs, Vec3 rhs)
    {
      return new Vec3 { x = lhs.y * rhs.z - lhs.z * rhs.y, y = lhs.z * rhs.x - lhs.x * rhs.z, z = lhs.x * rhs.y - lhs.y * rhs.x };
    }

    public static Vec3 operator *(Vec3 lhs, float rhs)
    {
      return new Vec3 { x = lhs.x * rhs, y = lhs.y * rhs, z = lhs.z * rhs };
    }
  }

  // set the relevant elements of our oriented bounding box
  public struct OBB
  {
    public Vec3 Pos, AxisX, AxisY, AxisZ, Half_size;

    public OBB(BoundingBox bbox)
    {
      // Calculate the center position of the bounding box
      Pos = new Vec3((float) (bbox.Min.X + bbox.Max.X) / 2f,
        (float) (bbox.Min.Y + bbox.Max.Y) / 2f,
        (float) (bbox.Min.Z + bbox.Max.Z) / 2f);

      // Calculate the size of the bounding box in each dimension
      float sizeX = (float) (bbox.Max.X - bbox.Min.X) / 2f;
      float sizeY = (float) (bbox.Max.Y - bbox.Min.Y) / 2f;
      float sizeZ = (float) (bbox.Max.Z - bbox.Min.Z) / 2f;

      // Set the axis vectors
      AxisX = new Vec3(1f, 0f, 0f);
      AxisY = new Vec3(0f, 1f, 0f);
      AxisZ = new Vec3(0f, 0f, 1f);

      // Set the half size of the bounding box
      Half_size = new Vec3(sizeX, sizeY, sizeZ);
    }

    public OBB(Box box)
    {
     

      // Calculate the center position of the box
      var center_points = box.PointAt(0.5, 0.5, 0.5);
      Pos = new Vec3((float) (center_points.X),
        (float) (center_points.Y),
        (float) (center_points.Z));

      // Calculate the axis vectors
      AxisX = new Vec3((float) (box.Plane.XAxis.X),
        (float) (box.Plane.XAxis.Y),
        (float) (box.Plane.XAxis.Z));
      AxisY = new Vec3((float) (box.Plane.YAxis.X),
        (float) (box.Plane.YAxis.Y),
        (float) (box.Plane.YAxis.Z));
      AxisZ = new Vec3((float) (box.Plane.ZAxis.X),
        (float) (box.Plane.ZAxis.Y),
        (float) (box.Plane.ZAxis.Z));

      // Set the half size of the box
      Half_size = new Vec3((float) (box.X.Length) / 2f,
        (float) (box.Y.Length) / 2f,
        (float) (box.Z.Length) / 2f);
    }
  }

  // check if there's a separating plane in between the selected axes
  public static bool GetSeparatingPlane(Vec3 RPos, Vec3 Plane, OBB box1, OBB box2)
  {
    return Math.Abs(RPos * Plane) >
      (Math.Abs((box1.AxisX * box1.Half_size.x) * Plane) +
      Math.Abs((box1.AxisY * box1.Half_size.y) * Plane) +
      Math.Abs((box1.AxisZ * box1.Half_size.z) * Plane) +
      Math.Abs((box2.AxisX * box2.Half_size.x) * Plane) +
      Math.Abs((box2.AxisY * box2.Half_size.y) * Plane) +
      Math.Abs((box2.AxisZ * box2.Half_size.z) * Plane));
  }

  // test for separating planes in all 15 axes
  public static int GetCollision(BoundingBox _box1, BoundingBox _box2) // -1_outside_0_intersected_1_inside
  {
    OBB box1 = new OBB(_box1);
    OBB box2 = new OBB(_box2);
    
    if(_box1.Contains(_box2))
      return 1;
    
    Vec3 RPos;
    RPos = box2.Pos - box1.Pos;

    bool result = !(GetSeparatingPlane(RPos, box1.AxisX, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisY, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisZ, box1, box2) ||
      GetSeparatingPlane(RPos, box2.AxisX, box1, box2) ||
      GetSeparatingPlane(RPos, box2.AxisY, box1, box2) ||
      GetSeparatingPlane(RPos, box2.AxisZ, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisX ^ box2.AxisX, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisX ^ box2.AxisY, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisX ^ box2.AxisZ, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisY ^ box2.AxisX, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisY ^ box2.AxisY, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisY ^ box2.AxisZ, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisX, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisY, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisZ, box1, box2));
    
    if(result)
      return 0;
    else
      return -1;
  }
  
  public static int GetCollision(Box _box1, Box _box2) // -1_outside_0_intersected_1_inside
  {
    OBB box1 = new OBB(_box1);
    OBB box2 = new OBB(_box2);
    
 
     if(_box1.Contains(_box2))
        return 1;
  

    Vec3 RPos;
    RPos = box2.Pos - box1.Pos;

    bool result = !(GetSeparatingPlane(RPos, box1.AxisX, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisY, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisZ, box1, box2) ||
      GetSeparatingPlane(RPos, box2.AxisX, box1, box2) ||
      GetSeparatingPlane(RPos, box2.AxisY, box1, box2) ||
      GetSeparatingPlane(RPos, box2.AxisZ, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisX ^ box2.AxisX, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisX ^ box2.AxisY, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisX ^ box2.AxisZ, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisY ^ box2.AxisX, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisY ^ box2.AxisY, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisY ^ box2.AxisZ, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisX, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisY, box1, box2) ||
      GetSeparatingPlane(RPos, box1.AxisZ ^ box2.AxisZ, box1, box2));
    
    if(result)
      return 0;
    else
      return -1;
  }

```
