I have set up a Metasequoia document as shown below.
The document shows a point object located on the X axis which will be rotated about the Y axis. The axis of rotation is shown by an orange coloured line object.
A counter-clockwise rotation about an axis when the rotation is viewed from the positive of end of the axis towards the zero end of that axis is a positive rotation.
To visualise this I have placed a clock face at the origin of the Y axis.
If you copy this example, the object name for the point object must be “point” and the object name for the axis object must be “axis”. The axis object must be a line with one or both points at (0, 0, 0).
The script is shown below and uses information contained in my post on quaternions [link].
# clear the script editor output window each run
MQSystem.clearLog()
# can add path where Python looks for modules
# with sys.path
import sys
sys.path.append("./Script")
# need pi, sin and cos from math module
import math
def pr(message):
'''
Save some typing
'''
MQSystem.println(str(message))
return
def quat(axis, angle):
'''
Create a quaternion from an axis and an angle.
The axis must be an MQPoint
The axis will be normalized in this function
The angle must be in degrees
A quaternion is returned as a Python tuple
'''
theta = math.pi * angle / 180.0
halftheta = theta / 2.0
v = axis.getNormal()
c = math.cos(halftheta)
s = math.sin(halftheta)
return (s*v.x, s*v.y, s*v.z, c)
def q_inv(q):
'''
Returns the inverse of a unit quaternion q
A quaternion is returned as a Python tuple
'''
return (-q[0],-q[1],-q[2],q[3])
def pxq(p,q):
'''
Returns the multiplication of two quaternions
A quaternion is returned as a Python tuple
'''
p1,p2,p3,p4 = p[0],p[1],p[2],p[3]
q1,q2,q3,q4 = q[0],q[1],q[2],q[3]
i = p4*q1-p3*q2+p2*q3+p1*q4
j = p3*q1+p4*q2-p1*q3+p2*q4
k = -p2*q1+p1*q2+p4*q3+p3*q4
w = -p1*q1-p2*q2-p3*q3+p4*q4
return (i,j,k,w)
# input the axis of the rotation here
axis = MQSystem.newPoint(0,1,0)
# input the angle here
angle = 45.0 # degrees
# the quaternion
q = quat(axis, angle)
pr("q is %s"%str(q))
# the inverse quaternion
qi = q_inv(q)
pr("qi is %s"%str(qi))
doc = MQSystem.getDocument()
if doc.numObject>0:
obj = None
for ob in doc.object:
if ob:
if ob.name.lower()=="point":
obj = ob
break
line = None
for ob in doc.object:
if ob:
if ob.name.lower()=="axis":
line = ob
break
if obj:
if line:
if line.numVertex == 2:
# creates a line showing the axis of rotation
sc = 100
pt = MQSystem.newPoint(axis.x*sc,axis.y*sc,axis.z*sc)
line.vertex[1].setPos(pt)
for v in obj.vertex:
ax = v.getPos()
p = (ax.x,ax.y,ax.z,0)
qxp = pxq(q,p)
# r is the result of q x p x qi
# i.e. the sandwich product
r = pxq(qxp,qi)
pp = MQSystem.newPoint(r[0],r[1],r[2])
v.setPos(pp)
pr("Script finished")
Repeatedly running the script rotates the point counter-clockwise about the Y axis in steps of 45 degrees.
You can change the axis of rotation and angle of rotation by changing the values in the script.
This post [link] has some basic information about using Metasequoia’s script editor.
No comments:
Post a Comment