[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