[ODE] Approximate Hydrodynamic Forces

David Whittaker david at csworkbench.com
Mon Apr 14 21:26:02 2003


I wrote up a fairly lengthy discussion of the concept of finding the area
of the 'silhouette' or 2 dimensional cross-sectional area of the basic
geoms as viewed from the direction of their velocity in
http://q12.org/pipermail/ode/2003-April/004101.html .

To go from your direction, i.e. to get the velocity that each side of the
cube is going in the direction of it's normal, you can use a fairly
similar concept (which may actually turn out to be faster).

First, how to get the normals for the faces of the cube:  Note that the
normals for the faces are the bodies x, y, and z axes.  Therefore, the
normal for those faces are the first, second, and third row of the R
matrix.  They will already be normalized and in global coordinates, so
that's a couple of computations knocked off my method right there.

Now you need the magnitude of the projection of the velocity in the
direction parallel to the x, y, and z axes.  This is nothing more than a
dot product.  Dot your velocity with each of the x, y, and z axes and you
have the magnitude of the velocity (i.e. the speed) in those directions.

For the box:

    ____
   /    /
  /____/| h
 |    | /
 |____|/ l
   w

 z  y
 | /
 |/___x

Which I beleive is the way ODE's box sides are laid out, your final
calculation would be:

const dReal *lvel = dBodyGetLinearVelocity(body);
const dReal *R = dBodyGetRotation(body);
dReal ss[3];
dGeomBoxGetLengths(geom, ss);
dReal l = ss[0], w = ss[1], h = ss[2];
dReal side = l * h * (R[0]*lvel[0] + R[1]*lvel[1] + R[2]*lvel[2]);
dReal front = w * h * (R[4]*lvel[0] + R[5]*lvel[1] + R[6]*lvel[2]);
dReal top = w * l * (R[8]*lvel[0] + R[9]*lvel[1] + R[10]*lvel[2]);

//either this......
dReal temp = -side*scale;
dBodyAddForce(body, temp*R[0], temp*R[1], temp*R[2]);
temp = -front*scale;
dBodyAddForce(body, temp*R[4], temp*R[5], temp*R[6]);
temp = -top*scale;
dBodyAddForce(body, temp*R[8], temp*R[9], temp*R[10]);

//or this is probably close enough, and will save a few clocks:
dReal temp = -scale*(side+front+top);
dBodyAddForce(body, temp*lvel[0], temp*lvel[1], temp*lvel[2]);

The scale factor represents the viscosity of the fluid you are moving
through, so this same method could be used to simulate air with a low
scale or water with a higher scale.  Man, I wish I had thought of this
method before I wrote that one up.  Hope it works for you.

David

> Hi All,
>
> I want to be able to get the speed that each face of a cube, say, is
> moving  along its own normal.  So I can apply an opposing force to each
> face  dependent on its area.  Is there an easy way to get this info?
>
> I am hoping to approximate hydrodynamic forces, so I can evolve a
> swimming  animat.
>
> Cheers,
>
> Ander
>
>
>
>
> _________________________________________________________________
> MSN Instant Messenger now available on Australian mobile phones. Go to
> http://ninemsn.com.au/mobilecentral/hotmail_messenger.asp
>
> _______________________________________________
> ODE mailing list
> ODE@q12.org
> http://q12.org/mailman/listinfo/ode