ShiftSpin

ShiftSpin (ST Actorname) [to] (ve #4 translation) (ve #4 rotation);

The syntax of this command is:

ShiftSpin "myActor" to [x,y,z,1] quat(Angle, [n1,n2,n3]);

            If you have not done so already, you might like to read the discussion of the Shift Command and Spin Command before proceeding with this section, since much of the terminology is developed in those sections.  Also useful for examples is the section on Moving Actors

An important form of animation manipulates the actors in a scene while leaving the scene (and camera) coordinates fixed.  This is why the named actors have names, so that scripts can manipulate them.  The commands that we use for this are:  SpinShift, ShiftSpin, Shift, Spin, Push, DoShift, DoSpinShift, and DoShiftSpin.  These commands are used to move individual actors in two ways.  The simplest and most straightforward way is to apply the command to an actor to move it discretely to a new location, perhaps with a new orientation.

            In Mathwright32, each actor is, ultimately, only a collection of vertices V in global (scene) coordinates, together with the "geometry" that binds the vertices together (the lines, triangles, quadrilaterals, etc. )  Now, after the actor vertices are defined, the actor is positioned in a scene by actively transforming these vertices to scene coordinates (usually using Translate() and Rotate() in the Actor Script).   The fact that these transformations commute with the navigation transformations (Move and Turn) means that these initial positions are independent of viewpoint.  That is natural.

Note:  In all of this discussion, we assume that Scale() transformations are not used in actor scripts.  They are not orthogonal, hence do not belong in general, to the Euclidean group.  All of the actors you may create or import in Mathwright32 may be scaled initially as you like to fit the scene without using the Scale() transformation in any case.

            The transformations in the Actor Script define the initial position and orientation of the actor, the way it appears when selected into the scene, in terms of the global coordinate system.  Together, they may be viewed as a rigid (Euclidean) transformation, I,  from R3 to R3.  We have already observed that each rigid transformation from R3 to R3 has unique representation as the composition of a rotation about the origin followed by a translation.  This is a SpinShift.  It also has a (usually different) unique representation as the composition of a translation first, followed by a rotation about the origin. This is a ShiftSpin

.  We find it convenient sometimes to use one such representation, sometimes the other, because while, in principle, we can always translate from one to the other, the algebra is sometimes messy.

            Each actor therefore has, attached to it two things:  A set of vertices, V,  referred to the global coordinate system, and a rigid transformation of the global coordinate system to itself that actively carries those vertices to the initial position, defined by its script.  Call this initial transformation of R3:  I.  It is a permanent property of the actor (like the vertices V) as long as the actor script is not changed.  "I" will also be called the "Initial Stage Transformation." 

            Before this initial stage transformation is applied, the actor is simply defined by its vertex coordinates, V.  While you will only see an actor in this state before you script it, it will be important to be aware of what that state, V,  is when you script motion for an actor.  The important thing to understand is that, in order to move any given actor, we must define a Euclidean transformation of all of R3  -- a combination of a spin and a shift.  That transformation will not affect other actors, but it will carry the vertices V of the current actor to new vertices, and we will see the effect of that transformation.  The Initial Stage transformation, I, defined by each actor's script does just that, for each actor, individually.

             This is all well and good.  When navigation commands are issued, they affect all actors in the same way, maintaining all relative spatial relations.  Now the question is:  How do we change the position of a single actor, leaving the others alone?  To do this,  we define a new Euclidean  stage transformation for the actor, one that replaces the Initial Stage transformation, and transforms V to its new destination.

            Each of the commands: SpinShift, ShiftSpin, Spin, and Shift defines for the actor a new Stage Transformation.  These do not accumulate.  Each new one simply replaces the previous one.  The actor is simply wherever the last command put it.  Thus at any time, the actor's vertices are the image of V under the last SpinShift, ShiftSpin, Spin, or Shift  that was called on the actor.  In this way, your program "knows" at any time what the position and orientation of each actor is.  This is obviously useful and important. 

            This is why it is important to remember what the vertex set V looks like for each actor.  Every motion will transform that vertex set to the desired position and orientation. 

            If the Stage transformation is the initial one, I,  the actor appears as the script initially dictated.  If not, it appears -- and remains under all navigation commands -- in the new position and orientation given by the last stage transformation.  Whenever the screen is Reset, using the Centering Button, the scene is restored to its original state and all Stage Transformations are restored to the original ones.

            Therefore, each actor carries with it, first, the initial coordinates, V,  defined by its vertices.  Its script defines the initial transformation, I,  into the global scene. This defines the initial position and orientation of the actor. 

As mentioned earlier, each rigid transformation from R3 to R3 has unique representation as the composition of a rotation about the origin followed by a translation, that is, as a SpinShift.  Sometimes it is useful, however, to represent a rigid motion in an alternative way, as a composition:  r o t  (where t, a translation, is done first, and it is followed by r, a rotation about the origin).  Representation of a rigid motion in this form is unique also, and it is called in Mathwright32 a ShiftSpin.

The syntax of this command is:

ShiftSpin "myActor" to [x,y,z,1] quat(Angle, [n1,n2,n3]);

            Notice that the translation (shift) is always the first argument in a ShiftSpin, and the rotation (spin) is the second.  Also, it is important that the last component of the translation vector be 1.

            The effect of this command will be to apply first the translation by (x,y,z) to the vertices, V, of "myActor"  and then to apply the rotation quat(Angle, [n1,n2,n3])  to the result.  You will see, of course, a single motion. 

            You may accumulate rotations in your script as products of quaternions, and accumulate translations as sums. 

Note:  The quaternion product u*v applied to an actor means v first, then u, just as in function composition. 

            The order of the arguments is thus, shift first, spin second, as the name indicates, and as they are applied.  ShiftSpin first translates V, then rotates. 

            For example.  Suppose we wanted to illustrate the noncommutativity of rotations.  We might imagine placing a cube at the point [-10,0,0], and applying a continuous series of rotations of the form  v*u, that is, u first and v second, where

u = quat( angle, [1,0,0])

v = quat( angle, [0,1,0])

for increasing values of angle.  This would cause the actor to revolve about the y-axis as it spun end-over-end about "its own" x-axis.  It would orbit and spin.

            On the other hand, a continuous sequence of the transformations u*v, that is, v first then u, would have an entirely different effect.  If the center of gravity of "myActor" is at the origin initially, this demonstration would be difficult to achieve with SpinShift, but easy with ShiftSpin, as the following scripts show:

program demoVU (ex step) {

  do

  s := 0

  until s > 360 {

  u := quat(s, [1,0,0]);

  v := quat(s, [0,1,0]);

  shiftspin "myActor" to [-10,0,0,1], v*u;

  s := s+step;

}

}

program demoUV (ex step) {

  do

  s := 0

  until s > 360 {

  u := quat(s, [1,0,0]);

  v := quat(s, [0,1,0]);

  shiftspin "myActor" to [-10,0,0,1], u*v;

  s := s+step;

}

}

            Now of course if V initially positioned the actor at [-10,0,0] then we could simply use the Spin command to achieve this effect.  But, for a given actor, we cannot have it both ways.  The SpinShift and ShiftSpin commands naturally complement each other, and together ease the burden of calculating motion.

            It was important for this simulation to do the full motion at once, and not to translate first, draw, then rotate, and draw at each step.  The latter would give a "jerky" appearance to the motion.  In principle, any motion desired can be obtained using ShiftSpin in this way. But some Geometry is required to discover the right transformations.

            Notice again that you may enter a quaternion as a 4-tuple.  If you execute

quat( a, [x,y,z])

on the command line, the system prints the quaternion value. And the quaternion product u*v applied to an actor means v first, then u, just as in function composition.

See Also

                        Moving Actors

                        Shift

                        Spin

                        SpinShift