Weird plane-aligned bounding box inaccuracy...!

So, in messing around with a script here, I discovered something pretty bizarre…

In the file below, you will find a simple perfect sphere of radius 10.

Now, run the script below, which simply makes first a world-aligned bounding box, then changes the CPlane to some odd angle (in the file) and makes a CPlane-aligned bounding box. Then it compares the volume of the two boxes…

Now, in theory, the bounding box should measure exactly (within tolerance limits) 20 x 20 x 20 no matter what the orientation, and thus have a volume of 8000. Which the world-aligned bounding box does… But the CPlane aligned bounding box does not - it’s only 7981.31404 (+/- 1e-06) … OK, that’s only a difference of about 1/4 of one percent, but to me it’s quite significant…

BBPlaneCalc.3dm (279.7 KB)

import rhinoscriptsyntax as rs

objID=rs.ObjectsByType(8)[0]
bb=rs.BoundingBox(objID)
volume=bb[1].DistanceTo(bb[0])*bb[3].DistanceTo(bb[0])*bb[4].DistanceTo(bb[0])
rs.AddBox(bb)
rs.RestoreNamedCPlane("Tilted")
bb2=rs.BoundingBox(objID,rs.CurrentView())
volume2=bb2[1].DistanceTo(bb2[0])*bb2[3].DistanceTo(bb2[0])*bb2[4].DistanceTo(bb2[0])
rs.AddBox(bb2)
print "World-aligned volume: {}".format(volume)
print "CPlane-aligned volume: {}".format(volume2)

If you use the Rhino Volume command to measure the volume of the boxes, you find the same thing; you can also measure the sides of the second box to see they are too small.

Can someone enlighten me on why this happens? I was under the impression that the functions call an “accurate” bounding box… The Rhino file above is a V6 file, but the results are quasi-identical in V5.

Thanks, --Mitch

Hi Mitch - Checking it, thanks… I assume I’ll end up just passing it along to a developer…
@Helvetosaur - looks like isocurves are considered for the BB - I see that the result is correct if the sphere is oriented to the custom plane, or if you boost the iso display way up (rhino commands, not the script so far)… and I see that the plane aligned BB does not have an bool for tight in RhinoCommon… just noticing, still poking.

The script also varies with the iso display.

Sum’n wrong here, even with the top level Rhino command - I am buggifying…

https://mcneel.myjetbrains.com/youtrack/issue/RH-46912

-Pascal

OK, thanks!

I suspected it might be something like that… But that’s wrong, as you can never know what kind of ISO display the user will have. Plus, I’m mostly working with RhinoCommon geometry - which doesn’t have isos as far as I know… :confused:

I am using the following for an RC plane-aligned bounding box function - stolen directly from rhinoscriptsyntax geometry.py - less some of the the “coerce…” and view stuff in there, as they’re not needed

def BoundingBoxPlane(objs,plane,ret_pts=False):
    """returns a plane-aligned bounding box in world coordinates
       - input geometry must be RhinoCommon geometry (not IDs)
       - adapted from python rhinoscriptsyntax rs.BoundingBox() code."""
    wxy_plane=Rhino.Geometry.Plane.WorldXY
    def __objectbbox(geom,xform):
        if isinstance(geom,Rhino.Geometry.Point):
            pt=geom.Location
            if xform: pt = xform * pt
            return Rhino.Geometry.BoundingBox(pt,pt)
        if xform: return geom.GetBoundingBox(xform)
        return geom.GetBoundingBox(True)
    
    xform = Rhino.Geometry.Transform.ChangeBasis(wxy_plane, plane)
    bbox = Rhino.Geometry.BoundingBox.Empty
    if type(objs) is list or type(objs) is tuple:
        for obj in objs:
            objectbbox = __objectbbox(obj, xform)
            bbox = Rhino.Geometry.BoundingBox.Union(bbox,objectbbox)
    else:
        objectbbox = __objectbbox(objs, xform)
        bbox = Rhino.Geometry.BoundingBox.Union(bbox,objectbbox)
    if not bbox.IsValid: return
    plane_to_world = Rhino.Geometry.Transform.ChangeBasis(plane,wxy_plane)
    if ret_pts:
        corners = list(bbox.GetCorners())
        for pt in corners: pt.Transform(plane_to_world)
        return corners
    else:
        box=Rhino.Geometry.Box(bbox)
        box.Transform(plane_to_world)
        return box

Note that GeometryBase.GetBoundingBox(xform) used above is supposed to get an “accurate” bounding box according to the doc…

http://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Geometry_GeometryBase_GetBoundingBox_2.htm

Yep… and been that way for a long time apparently… :astonished:

1 Like