June 7, 2012

Rotation: pivot around a point

For this discussion there will be two frames of reference: global and local, local being the frame of reference attached to an object's root prim.  Any position can be represented as a vector in either the global or local frame.  In this specific problem, rotations are always represented in the global frame.

The object has a starting global position and rotation and an ending global position and rotation.  There is a global pivot position.  The algebraic problem to solve is as follows:  Given the pivot position, the starting position, the starting rotation and the ending rotation, determine the ending position.

The specific relationship for solving this specific problem is that "to pivot about" means that the local vector of the pivot point does not change.

The general relationship for solving all rotation problems is that for any position, A, a rotation transforms a local vector into global vector in this manner:

(1)    gloVecA = gloVecObj + locVecA * gloRotObj

Represent the beginning and ending positions and rotations of the object by:

         gloVecObjBeg and gloVecObjEnd
         gloRotObjBeg and gloRotObjEnd

The global position of the pivot point does not change.  Represent it by:


By the meaning of  "to pivot about" the local position of the pivot point also does not change.  Represent it by:


The local and global pivot positions are related by the general equation (1):

(2)     gloVecPivot = gloVecObjBeg + locVecPivot * gloRotObjBeg 
(3)     gloVecPivot = gloVecObjEnd + locVecPivot * gloRotObjEnd   

Equations (2) and (3) will solved for the local pivot vector which will be elimiated by equating.  The resulting equation will be solved for gloVecPivotEnd in terms of the other known variables.

Step A)        Solve (2) and (3) for the local vectors

(4)    locVecPivot = ( gloVecPivot - gloVecObjBeg ) /gloRotObjectBeg
(5)    locVecPivot = ( gloVecPivot - gloVecObjEnd ) / gloRotObjectEnd

Step B)        Equate the right side expressions of Equations (4) and (5)

(6)     ( gloVecPivot - gloVecObjBeg ) / gloRotObjBeg
                    =  ( gloVecPivot - gloVecObjEnd ) / gloRotObjEnd

Step C)        Multiple both sides of (6) by gloRotObjectEnd

(7)    ( ( gloVecPivot - gloVecObjBeg ) / gloRotObjBeg ) * gloRotObjEnd
                    =  gloVecPivot - gloVecObjEnd 

Step D)        Rearrange (7) to isolate gloVecObjectEnd

(8)     gloVecObjEnd = gloVecPivot
                -  ( ( gloVecPivot - gloVecObjBeg ) / gloRotObjBeg ) * gloRotObjEnd

To script this, note that

      gloVecObjBeg = llGetPos();
      gloRotObjBeg = llGetRot();

and that the script knows gloVecPivot and that the script has calculated a value for gloRotObjEnd.

After using equation (8) to calculate gloVecObjEnd, the script will change the postion and rotation of the object:

     llSetPrimitiveParams( [ PRIM_POSITION, gloVecObjEnd,
                                                                   PRIM_ROTATION, gloRotObjEnd ] );

  • The labeling of variables is complex in this problem because it is essential to keep track of the frame of reference of any vector or rotation value.
  • Do not invert the order of rotations in equation (8).
  • Use llSetPrimitiveParameters() to avoid seeing the object shift and rotate in two steps.