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