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;
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.
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
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;
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;