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
& 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;**

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