# SLERP (Spherical Linear-Interpolate) between two vectors from Python

How to do this?

Below is my particular use case and attempt to solve the problem:

Consider Z_axis = (0,0,1) and an arbitrary point also on the unit sphere v.

You can imagine the arc on the surface of the sphere from Z_axis to v.

I wish to create v' by extending the arc by 10%.

How can I do this from Python?

Here is as far as I have got:

unit_v = v.normalized()
rot_axis = Z_axis.cross(unit_v)


...will give a vector perpendicular to rotation plane, and

theta = arcsin( abs(rot_axis) ) # <-- some potential problem with positive and negative angles here I think


...will return the angle.

So I was just need to rotate unit_v by theta' = 0.1*theta around rot_axis

How do I do this?

I can construct a Quaternion Q representing the rotation:

w = cos( theta'/2 )
x,y,z = sin( theta'/2 ) * rot_axis.normalized()

Q = Quaternion(( w,x,y,z ))


and then:

unit_v' = unit_v.rotate(Q)
v' = abs(v) * unit_v'


Is this correct, and is there a cleaner way?

Blender 2.71 (or any recent build) has Vector.slerp (spherical linear interpolation) which accepts values outside 0-1

So you can do:

a = Vector((1, 0, 0))
b = Vector((0, 1, 0))
c = a.slerp(b, 0.5)  # half way


To over rotate 10% do:

c = a.slerp(b, 1.1)


Note, this feature is not included in a stable release yet (but 2.71 will include it).

As @ideasman42 said you can use slerp for the rotation in coming releases, but until then, I think Quaternions are a good solution.
However if you want to rotate a large number of points, rotation matrices is faster. Rotating a point p using a quaternion q works as follows:

(0,p') = q * (0,p) * q^

where (0,p) is a quaternion with a w value of 0 and the x, y and z value of p and q^ is the conjugated quaternion of q. * denotes the quaternion multiplication.
This is what quaternion multiplication looks like if broken into bits:

q1*q2 = (w1,x1,y1,z1)*(w2,x2,y2,z2)
= ( w1*w2-x1*x2-y1*y2-z1*z2 ,
w1*x2+x1*w2+y1*z2-z1*y2 ,
w1*y2+y1*w2+z1*x2-x1*z2 ,
w1*z2+z1*w2+x1*y2-y1*x2  )


Both quaternion multiplications internally need 16 floatingpoint multiplications and 12 floatingpoint additions (seeing subtractions as additions with negative numbers).

Total cost:
32 multiplications

Rotating a point using a rotation matrix as follows:

p' = R * p


where R is the rotation matrix and * denotes the matrix multiplication. Note that p is a column vector.
Even if Blender imbeds the rotation matrix in a 4x4 transformation matrix and uses 4D homogenuous points in the calculation this results in less computation steps:

      |r11 r12 r13 r14|   |px|   |r11*px+r12*py+r13*pz+r14*pw|
R*p = |r21 r22 r23 r24| * |py| = |r21*px+r22*py+r23*pz+r24*pw|
|r31 r32 r33 r34|   |pz|   |r31*px+r32*py+r33*pz+r34*pw|
|r41 r42 r43 r44|   |pw|   |r41*px+r42*py+r43*pz+r44*pw|


Total cost:
16 multiplications