Hello Barnaclau,
Based on the clarification, I will outline the material based on the
structure of the loop. Each of the key formulas will be represented in
a form that should go into Flash without any problems [you may have to
change sin to Math.sin; I'm not sure]. I have also pointed out a few
places where approximations are used that should be invisible to the
user viewing the Flash animation.
Set Up Initial Conditions:
For all cases, the object has mass M, and rotational inertia I.
For a 1D example, I will use
X - position along the X axis
XS - speed along the X axis
XA - acceleration along the X axis
For this and all subsequent items, this refers to the "Center of
Mass", for a rectangle, the center of it. The velocity V is equal to
XS with the same magnitude.
Going to two dimensions, add Y, YS, and YA to refer to the position,
speed, and acceleration along the Y axis. The velocity V then refers
to the pair of values (XS,YS) with VM magnitude sqrt(XS*XS+YS*YS).
Going to three dimensions, add Z, ZS, and ZA to refer to the position,
speed, and acceleration along the Z axis. The velocity V then refers
to the three values (XS,YS,ZS) with VM magnitude
sqrt(XS*XS+YS*YS+ZS*ZS).
From the second paper, the author refers to upper / lower case omega
as the rotation (relative to the axes) and rotational motion and alpha
as the rotational acceleration. I will use:
R - rotation relative to the axes
RV - rotational (or angular) velocity (in cycles per second)
RA - rotational acceleration
In the 2D case, a single value is sufficient. In the 3D case, you
would have a rotational value around each axis (roll, pitch, yaw).
I will refer to ML as the linear momentum and MR as the rotational
momentum. Note that linear momentum is along the path taken by the
object and rotational is around the center of mass.
I will also refer to T as the current time and DT as the delta time.
If there is more than one object being referred to, I will add a
number to the end of the name; as an alternative in your code, use one
or more Array objects to store the values.
You may use longer names (e.g, XPOS, XSPEED) if you find it necessary
to keep the names unique in your application.
While Simulating Loop:
Use any appropriate condition (e.g., user action) to exit the loop and
stop motion of the object(s).
Compute Delta Time:
From the explanation of the third paper, he suggests a method to
determine the time of collision and adjust the delta time
appropriately. I suggest using a small, fixed DT value instead due to
relative errors in integration and because I expect the result will be
displayed (and not analyzed in detail).
Since you are using Flash, and I expect you to updating a display,
choose a nominal DT value (or make it adjustable by the user). For
comparison, a flight simulator might use DT=1/30 seconds (or 30 Hz) to
match with a visual system. Depending on the desktop PC performance,
you may need to update more slowly.
Calculate All Forces and Moments:
For friction, the force is generally proportional to the velocity of
the object. In 1D, this can be calculated as:
F = - KL * XS * DT
where KL refers to the drag coefficient for linear motion, XS is the
speed (1D velocity), and DT is the delta time.
Note - this, along with a number of other formulas represented in the
paper (and this answer) is an approximation. As a test, I computed one
second of drag with DT=1, 0.1, and 0.01, for that equation with K=.1,
initial XS=10 and have results (sum of F up to T=1 second):
DT=1 -- 1.00000000
DT=0.1 -- 0.95617925
DT=0.01 -- 0.95207853
You have less error from the "exact" value as DT decreases. A small
percentage error like these should not be visible to the viewer.
For 2D, you have
F = - K * VM * DT
which is "the same" as above, but affects XS and YS proportional to
the magnitude in each axis. [can be a single value here, and is split
in the next section]
Note - you can also compute friction for rotation (torque) in a
similar manner. In that case
F = -KR * RV * DT
where KR is the drag coefficient (for rotational motion).
Another force you may want to consider is gravity. Basically,
F = M * G * DT
where M is the mass of the object and G is the acceleration of
gravity. Note that G only operates on a single axis.
Add to these forces, any additional forces that are in your
system. For example, if you simulate a rocket, it would have thrust
(force) along the axis of the motor(s) and those would then be
computed as well. If you have a "guidance system", that would activate
thrusters to add torque to the calculations.
The linear momentum ML, is calculated by
ML = M * V
where M is the mass of the object and V the velocity.
The rotational moementum MR, is calculated by
MR = I * RV
where I is the rotational inertia and RV is the rotational velocity.
Yes - these are really that simple. You can certainly get a lot more
complicated, for example varying K by the orientation of the object,
but let's keep it simple for now.
Compute Linear and Angular Accelerations:
We know both the linear forces and the mass. We know the rotational
forces and inertia. With these we can compute both the linear and
rotational accelerations.
Knowing F = M * A, we get
A = F / M
In the 1D case, this is a single calculation. In the 2D case, the
force is a vector with two components, affecting X and Y. Working
through the friction example,
F = - K * VM * DT
is the magnitude of the friction, along V, made up of (XS,
YS). I will split that force into the X and Y components as:
FX = -K * VM / ( M * XS )
FY = -K * VM / ( M * YS )
Yes - if you have the angles, you can use cosine to calculate the X
part and sine to calculate the Y part, but this is a lot simpler.
In a simular matter, rotational acceleration due to friction can be
computed as
RA = F / I
and the same kind of formulas are used to compute the portion in each
direction.
For both the linear and rotational accelerations, you can add them
(add the X, Y, and Z components) to get the resulting accelerations.
Integrate Accelerations and Velocities:
For linear motion along each axis, you use
XA = XA + sum of linear force accelerations * DT
XS = XS + XA * DT
to compute the new values of acceleration and speed along that
axis. Don't forget to compute the new velocity magnitude and momentum
values (for the next cycle).
For angular motion along each axis, you use
RA = RA + sum of rotational force accelerations * DT
RV = RV + RA * DT
to compute the new values of rotational acceleration and
velocity. Again, update the new velocity magnitude and momentum
values.
Collisions:
The paper suggests subdividing the time difference (DT) if two objects
collide to get the "right" time. To keep it simple, I would recommend
just using the relative position of the two centers of mass at the new
time to compute the results of the collision. The reason for this is
the person can't see the difference between this solution and a more
complicated scheme if DT is relatively small.
First, we have to compute the relative velocities. Basically
V12 = V1 - V2
which is a single value for the 1D case and
XV12 = X1 - X2
YV12 = Y1 - Y2
for the 2D case. Note that if object 1 is moving and object 2 is
fixed, this is simply the velocity of object 1.
Second, we have to compute the "normal vector" N. N is the line
perpendicular to the surface being hit.
If the object is hitting a flat, level surface, N will point up
(positive Y in 2D).
For a pair of circles hitting, N is the vector between the two centers
of mass.
For the 2D rectangle example, N will vary by rotation (R) of the
rectangle and depend on which surface is hit. For example, rotate the
rectangle 45 degrees so it looks something like <> and the vector will
be one of:
N = (cos(R), sin(R)) - right, up facing surface
N = (-cos(R), -sin(R)) - left, down facing surface
N = (sin(R), -cos(R)) - right, down facing surface
N = (-sin(R), cos(R)) - left, up facing surface
for NX and NY, the X and Y parts of the normal vector N
respectively. You use similar values for the perpendicular vectors
used in the rotational calculations below.
The impulse is computed with that nasty equation which I will try to
simplify a couple different ways. For object 1 hitting a flat, level
surface object 2:
J = (-(1+E)*Y1) / ( 1 / M1)
or
J = -(1+E)*Y1*M1
Note that Y1 is negative, so J is positive and since N is up, the
impulse is up (does not affect X velocity). The new velocity will be
V1 = V1 + (J / M1)
where:
XS1 is unchanged
YS1 = -YS1
[trust me - if you do the math, that is the result] This is the
expected result, the object hitting the flat surface will bounce up.
Ignoring rotation, the equation for J uses a dot product which for the
2D case is simply X1*X2 + Y1*Y2. So J is just a single value, in 2D
computed as:
J = (-(1+E)*(XV12*NX+YV12*NY)) / (NX*NX+NY*NY)*((1/M1)+(1/M2))
So, the more general solution, ignoring rotation, the new velocities
are:
V1 = V1 + (J / M1) * N
V2 = V2 - (J / M2) * N
Note that V1, V2, and N are all vectors (in 2D, two values each).
Taking rotation into account requires a change in J to be:
J = (-(1+E)*(XV12*NX+YV12*NY)) / ((NX*NX+NY*NY)*((1/M1)+(1/M2))
+((XR1PP*NX+YR1PP*NY)*(XR1PP*NX+YR1PP*NY)/I1)
+((XR2PP*NX+YR2PP*NY)*(XR2PP*NX+YR2PP*NY)/I2))
where XR1PP is the X part of vector perpendicular to the rotation of
object 1, YR1PP is the Y part of that same vector. XR2PP and YR2PP are
the similar values for object 2. I1 and I2 are the inertia for objects
1 and 2. Yech. I am not quite sure this is completely correct - it
does not seem to take into account the rotational momentum, but this
is what the paper says is correct (expanded into variables).
For the complete solution, the new velocities are:
V1 = V1 + (J / M1) * N
V2 = V2 - (J / M2) * N
(these are two values for X and Y as computed above)
RV1 = RV1 + ((XR1PP*J*XN+YR1PP*J*YN)/I1)
RV2 = RV2 - ((XR1PP*J*XN+YR1PP*J*YN)/I1)
Whew!
Update Position and Velocities:
The position update is straight forward:
X = X + XV*DT
Y = Y + YV*DT
R = R + RV*DT
The velocities should already be updated (from previous steps) but may
be required in the original loop due to the step adjustments.
Draw the Objects:
Use the Flash routines to draw the objects in the new positions.
Wrap Up:
That should cover all major aspects of the simulation of motion for a
single or group of objects taking into account motion, rotation, and
friction. I described some cases in 1D as well as some other
simplifications and provided the additional formulas needed for 2D,
and by similar means the 3D solution.
After reading this over again, I may have jumped to some of the
results without sufficient explanation. If some part of this answer is
unclear to you, don't hesitate to make a clarification request. I
would be glad to expand on the answer as needed.
--Maniac |