Doing it the other way 'round:
Inverse Kinematics
by Thomas 'ThamasTah' van Dijk
Please note, that it is recommended that
you read my Skeletal Modelling tutorial.
Introduction
In this tutorial, we'll have a look at
applying a force to the bones. Later on,
this involves some Inverse Kinematics, I
think... ;)
This tutorial just discusses the theory
behind it. No code :(
Theory
Okay, here we go then!
Applying Force
Forces: we describe them using a vector
-- angle and length (which in this case is
power). New in this version of the Skeletal
Modelling system is cVelocity, which is the
angular velocity. In other words: how much
we need to increment the angle each time
unit.
We'll start with just one bone. (I only
account for forces applied to the ending
point of a bone.)
I'll use the following: F(u) is the force
applied by the user and cVel is the angular
velocity added to the bone. We'll treat bone
as a vector.
cVel = the component of F(u) perpendicular
to bone. Sounds confusing? It actually makes
sense (to me ;). I'll illustrate the
application of a force using three examples:



That's all there's to it. (I
say that a lot, don't I...)
Influencing the Parent
The above should be correct. Here is
where the experimentation comes in. As a
first try: if a force is applied to a bone,
it applies it to its parent (which applies
it to its parent, etc.) This is illustrated
below with two bones.
Note:
- radius of the green circle = | F(u)
|,
- | F(u) | = | F(bone1) |,
- F(u) is parallel to F(bone1).



I haven't tried this, but I
imagine this is not how it's supposed to be:
the parent would be equally influenced. No
good!
A possible solution is to
use a fraction of the length of F(u), e.g.
| F(bone1) | = 0.5 * | F(u) |
or, better:
| F(bone1) | = stiffness * | F(u) |
where stiffness is a Single/Double
between 0 and 1.
This is getting better, but still not quite
it...
The angle between bone1 (parent) and
bone2 (child) also influences the magnitude
of the force applied to bone1. If bone1 and
bone2 are perpendicular, the force on bone1
is at its max, whereas it is at its minimum
when they are parallel.
Well, we'll just add another fraction.
We calculate the bone1-component of bone2 (a
projection of bone2 on bone1) and devide
that by the length of bone2. That will give
us a value between 0 and 1. It will be 1
when b1 and b2 are parallel, which is the
wrong way 'round. Fixing that, we get:
,
or perhaps it should be
,
so we won't multiply by 0 if they are
parallel, but by 0.5: the parent always gets
a force, just not as big as the child.
You may want to experiment with other values
for '0.5', it's just a value I chose. Go
with what looks best.
Note that the above formula can prolly be
optimized a lot if you use goneometrics:
calculate the angle between b1 and b2 (you
already know that in the Skeletal Modelling
example) and then use the absolute value of
the [sine or cosine, haven't thought about
it yet] of that angle. That should give the
same result, shouldn't it?
As a final note: this will probably
conflict with any animation code. Anybody
got ideas on a fix for that?
That's all, folks: happy kinemation!
Conclusion
I haven't the time to code this stuff,
but I suppose it will work.
Thomas 'ThamasTah' van Dijk
paxdev@hotmail.com
dec 3 2000 |