Volume and Center of mass

classic Classic list List threaded Threaded
7 messages Options
Reply | Threaded
Open this post in threaded view
|

Volume and Center of mass

blobule
Hi everyone, happy new year!

I have implemented the computation of volume and center of mass in OpenSCAD.
This is extending a previous proposal to compute the bounding box of an object ( see http://forum.openscad.org/request-for-comments-object-properties-and-or-alignment-td12983.html#a13200  ).

The way it works is through a "probe()" function which computes the bounding box, volume and center of mass of its first children, then renders all the other children with extra variables defined (bbsize, bbcenter, volume, centroid, ...).
For exemple:

module thing() { cube(20); translate([10,10,10]) cube(20); }
probe(volume=true) {
    thing(); // the thing to measure
    echo("volume=",volume," centroid=",centroid);
    %thing();
    color("red") translate(centroid) sphere(r=1,$fn=32);
}



This code will print "volume=15000 centroid=[15,15,15]". Notice that because volume computation can be slow, you must specify "volume=true" to probe() in order to get the information. It is an "on demand" computation, so I assume it will be used only when needed. And when its needed, it will surely be faster than computing by hand... :-)

The implementation somewhat simple: the polyhedron is decomposed into convex parts (just like minkowski() does), then each part is further decomposed into tetrahedrons. The volumes and centroids of all tetrahedrons are then collected to get the final result. By the way, the computation is performed on nef polyhedron using exact number representation, so it is very accurate.

Here are a few examples of what can be done with this...

A perfectly balanced object, where the base is automatically put at the center of gravity:


Balancing objects:


Finding the center of rotation of assymetric wheels:


Making objects the exact same volume (here a sphere(20) is used as a reference, and the computed cube has sides 32.0439... both have a volume of 32902.7 (not 33510.3 since the sphere is not a perfect sphere)



Can this be of any use to anyone? If so, I'll be happy to finalize it and submit it for inclusion.

Sincerely,

Sébastien

Reply | Threaded
Open this post in threaded view
|

Re: Volume and Center of mass

runsun
Looks nice ! I for one is very interested in this.

btw can you provide some references to the algorithm you use ? I cannot image how this could be done with the current openscad. So there must be something worth my learning.
$ Runsun Pan, PhD
$ libs: scadx, doctest, faces(git), offline doc(git), runscad.py(2,git), editor of choice: CudaText ( OpenSCAD lexer); $ Tips; $ Snippets
Reply | Threaded
Open this post in threaded view
|

Re: Volume and Center of mass

doug.moen
Hi Runsun. I'm pretty sure that Blobule implemented this in C++.

On 3 January 2016 at 11:43, runsun <[hidden email]> wrote:
Looks nice ! I for one is very interested in this.

btw can you provide some references to the algorithm you use ? I cannot
image how this could be done with the current openscad. So there must be
something worth my learning.



-----

$  Runsun Pan, PhD

$ libs:

doctest ,

faces ( git ),

offline doc ( git ),

runscad.py( 1 , 2 , git ),


synwrite( 1 , 2 );



 $ tips:

hash( 1 , 2 ),

sweep ,

var( 1 , 2 ),

lerp ,

animGif ,

precision( 1 , 2 ),

xl-control








--
View this message in context: http://forum.openscad.org/Volume-and-Center-of-mass-tp15421p15433.html
Sent from the OpenSCAD mailing list archive at Nabble.com.

_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org




_______________________________________________
OpenSCAD mailing list
[hidden email]
http://lists.openscad.org/mailman/listinfo/discuss_lists.openscad.org
Reply | Threaded
Open this post in threaded view
|

Re: Volume and Center of mass

blobule
Hi,
Yes indeed... the volume/centroid code is in C++, although sometimes the heavily templated cgal library makes it look like a totally different language... :-)

What is done in C++ is only the basic volume/centroid computation.
Once you have that information, you can make the OpenSCAD code find by itself the parameters that will make an object the exact volume you want. I do this using binary search.

For example, you can have a module which makes a bottle with one parameter n for its general size:

module inside(n=50) {
    hull() {
        sphere(r=20);
        translate([0,0,n]) cylinder(r=10,h=10);
    }
}

module wall() { translate([0,0,-3.02]) cylinder(r=3,h=3); }

module bottle() {
    difference() {
        minkowski() { children(); wall(); }
        children();
    }
}

By varying the parameter, you get bottles of different shapes. For example:
bottle() inside(20);

bottle() inside(50);



The first has a volume of 40.0ml, and the second one 60.9ml. To compute the volume (in ml), I use:
probe(volume=true) { inside(20); echo(volume/1000); }

What is the parameter needed to get a volume of exactly 50ml? It's hard to predict because the geometry is complex.
You can make a module that will find the parameter and make the bottle of the correct size using binary search over the parameter space. This obviously implies a monotonic relation between the parameter and the volume.
See the solve() module :

module solve(iter=0,min=20,max=50,target=50*1000) {
    m=(min+max)/2; // guess the parameter
    probe(volume=true) {
        inside(m); // we measure the inside
        echo("parameter=",m," and volume=",volume);
        if( iter==0 ) {
            // we are done searching!
            echo("FINAL bottle parameter=",m," volume=",volume);
            bottle() inside(m); // the final bottle
        }else{
            // try again, with a reduced interval for the search
            if( volume>target ) solve(iter-1,min,m,target);
            else solve(iter-1,m,max,target);
        }
    }
}

min/max are the interval where we want to search for the parameter, target is the goal volume.
iter is the number of tries we want to make. Each try reduce the interval by two, so you rarely need more than 10 iterations.

So now you can ask for a 50ml bottle using this:

solve(10,20,50,50*1000);
The parameter found for 50ml is 34.546. Here are the 3 bottles side by side:



Once you do binary search, it becomes possible to specify an object with parameters that are more natural to the user (like volume in this case). Here is a collection of bottles/glass, with specified volumes solved by OpenSCAD.



Reply | Threaded
Open this post in threaded view
|

Re: Volume and Center of mass

Neon22
I think its fantastic.
I also really like the idea of extending probe() to be able to do other things with the geometry. E.g.
- slice object using projection() at various values and export as svgs
- get a boolean result if it intersects with a second object
very nice implementation.
Reply | Threaded
Open this post in threaded view
|

Re: Volume and Center of mass

joao.quezada
This post has NOT been accepted by the mailing list yet.
I agree! very nice work.

Please publish :)
Reply | Threaded
Open this post in threaded view
|

Re: Volume and Center of mass

MichaelAtOz
Administrator
joao.quezada wrote
I agree! very nice work.

Please publish :)
Welcome to the forum. Your post is still flagged as "This post has NOT been accepted by the mailing list yet", so nobody gets it unless they look.
You need to subscribe to the mailing list, and respond to the registration email.
Admin - email* me if you need anything,
or if I've done something stupid...
* click on my MichaelAtOz label, there is a link to email me.

Unless specifically shown otherwise above, my contribution is in the Public Domain; to the extent possible under law, I have waived all copyright and related or neighbouring rights to this work.
Obviously inclusion of works of previous authors is not included in the above.


The TPP is no simple “trade agreement.” Fight it! http://www.ourfairdeal.org/ time is running out!