POV-Ray : Newsgroups : povray.general : Object "center of mass" macro Server Time
30 Jul 2024 10:24:53 EDT (-0400)
  Object "center of mass" macro (Message 6 to 15 of 15)  
<<< Previous 5 Messages Goto Initial 10 Messages
From: waggy
Subject: Re: Object "center of mass" macro
Date: 5 Sep 2009 18:40:00
Message: <web.4aa2e7c2708de865f99d05c80@news.povray.org>
CShake wrote:

> True. I picked the 'orientation' of what direction to shoot the rays as
> somewhat arbitrary. For most objects it should work fine, but I am aware
> specifically that an image-based heightfield (since it normally rises up
> from the x-z plane) will create a large number of intersections, and
> would be more efficient to shoot along y. Considering the likelihood of
> this sort of comparison, I may actually switch it to shooting along y,
> since for 'normal' object it wouldn't make much of a difference.

It might be a good idea to do that.  It may be worthwhile putting into the usage
notes that the following construction works fine to rotate the object just for
use with this macro.  (I checked it.)

FindObjectCenter(object{BoxObj rotate<1,2,3>})

> I did have in mind a few different ways of shooting rays, specifically
> doing a sort of spherical shoot where theta and phi are the control
> variables, but evenly distributing the rays around the surface (and
> finding the volume of each 'chunk') would be a little more complicated.
> At least this method works in k*n^2, where k is something like the
> number of voids in the object, which is slightly more optimized than n^3
> in the case of most simpler objects (CSG, etc). I thought about trying
> to use an adaptive sampling method, but the extra code would be
> significant (and I don't have a good handle on how to do it yet, so it
> would involve more research too).
> It could be helpful to do a sort of basic test if the object is a
> primitive, and then use the appropriate mathematical formula, but the
> amount of time you'd run into that 'in the wild' would be nearly 0.

Initially I thought it might be worthwhile to keep track of how many times the
#while(more_sections... loop is iterated for each ray, then give up and use
another method if the number of iterations exceeds 10 or 100 times the number
of divisions.  But I agree, it would probably be better to just post a
different method and let the scene designer choose which one to use.  Yours is
likely to be superior for 99 out of a hundred uses, but it didn't look too
difficult to provide an alternative for that poor slob with the oddball case.

The main reason I considered writing an alternative is that I like to use noise
functions to make rock-shaped isosurface objects.  Although the ones I usually
need are simple bumpy rocks (so I'll end up using your macro), I seem to
remember getting the idea after seeing rather complex asteroid-like or volcanic
ejecta-shaped objects and thought someone may need to be able to determine their
masses for some kind of animation...

I got this alternative version working, and as expected it is much slower and
less accurate than yours for simple shapes (with a given number of x and y
divisions, and a similar number of z divisions for my version).  I'll test it
with more gnarly objects, see if I can find some cases where the alternative
gives better performance, and post the results and the finished code here.

Thanks for providing your test objects.  Since I make so many mistakes, I always
prefer to verify known working cases.  :)

Also, thank you for letting me start with your nice, clean code.  It really
helped to get it working quickly.  (Proper attribution is given in the code
comments, of course.)

~David


Post a reply to this message

From: Alain
Subject: Re: Object "center of mass" macro
Date: 5 Sep 2009 18:48:15
Message: <4aa2eaaf$1@news.povray.org>


> True. I picked the 'orientation' of what direction to shoot the rays as 
> somewhat arbitrary. For most objects it should work fine, but I am aware 
> specifically that an image-based heightfield (since it normally rises up 
> from the x-z plane) will create a large number of intersections, and 
> would be more efficient to shoot along y. Considering the likelihood of 
> this sort of comparison, I may actually switch it to shooting along y, 
> since for 'normal' object it wouldn't make much of a difference.
> 
The orientation of the tests can be passed as a parameter,somewhat like 
the direction vector used by trace, or a global variable.
In the later case, you can have a default orientation that is used if 
the user don't set it.

That way, if the object been tested have a special shape, the direction 
can be chosen to be more effecient. After all, not all hightfields are 
used horizontaly.


Alain


Post a reply to this message

From: clipka
Subject: Re: Object "center of mass" macro
Date: 6 Sep 2009 03:43:26
Message: <4aa3681e$1@news.povray.org>
CShake schrieb:
> I did have in mind a few different ways of shooting rays, specifically 
> doing a sort of spherical shoot where theta and phi are the control 
> variables, but evenly distributing the rays around the surface (and 
> finding the volume of each 'chunk') would be a little more complicated. 

You could start from a platonic polyhedron as an approximation - a cube 
would be sufficiently "spherical" for this purpose I guess :-)


Post a reply to this message

From: CShake
Subject: Re: Object "center of mass" macro
Date: 6 Sep 2009 23:03:18
Message: <4aa477f6$1@news.povray.org>
waggy wrote:
> I got this alternative version working, and as expected it is much slower and
> less accurate than yours for simple shapes (with a given number of x and y
> divisions, and a similar number of z divisions for my version).  I'll test it
> with more gnarly objects, see if I can find some cases where the alternative
> gives better performance, and post the results and the finished code here.
> 
> Thanks for providing your test objects.  Since I make so many mistakes, I always
> prefer to verify known working cases.  :)

I've now written my moment of inertia macro, and couldn't find an 
optimized way to do it in n^2, so here it is in n^3. My issue here is 
that I'm getting the wrong values for the moments for everything but a 
box, and I can't figure out why. Spheres and Toruses are giving almost 
exactly half the official value. This macro would have even less of an 
audience than my last, but again any math help would be appreciated.
I need to read up more on how to use moment of inertial tensors for 
calculating the moment about an arbitrary axis, and I left my dynamics 
textbooks at home this semester...
Also, this macro requires the center of mass to already be computed.

Chris

(I'm interchanging volume and mass here in the terminology, sorry. It 
will be better once density is involved.)

// Macro, description, and test values:

#declare X_Resolution=20;
#declare Y_Resolution=20;
#declare Z_Resolution=20;
// Finds the moment of inertia for an arbitrary object.
// Return value is <Ix,Iy,Iz> where each is the moment around that axis 
where it passes
// through the center of mass of the object, allowing for "easy" 
calculation of any moment
// with the parallel axis theorem
#macro FindMomentsOfInertia(Object_Identifier, Center_Of_Mass)
   // Set up reference vars
   #local maxcorner = max_extent(Object_Identifier);
   #local mincorner = min_extent(Object_Identifier);
   #local max_x = max(maxcorner.x,mincorner.x);
   #local min_x = min(maxcorner.x,mincorner.x);
   #local max_y = max(maxcorner.y,mincorner.y);
   #local min_y = min(maxcorner.y,mincorner.y);
   #local max_z = max(maxcorner.z,mincorner.z);
   #local min_z = min(maxcorner.z,mincorner.z);
   #local dx = abs(max_x-min_x)/X_Resolution;
   #local dy = abs(max_y-min_y)/Y_Resolution;
   #local dz = abs(max_z-min_z)/Z_Resolution;
   #local dv = dx*dy*dz;
   #local Moments = <0,0,0>;
   #local Volume = 0;
   // Go through entire 3D matrix
   #local curr_x = min_x+dx/2;
   #while (curr_x < max_x)
     #local curr_y = min_y+dy/2;
     #while (curr_y < max_y)
       #local curr_z = min_z+dz/2;
       #while (curr_z < max_z)
         #if(inside(Object_Identifier,<curr_x,curr_y,curr_z>))
           // I = sum(m*r^2) where m is each point mass, r is distance 
to axis
           #local Volume = Volume+dv;
           #local Moments = Moments+dv*<pow(abs(Center_Of_Mass.x-curr_x),2),
                                        pow(abs(Center_Of_Mass.y-curr_y),2),
 
pow(abs(Center_Of_Mass.z-curr_z),2)>;
         #end
         #local curr_z = curr_z+dz;
       #end
       #local curr_y = curr_y+dy;
     #end
     #local curr_x = curr_x+dx;
   #end
   //(Moments)
   DebugVector3("Calculated moments",Moments)
   #debug concat("Calculated volume: ",str(Volume,0,2),"\n")
#end

#declare BoxObj=box{-1,1}
#declare SphereObj=sphere{0,1.5}
#declare TorusObj=torus{1,0.5}

#debug "Box: \n"
#debug concat("Real moments: ",str(1/12*4*(pow(2,2)+pow(2,2)),0,2),"\n")
#debug concat("Real volume: ",str(pow(2,3),0,2),"\n")
FindMomentsOfInertia(BoxObj,<0,0,0>)

#debug "Sphere: \n"
#local sphereMass = 4/3*pi*pow(1.5,3);
#debug concat("Real moments: ",str(2/5*sphereMass*pow(1.5,2),0,2),"\n")
#debug concat("Real volume: ",str(sphereMass,0,2),"\n")
FindMomentsOfInertia(SphereObj,<0,0,0>)

#debug "Torus: \n"
#local torusMass = 2*pow(pi,2)*1*pow(0.5,2);
#debug concat("Real moments: 
",str(torusMass*(pow(1,2)+3/4*pow(0.5,2)),0,2),0,2),"\n")
#debug concat("Real volume: ",str(torusMass,0,2),"\n")
FindMomentsOfInertia(TorusObj,<0,0,0>)


Post a reply to this message

From: CShake
Subject: Re: Object "center of mass" macro
Date: 6 Sep 2009 23:07:06
Message: <4aa478da$1@news.povray.org>
Alain wrote:
> The orientation of the tests can be passed as a parameter,somewhat like 
> the direction vector used by trace, or a global variable.
> In the later case, you can have a default orientation that is used if 
> the user don't set it.
> 
> That way, if the object been tested have a special shape, the direction 
> can be chosen to be more effecient. After all, not all hightfields are 
> used horizontaly.
> 
> Alain

Good idea, I'll look at implementing that. It will be a lot more work to 
make it an arbitrary axis (with how I'm using the grid from one side of 
the bounding box), but I figure that a choice of x,y,z should be enough 
for most uses. Anything more and it's just as easy to rotate the object, 
call the macro, then rotate it back and transform the returned location.

Chrsi


Post a reply to this message

From: Alain
Subject: Re: Object "center of mass" macro
Date: 7 Sep 2009 14:40:44
Message: <4aa553ac$1@news.povray.org>

> Alain wrote:
>> The orientation of the tests can be passed as a parameter,somewhat 
>> like the direction vector used by trace, or a global variable.
>> In the later case, you can have a default orientation that is used if 
>> the user don't set it.
>>
>> That way, if the object been tested have a special shape, the 
>> direction can be chosen to be more effecient. After all, not all 
>> hightfields are used horizontaly.
>>
>> Alain
> 
> Good idea, I'll look at implementing that. It will be a lot more work to 
> make it an arbitrary axis (with how I'm using the grid from one side of 
> the bounding box), but I figure that a choice of x,y,z should be enough 
> for most uses. Anything more and it's just as easy to rotate the object, 
> call the macro, then rotate it back and transform the returned location.
> 
> Chrsi
I agree, over 99.999% of the time, only changing the axis used should be 
all that's needed.


Alain


Post a reply to this message

From: waggy
Subject: Re: Object "center of mass" macro
Date: 7 Sep 2009 15:00:00
Message: <web.4aa557b7708de865f99d05c80@news.povray.org>
CShake wrote:
> waggy wrote:
> I've now written my moment of inertia macro, and couldn't find an
> optimized way to do it in n^2, so here it is in n^3. My issue here is
> that I'm getting the wrong values for the moments for everything but a
> box, and I can't figure out why. Spheres and Toruses are giving almost
> exactly half the official value. This macro would have even less of an
> audience than my last, but again any math help would be appreciated.
> I need to read up more on how to use moment of inertial tensors for
> calculating the moment about an arbitrary axis, and I left my dynamics
> textbooks at home this semester...
> Also, this macro requires the center of mass to already be computed.
>
> Chris
>
> (I'm interchanging volume and mass here in the terminology, sorry. It
> will be better once density is involved.)

This is very much right up my alley.  (I'm currently working on a research grant
to calculate the stress intensity factor around a crack tip using a
complex-perturbation numerical integration technique.)  I apologize I probably
won't have time until later this week to help with the math and look at your
factor-of-two error (if you haven't already found the problem by then).

I would like to see both your original kn^2 macro and an n^3 macro calculating
useful inertial and geometric properties of an arbitrary object.  (I used
intersecting open xy planes and trace() rather than inside(), for my n^3 macro.
 I'll test both later to see which is better for the pathological cases that
need to use an n^3 method.)

From what you've posted so far, it looks like a good approach.  I think you may
end up calculating the volume, center of mass, and inertial tensor with respect
to the origin all together.  Then, after the loops, find the stress tensor with
respect to the center of mass.  Now you can find the directions of the
principle axes by finding the transformation needed to diagonalize the stress
tensor.  As you're already doing, you should be able to leave factoring in the
density until the end (assuming the density is constant).

As far as using a different subdivision axis, I agree that you'll find it far
easier to rotate the object by the inverse of the desired axis rotation, use
the loops as they are, then transform the coordinate results.

~David


Post a reply to this message

From: CShake
Subject: Re: Object "center of mass" macro
Date: 7 Sep 2009 23:42:20
Message: <4aa5d29c$1@news.povray.org>
Alain wrote:
> The orientation of the tests can be passed as a parameter,somewhat like 
> the direction vector used by trace, or a global variable.
> In the later case, you can have a default orientation that is used if 
> the user don't set it.
> 
> That way, if the object been tested have a special shape, the direction 
> can be chosen to be more effecient. After all, not all hightfields are 
> used horizontaly.
> 
> 
> Alain

Updated macro with your suggestion implemented uploaded to p.t.scene-files
It will accept any of the three primary axes, and will default to y if 
the passed parameter isn't at least mostly along one of the axes.

I haven't done a study on very complex surfaces, so I can't say for sure 
how accurate it will be vs. iterations for a fractal-based form or even 
a spikey image heightfield, but I assume that any protrusions small 
enough to be missed by the tracing will not affect the center location 
too much, especially as the grid resolution is increased.

Chris


Post a reply to this message

From: Alain
Subject: Re: Object "center of mass" macro
Date: 8 Sep 2009 12:15:07
Message: <4aa6830b$1@news.povray.org>

> Alain wrote:
>> The orientation of the tests can be passed as a parameter,somewhat 
>> like the direction vector used by trace, or a global variable.
>> In the later case, you can have a default orientation that is used if 
>> the user don't set it.
>>
>> That way, if the object been tested have a special shape, the 
>> direction can be chosen to be more effecient. After all, not all 
>> hightfields are used horizontaly.
>>
>>
>> Alain
> 
> Updated macro with your suggestion implemented uploaded to p.t.scene-files
> It will accept any of the three primary axes, and will default to y if 
> the passed parameter isn't at least mostly along one of the axes.
> 
> I haven't done a study on very complex surfaces, so I can't say for sure 
> how accurate it will be vs. iterations for a fractal-based form or even 
> a spikey image heightfield, but I assume that any protrusions small 
> enough to be missed by the tracing will not affect the center location 
> too much, especially as the grid resolution is increased.
> 
> Chris

For a high frequency, high noise object's surface, the spikes that you 
miss are frequently compensated by the pits that you miss.

Alain


Post a reply to this message

From: CShake
Subject: Re: Object "center of mass" macro
Date: 10 Sep 2009 18:10:14
Message: <4aa97946$1@news.povray.org>
waggy wrote:
> This is very much right up my alley.  (I'm currently working on a research grant
> to calculate the stress intensity factor around a crack tip using a
> complex-perturbation numerical integration technique.)  I apologize I probably
> won't have time until later this week to help with the math and look at your
> factor-of-two error (if you haven't already found the problem by then).
Sounds like fun research, I'm just starting on my Ph.D. in Mechanical 
Engr, hoping to work on either simulation or outright building of 
non-industrial robotics.

As for the error in the previous macro:
Well, I'm not sure exactly where it came from in the macro I posted 
there, but I redid it to make a full moment tensor and the primary 
moments seemed to double. Then I realized that my original calculated 
box moment was wrong, my volume was half what it should be.

> I would like to see both your original kn^2 macro and an n^3 macro calculating
> useful inertial and geometric properties of an arbitrary object.  (I used
> intersecting open xy planes and trace() rather than inside(), for my n^3 macro.
>  I'll test both later to see which is better for the pathological cases that
> need to use an n^3 method.)
Well, here's my 'completed' "find everything in one pass" macro that 
works in n^3, I figure that it's gotten big enough that I should attach 
it. I know it isn't a binary group here, but it's only a small pov file.
The problem with this is that it isn't nearly as optimized as the 
previous kn^2 CoM finder, and the mesh needs to be pretty small to get 
good accuracy. Fortunately, a decent approximation should be good enough 
for most uses in pov, and that doesn't take too long.

> From what you've posted so far, it looks like a good approach.  I think you may
> end up calculating the volume, center of mass, and inertial tensor with respect
> to the origin all together.  Then, after the loops, find the stress tensor with
> respect to the center of mass.  Now you can find the directions of the
> principle axes by finding the transformation needed to diagonalize the stress
> tensor.  As you're already doing, you should be able to leave factoring in the
> density until the end (assuming the density is constant).
Yup, this one does all that. Thanks for the idea, I just had to look up 
tensor transformations.

> As far as using a different subdivision axis, I agree that you'll find it far
> easier to rotate the object by the inverse of the desired axis rotation, use
> the loops as they are, then transform the coordinate results.
The 'optimized' kn^2 macro for just center of mass has been posted to 
p.t.scene-files, and the subdivision axis can be specified to be x, y, or z.

Now to write a macro that finds the location and normal direction of the 
contact force for arbitrary object collisions...

Chris


Post a reply to this message


Attachments:
Download 'findobjectproperties.pov.txt' (6 KB)

<<< Previous 5 Messages Goto Initial 10 Messages

Copyright 2003-2023 Persistence of Vision Raytracer Pty. Ltd.