# ===-- quat.py -----------------------------------------------------------===## # # The KLEE Symbolic Virtual Machine # # This file is distributed under the University of Illinois Open Source # License. See LICENSE.TXT for details. # # ===----------------------------------------------------------------------===## from __future__ import division import math import vec3, vec4 def identity(): return (0.0,0.0,0.0,1.0) def fromaxisangle(axisangle): axis,angle= axisangle ang_2= angle/2.0 s_ang= math.sin(ang_2) c_ang= math.cos(ang_2) q= vec3.mulN(axis, s_ang) + (c_ang,) return normalize(q) def fromnormals(n1,n2): axis,angle= vec3.normalize(vec3.cross(n1, n2)), math.acos(vec3.dot(n1, n2)) return fromaxisangle((axis,angle)) # avoid trigonmetry def fromnormals_faster(n1,n2): axis= vec3.normalize(vec3.cross(n1, n2)) half_n= vec3.normalize(vec3.add(n1, n2)) cos_half_angle= vec3.dot(n1, half_n) sin_half_angle= 1.0 - cos_half_angle**2 return vec3.mulN(axis, sin_half_angle) + (cos_half_angle,) def fromvectors(v1,v2): return fromnormals(vec3.normalize(v1), vec3.normalize(v2)) def magnitude(q): return vec4.length(q) def normalize(q): return vec4.divN(q, magnitude(q)) def conjugate(q): x,y,z,w= q return (-x, -y, -z, w) def mulvec3(q, v): t= mul(q, v+(0.0,)) t= mul(t, conjugate(q)) return t[:3] def mul(a, b): ax,ay,az,aw= a bx,by,bz,bw= b x= aw*bx + ax*bw + ay*bz - az*by y= aw*by + ay*bw + az*bx - ax*bz z= aw*bz + az*bw + ax*by - ay*bx w= aw*bw - ax*bx - ay*by - az*bz return (x,y,z,w) def toaxisangle(q): tw= math.acos(q[3]) scale= math.sin(tw) angle= tw*2.0 try: axis= vec3.divN(q[:3], scale) except ZeroDivisionError: axis= (1.0,0.0,0.0) return axis,angle def tomat3x3(q): x,y,z,w= q m0= ( 1.0 - 2.0 * ( y*y + z*z ), 2.0 * ( x*y - z*w ), 2.0 * ( x*z + y*w )) m1= ( 2.0 * ( x*y + z*w ), 1.0 - 2.0 * ( x*x + z*z ), 2.0 * ( y*z - x*w )) m2= ( 2.0 * ( x*z - y*w ), 2.0 * ( y*z + x*w ), 1.0 - 2.0 * ( x*x + y*y )) return m0,m1,m2 def tomat4x4(q): m0,m1,m2= tomat3x3(q) return (m0 + (0.0,), m1 + (0.0,), m2 + (0.0,), (0.0, 0.0, 0.0, 1.0)) def slerp(a, b, t): raise NotImplementedError cos_omega= vec4.dot(a, b) if (cos_omega<0.0): cos_omega= -cos_omega b= vec4.neg(b) imega= math.acos(cos_omega) t= sin(t*omega)/sin(omega) return vec4.lerp(a, b, t)