Details of Kinetic Functions in BodyBuilder

reactionS = REFER(reactionR,pointP)

This function ëmovesí the reference point for the given reaction reactionR, to create a
new reactionS. The Force component of the reaction remains unchanged. The moment is changed by adding the additional moment caused by the movement of the reference point. As the reference point moves away from the line of application of the force, the moment increases. This is found from the cross product of the point movement and the force.

NewMoment = OldMoment + (OldPoint - NewPoint) x Force;

Reaction = ForcePlate1

to get force plate data gives the closest single sample from the analogue data (which is sampled at a higher rate than the marker data) for the given force plate. There is no attempt to take a mean of a period of data.

ReactionR = REACTION(segmentS)

The reaction calculation needs to add all the reactions acting on the given segment, making the assumption that only one reaction (acting at the proximal end) is unknown. All of the components are added to give the compensating reaction that needs to be applied to the segment to keep it in dynamic equalibrium.

The forces due to acceleration (including gravity) and moments of inertia are calculated from the position of the centre of mass of the segment (as given in the anthropometric table) from the current frame, and frames +- 0.25 seconds from the current frame (represented by ëNextí and ëPreviousí). This gives a moving average filter (of width 0.5 seconds).

See Winter (2nd edition p47-48), and 3D analysis of human movement, Ed.Allard/Stokes/Blanchi 1995 ISBN 0-87322-623-2 for fuller explanations of the equations.

LinearAccel = Next.CoM + Previous.CoM - 2 * Current.CoM
                        / m_FramePeriod * m_FramePeriod*SampleWidth*SampleWidth
LinearAccel += Gravity;
Reaction.Force = Segment.Mass * LinearAccel / 1000; //  kilos and millimetres

The angular velocities are calculated from the dot products ( ë&í ) of the axes of the segment +- 0.25 seconds from the current time.

AngularVeloc.X = Next.YAxis & Previous.ZAxis;
AngularVeloc.Y = Next.ZAxis & Previous.XAxis;
AngularVeloc.Z = Next.XAxis & Previous.YAxis;
AngularVeloc /= 2*FramePeriod*SampleWidth;

and accelerations are calculated similarly, also using the Current position :-

AngAccel.X = (Next.YAxis & Current. ZAxis) -  (Current.YAxis & Previous.ZAxis);
AngAccel.Y = (Next.ZAxis & Current.XAxis) -  (Current.ZAxis & Previous.XAxis);
AngAccel.Z = (NextXAxis & Current.YAxis) -  (Current.XAxis & Previous.YAxis);
AngularAccel /= m_FramePeriod * m_FramePeriod*SampleWidth*SampleWidth;

These are then used to calculate the gyroscopic component, then the moment of inertia acting round the centre of mass.

GyrComp.X = Inertia.X * Mass * AngularVeloc.X;
GyrComp.Y = Inertia.Y * Mass * AngularVeloc.Y;
GyrComp.Z = Inertia.Z * Mass * AngularVeloc.Z;
Moment = AngularVeloc x GyrComponent;

Moment.X += Inertia.X * AngularAccel.X;
Moment.Y += Inertia.Y * AngularAccel.Y;
Moment.Z += Inertia.Z * AngularAccel.Z;

The other reactions acting on the segment are then added, refering them all to the CoM:-

for ( R=0; R<NumReactions; R++ )
  Reaction.Force += Reaction[R]. Force;
  Reaction.Moment += Reaction[R]. Moment;
  Reaction.Moment += (Reaction[R]. Point - Reaction.Point) x Reaction[R].Force;

And then if a force plateís connected, add its values, noting that the data from the force plates is expressed as the reaction being applied to the segment, rather than to the plate, again refering to the CoM :-

for ( FP=0; FPIter <NumForcePlates; FP++ )
   if ( ForcePlates[FP]->IsConnected() )
      Reaction.Force -= ForcePlates[FP].Force;
      Reaction.Moment -= ForcePlates[FP].Moment;
      Reaction.Moment -= (ForcePlates[FP].Point - Reaction.sm_Point) x ForcePlates[FP].Force;
      FP = NumForcePlates; // skip the rest of the plates

Convert the result to refer to the attachment point.

Reaction.Moment += (Reaction.Point - Segment.Attachment) x Reaction.Force;
Reaction.Point = Segment.Attachment;

powerI = POWER( Seg1, Seg2 )

The same time separations are used to calculate the angular velocity for this as was used for the REACTION function above. ëPreviousí ëCurrentí and ëNextí positions separated by +- 0.25 seconds of the two segments are found.

Initially the Seg2 axes (represented in a 3x3 matrix) are converted to be relative to Seg1 coordinate space for each sample time.

Seg2Previous.Axes = Seg1Previous. Axes * Seg2Previous. Axes;
Seg2Current.Axes = Seg1Current. Axes * Seg2Current. Axes;
Seg2Next.Axes = Seg1Next. Axes * Seg2Next. Axes;

find the relative angular velocity between the two segments

AngularVeloc.X = Seg2Next.Axes.Y & Seg2Previous.Axes.Z;
AngularVeloc.Y = Seg2Next.Axes.Z & Seg2Previous.Axes.X;
AngularVeloc.Z = Seg2Next.Axes.X & Seg2Previous.Axes.Y;
AngularVeloc /= 2*m_FramePeriod*SampleWidth;

Convert the moment of the reaction between the segments (found using the REACTION function) to Segment 1 coordinate space too, and do the dot product with the angular velocity

LocalMoment = Transpose(Seg1Current. Axes) * Reaction. Moment
Power = LocalForce & AngularVeloc;