I’m sure this later one is much improved, but FYI, it’s almost ten years since I did this code below, as part of a bigger example over on SketchUcation.com…
I added modules etc to tidy it up here…
You pass a transformation tr with 0.1.2 or x,y,z axes…
The # sections in the rot’ methods are older alternatives that will sometimes not give the same results…
Usage example:
rotx = TIG::Transformation.rotX(transformation)
module TIG
module Transformation
def self.euler_angle(tr, xyz=[])
m = tr.xaxis.to_a + tr.yaxis.to_a + tr.zaxis.to_a
if m[6] != 1 && m[6] != -1
ry = -Math.asin(m[6])
rx = Math.atan2(m[7]/Math.cos(ry), m[8]/Math.cos(ry))
rz = Math.atan2(m[3]/Math.cos(ry), m[0]/Math.cos(ry))
else
rz = 0
phi = Math.atan2(m[1], m[2])
if m[6] == -1
ry = Math::PI/2
rx = rz + phi
else
ry = -Math::PI/2
rx = -rz + phi
end
end
return -rx if xyz==0
return -ry if xyz==1
return -rz if xyz==2
return [-rx,-ry,-rz] if xyz==[]
end
###
def self.rotX(tr)
#(Math.atan2(self.to_a[9],self.to_a[10]))
#Math.acos(self.to_a[5])
self.euler_angle(tr, 0)
end
def self.rotY(tr)
#(Math.arcsin(self.to_a[8]))
#Math.acos(self.to_a[0])
self.euler_angle(tr, 1)
end
def self.rotZ(tr)
#(-Math.atan2(self.to_a[4],self.to_a[0]))
#Math.asin(self.to_a[4])
self.euler_angle(tr, 2)
end
def self.rotXYZ(tr)
self.euler_angle(tr)
end
end
end