Sweep Plane until Lower Section has a certain volume


I am new to Kangaroo, and I have a simple problem I am trying to solve:

  • I have two shapes: a plane and a box as shown in the photo:

  • The plane cuts the box into two parts (upper and lower).

  • The box is fixed, but the plane is allowed to move up and down.

  • I want to find the position of the plane such that the lower part is a certain value (let’s say 40% of the original box volume).

  • Can this be done in Kangaroo, and how?

I would appreciate any tips and advice.

Background about the question: I am currently working on floating city project at Princeton, and the box actually represents the platform of the floating city; the plane represents the waterline at rest.
Solving the problem above can help me understand the stability of floating cities using potential energy.

Thanks in advance!

For a simple geometry like this I don’t think there’s any need to use Kangaroo - it can be a simple geometric calculation.
If this is an example leading to more complex geometries though, here’s an example I made a while ago for simulating floating objects using Archimedes’ principle
buoyancy_archimedes.gh (60.1 KB)


If you’re just dealing with an upright box, I don’t think you need Kangaroo. If the box has a height H, and you want the bottom volume to be 40% of the total, then the plane, oriented any way you like (so long as it does not intersect the top or bottom) should pass through a point .40*H along the line going from the base through the centroid. BTW, I’m using a Python component that splits a brep with a plane that I downloaded from who knows where, who knows when.

Box Slice.gh (13.9 KB)


this looks amazing! yes I am eventually looking to do more complex shapes for sure. By the way, how did you calculate the angle of floatation? did you use metacenter or potential energy?

It uses the centre of mass and the centre of buoyancy, iteratively recalculating the volume of the object which is below the waterline.

I remember a fun online discussion a while back about how most illustrations you find of icebergs draw them wrong in completely unstable positions.

Following that someone made a little interactive thing where you could draw a 2d iceberg and see how it would float:

The definition above is doing the same thing but in 3d


thanks a lot! I will start digging into the file you attached and try to understand it.

I really appreciate your replies!

thanks a lot for your reply! actually I need the plane to cut through the bottom and top and this is essential for my project. Do you think you can still help with it? I would really appreciate it.

I was looking at the file, and I have noticed there is a script coding panel. Do you think the problem can be solved without using script coding?

What’s the problem with the script?
You don’t need to open or edit it. When you open the definition you will get a message about setting the assembly reference location, and you need to select where KangarooSolver.dll is located on your machine, which is typically something like:

The buoyancy function isn’t a part of default Kangaroo so I used the script here to add it.

For just finding the height of a plane of predefined orientation which divides an arbitrary solid into given volume fractions, I think it could be done without any Kangaroo by sampling at many heights and interpolating.
To also include the rotation and see in what orientation an object would float I think it would be awkward to do without either Kangaroo or some other form of iteration or scripting.

Thanks a lot for the reply.

When you mentioned:

" For just finding the height of a plane of predefined orientation which divides an arbitrary solid into given volume fractions, I think it could be done without any Kangaroo by sampling at many heights and interpolating."

This is exactly what I am looking for. I have done it for 2D shapes in Python using for loops, but I wanted a 3D shape so that’s why I moved to Kangaroo, so how could this process be done in it or even just in Grasshopper? Any tips to get started is appreciated.

This is the vanilla GH brute force sampling approach -

volumefraction.gh (105.3 KB)

1 Like

Daniel, I tried basically the same interpolation method last night using breps instead of meshes, but normalizing the volume fraction curve to be between 0 and 1 before intersecting with a line. It was only sometimes accurate. When I saw that you extended your curve WAY out there so it almost looks straight, as well as the intersecting line, I figured you’d lose accuracy, but I guess I was wrong.

Yes, here the curve height values are directly from the non normalised volumes, and the normalisation happens downstream of the interpolation and intersection. I guess compressing it all down to unit height before doing the intersection could run into numerical accuracy issues.

Thanks for the reply! In this solution, does the plane need to be horizontal? is there a way to allow for inclined planes?

Do you mean a single predefined and fixed inclination? If so, then the easiest way is probably just to rotate the input mesh.

If you mean having the orientation of the plane change to find how a shape would actually float - for this the curve interpolation/intersection approach isn’t suitable, since you have more than one input variable to optimize.
So there an iterative approach like the one in my first reply makes more sense.

Thanks a lot! I have spent the past 2 days trying to understand what you created, and I really appreciate it. I am moving now to the next step and I will ask more on the forum since I am new to this software.

By the way, what’s the purpose of the little C# script in the grasshopper network you created?

Hi Daniel

I’ve been studying your excellent floatation simulation.

One thing I’ve noticed it that the center of mass is a fixed point of the object and the beginning and doesn’t moved with the object as the solver iterates. Am I correct? If so, how would you get the center of mass to stay relative to the object as it moves?

Thanks in advance,


This is very cool. Sorry I missed it when you posted. I don’t think I need this:


But I would appreciate a ‘Transform’ output like OpenNest has, so that I can apply the same transformations to a brep input? (boat hull)

Years ago I wrote a ‘Z-offset Solver’ with Anemone for this purpose. Many of the results I get from this Hydrostatics package depend on brep solutions so while I don’t mind using a mesh to calculate where the hulls sit in the water, I prefer working with the original brep to derive the rest.


How the bear/hull floats is very interesting but now that I think about it, I don’t necessarily want Kangaroo to change the initial pitch and roll angles because seeing where the hull floats with those inputs was a major feature. But that is secondary to getting the ‘Transform’ output.

The BouncySolver ‘V’ output shows the COG (Center Of Gravity) moves in Z to its floating position but keeps X and Y constant, which is fine with me.

Yes, that MeshVolume can be replaced with the native one

Here’s how you get the transform output for a rigid body from the simulation-
buoyancy_archimedes2.gh (56.7 KB)

1 Like

EXCELLENT! Thank you very much. This will drastically improve the speed and convenience of my hydro calcs. I’m very curious to see how this will work with two unequal proa hulls. Coffee first.

Just in case, is there a way to prevent the bear from rolling over or pitching?

P.S. Belatedly, I see the C# now in the Buoyancy ‘GoalObject’. Very interesting. Will study it later, after getting the hydrostatics to work with it as is. Way cool! :sunglasses: