Jmol/Quaternions: Difference between revisions

From Proteopedia
Jump to navigation Jump to search
Karsten Theis (talk | contribs)
No edit summary
Karsten Theis (talk | contribs)
m User:Karsten Theis/quaternions moved to Jmol/Quaternions: add to other Jmol resources, let others edit
 
(13 intermediate revisions by the same user not shown)
Line 1: Line 1:
<StructureSection load='' size='340' side='right' caption='' scene='43/433638/Fullview_cartoon/20'>
<StructureSection load='' size='340' side='right' caption='' scene='43/433638/Fullview_cartoon/21'>


==Examples of how quaterions are used==
==Examples of how quaterions are used==
Line 23: Line 23:
Jmol shows structures (e.g. atomic positions) on a display and allows the view to be rotated and individual atomic positions to be manipulated. The display has Cartesion coordinates (the x-axis goes right, the y-axis goes up, and the z-axis points at the viewer). The atoms have Cartesian coordinates x, y, z. The meaning of the axes is sometimes arbitrary (NMR structures) or along certain crystallographic directions (X-ray structures). When you rotate the model, the coordinate system of the model is rotated (same coordinates x, y, z, but axes of coordinate system point in different directions) with respect to the display coordinate system.
Jmol shows structures (e.g. atomic positions) on a display and allows the view to be rotated and individual atomic positions to be manipulated. The display has Cartesion coordinates (the x-axis goes right, the y-axis goes up, and the z-axis points at the viewer). The atoms have Cartesian coordinates x, y, z. The meaning of the axes is sometimes arbitrary (NMR structures) or along certain crystallographic directions (X-ray structures). When you rotate the model, the coordinate system of the model is rotated (same coordinates x, y, z, but axes of coordinate system point in different directions) with respect to the display coordinate system.


<jmol><jmolButton><script>axes on</script><text>show axes</text></jmolButton></jmol>
<jmol><jmolButton><script>axes MOLECULAR; axes on</script><text>show axes</text></jmolButton></jmol>


When a new structure is loaded, the model axes point left, up, and out of the screen. The Jmol command "reset" puts that coordinate system back into that initial orientation.
When a new structure is loaded, the model axes point left, up, and out of the screen. The Jmol command "reset" puts that coordinate system back into that initial orientation.


<jmol><jmolButton><script>reset</script><text>reset to initial orientation</text></jmolButton></jmol>
<jmol><jmolButton><script>reset; axes MOLECULAR; axes on</script><text>reset to initial orientation</text></jmolButton></jmol>


==Changing orientations using quaternions==
==Changing orientations using quaternions==
Line 33: Line 33:
The Jmol command "q = quaternion()" assigns the current orientation to q.  
The Jmol command "q = quaternion()" assigns the current orientation to q.  


<jmol><jmolButton><script>q = quaternion()</script><text>save orientation</text></jmolButton></jmol>
<jmol><jmolButton><script>q = quaternion()</script><text>store orientation</text></jmolButton></jmol>


So, again, how is an orientation different from a rotation? An orientation is the rotation necessary to get the coordinate system from the "reset" orientation to the current orientation. The quaternion ''q0'' for the initial orientation corresponds to no rotation, i.e. {0 0 1 0}. To get back to an orientation ''q'' after rotating, use "moveto 0 quaternion q". After you saved an orientation, click the reset button above and then go back to the saved orientation with the button below.
So, again, how is an orientation different from a rotation? An orientation is the rotation necessary to get the coordinate system from the "reset" orientation to the current orientation. The quaternion ''q0'' for the initial orientation corresponds to no rotation, i.e. {0 0 1 0}. To get back to an orientation ''q'' after rotating, use "moveto 0 quaternion q". After you saved an orientation, click the reset button above and then go back to the saved orientation with the button below.


<jmol><jmolButton><script>moveto 0 quaternion @q</script><text>go to saved orientation</text></jmolButton></jmol>
<jmol><jmolButton><script>moveto 0 quaternion @q</script><text>go to stored orientation instantly</text></jmolButton></jmol>
 
<jmol><jmolButton><script>moveto 2 quaternion @q</script><text>go to stored orientation gradually</text></jmolButton></jmol>


Relevant Jmol command examples:
Relevant Jmol command examples:
  q = quaternion() # store current orientation
  q = quaternion() # store current orientation
  moveto 0 quaternion @q # go back to stored orientation instantly
  moveto 0 quaternion @q # go back to stored orientation instantly
  moveto 1 quaternion @q # go back to stored orientation gradually
  moveto 2 quaternion @q # go back to stored orientation gradually (2 sec)
   
   
==Combining two rotations==
==Combining two rotations==
Line 55: Line 57:


Choosing x = 1, y = 0.5, z = 0 and tilt = 10, the buttons illustrate the commands.
Choosing x = 1, y = 0.5, z = 0 and tilt = 10, the buttons illustrate the commands.
<jmol><jmolButton><script>s = quaternion(); r = quaternion({1 0.5 0},10); tilted = r * s; moveto 1 quaternion @tilted </script><text>tilt 10 degrees away from view</text></jmolButton></jmol>
<jmol><jmolButton><script>s = quaternion(); r = quaternion({1 0.5 0},10); tilted = r * s; moveto 1 quaternion @tilted </script><text>tilt 10 degrees away from view</text></jmolButton></jmol>


Line 72: Line 75:


Here is an example:  
Here is an example:  
<jmol><jmolButton><script>q0 = quaternion(); qr = quaternion({1 1 0}, 90); rotate @qr</script><text>rotate all the way</text></jmolButton></jmol>
<jmol><jmolButton><script>q0 = quaternion(); qr = quaternion({1 1 0}, 180); rotate @qr</script><text>rotate all the way</text></jmolButton></jmol>


<jmol><jmolButton><script>moveto 0 quaternion @q0</script><text>back to last orientation</text></jmolButton></jmol>
<jmol><jmolButton><script>moveto 0 quaternion @q0</script><text>back to last orientation</text></jmolButton></jmol>


<jmol><jmolButton><script>q10 = @qr / 10; rotate @q10</script><text>rotate one tenth</text></jmolButton></jmol>
<jmol><jmolButton><script>q10 = @qr / 10; rotate @q10</script><text>rotate one tenth</text></jmolButton></jmol>
<jmol><jmolButton><script>q10 = @qr / 10;
moveto 0 quaternion @q0;delay 0.5;
qn = q10 * q0; moveto 0.5 quaternion @qn;
qn = (q10 * 3) * q0; moveto 0.3 quaternion @qn;
qn = (q10 * 7) * q0; moveto 0.2 quaternion @qn;
qn = (q10 * 9) * q0; moveto 0.3 quaternion @qn;
qn = (q10 * 10.1) * q0; moveto 0.5 quaternion @qn;
qn = (q10 * 10) * q0; moveto 0.5 quaternion @qn;
</script><text>rotate all the way with variable speed</text></jmolButton></jmol>


Relevant Jmol command examples:
Relevant Jmol command examples:
  qr = quaternion({1 1 0}, 90) #define the overall rotation
  qr = quaternion({1 1 0}, 180) #define the overall rotation
  q10 = @qr / 10 #q10 is rotating only one tenth of the way
  q10 = @qr / 10 #q10 is rotating only one tenth of the way
  rotate @q10 # rotate the view by the given amount
  rotate @q10 # rotate the view by the given amount
Line 86: Line 99:
For the second example script, I wanted to rotate the view back to the initial orientation. For small adjustments, I wanted it to take a small time, while for larger adjustment, I wanted to spend enough time that you can easily follow. The Jmol moveto command takes a duration for the entire rotation as a parameter. If I set this to a fixed value, it would be too slow for small adjustments or too fast for large rotations. So I had to figure out by how many degrees I would rotate first, and then decide on the timing accordingly.
For the second example script, I wanted to rotate the view back to the initial orientation. For small adjustments, I wanted it to take a small time, while for larger adjustment, I wanted to spend enough time that you can easily follow. The Jmol moveto command takes a duration for the entire rotation as a parameter. If I set this to a fixed value, it would be too slow for small adjustments or too fast for large rotations. So I had to figure out by how many degrees I would rotate first, and then decide on the timing accordingly.


<jmol><jmolButton><script>q1 = quaternion()</script><text>store first orientation</text></jmolButton></jmol>
<jmol><jmolButton><script>q1 = quaternion(); set echo top left; echo "orientation stored"</script><text>store first orientation</text></jmolButton></jmol>


After pressing the button above, rotate the model a bit or a lot. Now will will go back the first orientation, with a nice speed no matter how different they are:
After pressing the button above, rotate the model a bit or a lot. Now will will go back the first orientation, with a nice speed no matter how different they are:


<jmol><jmolButton><script>q2 = quaternion(); rotation = q2 / q1; rotangle = rotation%"theta"; duration = rotangle/45 + 0.1; set echo top left; t = "rotate by " + (rotangle%3) + "degrees"; echo @t; moveto @duration quaternion @q1</script><text>back to first orientation</text></jmolButton></jmol>
<jmol><jmolButton><script>q2 = quaternion(); rotation = q2 / q1; rotangle = rotation%"theta"; duration = rotangle/45 + 0.1; set echo top left; t = "rotate by " + (rotangle%1) + " degrees"; echo @t; moveto @duration quaternion @q1</script><text>back to first orientation</text></jmolButton></jmol>




Line 102: Line 115:
  moveto @duration quaternion @q1 # reorient the view back to q1 in duration seconds
  moveto @duration quaternion @q1 # reorient the view back to q1 in duration seconds
   
   
==Moveto vs Rotate command==
The rotate command only rotates (no zoom or translation), and always at the same speed. If you want to have control over the rotation speed, you have to use moveto instead. Moveto takes the final orientation as a parameter, and moves to it from whatever the current orientation is. On the other hand, the rotate command is relative to the starting orientation. If you want to turn a rotate command into a moveto command, you have to calculate the final orientation in the following way:
start = quaternion();
final = rotation * start; #equation 1
Then, you can use the moveto command.
On the flip side, if you have the final and start orientations, and need the rotation, you use quaternion division:
rotation = final / start; #equation 2
Equation 2 is derived by right-dividing equation 1 by start to isolate rotation on the right hand side


==Moving atoms==
some other time...
</StructureSection>
</StructureSection>
==Resources==
==Resources==
http://sacredsoftware.net/tutorials/quaternion.html
http://sacredsoftware.net/tutorials/quaternion.html

Latest revision as of 19:38, 21 June 2020


Examples of how quaterions are used

http://proteopedia.org/wiki/images/7/76/Wobble.spt

jmol script to move molecule around a given orientation in a precession movement.



Preliminary definitions

A quaternion q is an mathematical object (like a matrix or a complex number) with four parameters x y z w. It is useful to express orientations and rotations, and to do calculations (combining, interpolating, dissecting) on them.

Orientation refers to from which side we are looking at an object (or how we a orienting the object in front of the camera or viewport). Rotation refers to changing either the orientation, or turning a selected object while keeping the view.

Coordinate systems

Jmol shows structures (e.g. atomic positions) on a display and allows the view to be rotated and individual atomic positions to be manipulated. The display has Cartesion coordinates (the x-axis goes right, the y-axis goes up, and the z-axis points at the viewer). The atoms have Cartesian coordinates x, y, z. The meaning of the axes is sometimes arbitrary (NMR structures) or along certain crystallographic directions (X-ray structures). When you rotate the model, the coordinate system of the model is rotated (same coordinates x, y, z, but axes of coordinate system point in different directions) with respect to the display coordinate system.

When a new structure is loaded, the model axes point left, up, and out of the screen. The Jmol command "reset" puts that coordinate system back into that initial orientation.

Changing orientations using quaternions

The Jmol command "q = quaternion()" assigns the current orientation to q.

So, again, how is an orientation different from a rotation? An orientation is the rotation necessary to get the coordinate system from the "reset" orientation to the current orientation. The quaternion q0 for the initial orientation corresponds to no rotation, i.e. {0 0 1 0}. To get back to an orientation q after rotating, use "moveto 0 quaternion q". After you saved an orientation, click the reset button above and then go back to the saved orientation with the button below.

Relevant Jmol command examples:

q = quaternion() # store current orientation
moveto 0 quaternion @q # go back to stored orientation instantly
moveto 2 quaternion @q # go back to stored orientation gradually (2 sec)

Combining two rotations

For the wobble script, I want to change the orientation a little bit, rotating about an axis in the plane of the display. The effect is that parts of the structure the the center foreground move around in a circle, tilting the view a bit in different directions. Distinct from the spin command, the view does not change much. Distinct from a rocking motion, the structure gets tilted over time in all directions, giving a better spatial view.

In order to achieve this effect, we have to apply a rotation r on the starting orientation s. This is done by quaternion multiplication. The order matters: the right-most rotation is applied first. Here, we first want to rotate the structure from the initial orientation to the current orientation, and then apply the tilting rotation, so the overall orientation becomes r * s.

Relevant Jmol command examples:

r = quaternion({@x @y @z},@tilt) # rotation about an axis xyz by tilt degrees
tilted = r * s # rotate the starting orientation to get the tilted orientation
moveto @time quaternion @tilted # tilt the view, taking some time to do so.

Choosing x = 1, y = 0.5, z = 0 and tilt = 10, the buttons illustrate the commands.

Choosing x = 1, y = -0.5, z = 0 and tilt = 10, the buttons illustrate tilting in a different direction.



Interpolating between orientations

If you have a quaternion that defines a rotation, and you want to rotate in a stepwise fashion, this is very easy. You just divide the quaternion by the number of steps, and apply that rotation.

Here is an example:

Relevant Jmol command examples:

qr = quaternion({1 1 0}, 180) #define the overall rotation
q10 = @qr / 10 #q10 is rotating only one tenth of the way
rotate @q10 # rotate the view by the given amount

Interpreting a rotation

For the second example script, I wanted to rotate the view back to the initial orientation. For small adjustments, I wanted it to take a small time, while for larger adjustment, I wanted to spend enough time that you can easily follow. The Jmol moveto command takes a duration for the entire rotation as a parameter. If I set this to a fixed value, it would be too slow for small adjustments or too fast for large rotations. So I had to figure out by how many degrees I would rotate first, and then decide on the timing accordingly.

After pressing the button above, rotate the model a bit or a lot. Now will will go back the first orientation, with a nice speed no matter how different they are:


Here are the relevant Jmol commands:

q1 = quaternion() #Store first orientation
q2 = quaternion() #Store second orientation
rotation = q2 / q1 #rotation to get from q1 to q2 
rotangle = rotation%"theta" #Extract the rotation angle from the quaternion
rotangle = 2 * acos(rotation.w) #Alternative way to get the angle, avoids percent sign
duration = angle/45 + 0.1 #take one second per 45 degrees rotation, plus 0.1 sec 
moveto @duration quaternion @q1 # reorient the view back to q1 in duration seconds

Moveto vs Rotate command

The rotate command only rotates (no zoom or translation), and always at the same speed. If you want to have control over the rotation speed, you have to use moveto instead. Moveto takes the final orientation as a parameter, and moves to it from whatever the current orientation is. On the other hand, the rotate command is relative to the starting orientation. If you want to turn a rotate command into a moveto command, you have to calculate the final orientation in the following way:

start = quaternion();
final = rotation * start; #equation 1

Then, you can use the moveto command.

On the flip side, if you have the final and start orientations, and need the rotation, you use quaternion division:

rotation = final / start; #equation 2

Equation 2 is derived by right-dividing equation 1 by start to isolate rotation on the right hand side


Moving atoms

some other time...

Drag the structure with the mouse to rotate

ResourcesResources

http://sacredsoftware.net/tutorials/quaternion.html

Proteopedia Page Contributors and Editors (what is this?)Proteopedia Page Contributors and Editors (what is this?)

Karsten Theis