class Geo3d::Quaternion

Attributes

w[R]
x[R]
y[R]
z[R]

Public Class Methods

from_axis(rotation_axis, radians = 0) click to toggle source
# File lib/geo3d/quaternion.rb, line 49
def self.from_axis rotation_axis, radians = 0
  radians = Geo3d::Utils.normalize_angle radians  #todo: is this cheating?....
  normalized_rotation_axis = rotation_axis.zero_w.normalize
  q = self.new
  q.x = Math.sin(radians / 2.0) * normalized_rotation_axis.x
  q.y = Math.sin(radians / 2.0) * normalized_rotation_axis.y
  q.z = Math.sin(radians / 2.0) * normalized_rotation_axis.z
  q.w = Math.cos(radians / 2.0)
  q
end
from_axis_degrees(rotation_axis, degrees = 0) click to toggle source
# File lib/geo3d/quaternion.rb, line 60
def self.from_axis_degrees rotation_axis, degrees = 0
  from_axis rotation_axis, Geo3d::Utils.to_radians(degrees)
end
from_matrix(pm) click to toggle source
# File lib/geo3d/quaternion.rb, line 64
def self.from_matrix pm
  pout = self.new

  #puts "trace is #{pm.trace}"
  if false && pm.trace > 1.0
    sq_root_of_trace = Math.sqrt pm.trace
    pout.x = (pm._23 - pm._32) / (2.0 * sq_root_of_trace)
    pout.y = (pm._31 - pm._13) / (2.0 * sq_root_of_trace)
    pout.z = (pm._12- pm._21) / (2.0 * sq_root_of_trace)
    pout.w = sq_root_of_trace / 2.0
    #puts "a and pout is #{pout.inspect}"

    return pout
  end
  maxi = 0
  maxdiag = pm._11


  for i in 1..2
    if pm[i, i] > maxdiag #todo: indexing might need to be fixed > maxdiag
      maxi = i
      maxdiag = pm[i, i] #todo: indexing might need to be fixed
    end
  end
  case maxi
    when 0
      s = 2.0 * Math.sqrt(1.0 + pm._11 - pm._22 - pm._33)
      pout.x = 0.25 * s
      pout.y = (pm._12 + pm._21) / s
      pout.z = (pm._13 + pm._31) / s
      pout.w = (pm._23 - pm._32) / s

    when 1
      s = 2.0 * Math.sqrt(1.0 + pm._22 - pm._11 - pm._33)
      pout.x = (pm._12 + pm._21) / s
      pout.y = 0.25 * s
      pout.z = (pm._23 + pm._32) / s
      pout.w = (pm._31 - pm._13) / s

    when 2
      s = 2.0 * Math.sqrt(1.0 + pm._33 - pm._11 - pm._22)
      pout.x = (pm._13 + pm._31) / s
      pout.y = (pm._23 + pm._32) / s
      pout.z = 0.25 * s
      pout.w = (pm._12 - pm._21) / s
  end
  #puts "b"
  pout
end
identity() click to toggle source
# File lib/geo3d/quaternion.rb, line 212
def self.identity
  self.new 0, 0, 0, 1
end
new(*args) click to toggle source
# File lib/geo3d/quaternion.rb, line 5
def initialize *args
  @x, @y, @z, @w = 0.0, 0.0, 0.0, 0.0
  @x = args[0].to_f if args.size > 0
  @y = args[1].to_f if args.size > 1
  @z = args[2].to_f if args.size > 2
  @w = args[3].to_f if args.size > 3
end

Public Instance Methods

!=(vec) click to toggle source
# File lib/geo3d/quaternion.rb, line 45
def != vec
  !(self == vec)
end
*(v) click to toggle source
# File lib/geo3d/quaternion.rb, line 122
def * v
  if Quaternion == v.class
    quat = v
    out = self.class.new
    out.w = w * quat.w - x * quat.x - y * quat.y - z * quat.z
    out.x = w * quat.x + x * quat.w + y * quat.z - z * quat.y
    out.y = w * quat.y - x * quat.z + y * quat.w + z * quat.x
    out.z = w * quat.z + x * quat.y - y * quat.x + z * quat.w
    out
  else
    self.class.new x*v, y*v, z*v, w*v
  end
end
+(quat) click to toggle source
# File lib/geo3d/quaternion.rb, line 114
def + quat
  self.class.new x + quat.x, y + quat.y, z + quat.z, w + quat.w
end
+@() click to toggle source
# File lib/geo3d/quaternion.rb, line 33
def +@
  self.class.new x, y, z, w
end
-(quat) click to toggle source
# File lib/geo3d/quaternion.rb, line 118
def - quat
  self.class.new x - quat.x, y - quat.y, z - quat.z, w - quat.w
end
-@() click to toggle source
# File lib/geo3d/quaternion.rb, line 37
def -@
  self.class.new -x, -y, -z, -w
end
/(v) click to toggle source
# File lib/geo3d/quaternion.rb, line 136
def / v
  self.class.new x/v, y/v, z/v, w/v
end
==(q) click to toggle source
# File lib/geo3d/quaternion.rb, line 41
def == q
  Geo3d::Utils.float_cmp(x, q.x) && Geo3d::Utils.float_cmp(y, q.y) && Geo3d::Utils.float_cmp(z, q.z) && Geo3d::Utils.float_cmp(w, q.w)
end
angle() click to toggle source
# File lib/geo3d/quaternion.rb, line 159
def angle
  Math.acos(normalize.w) * 2.0
end
angle_degrees() click to toggle source
# File lib/geo3d/quaternion.rb, line 163
def angle_degrees
  Geo3d::Utils.to_degrees angle
end
axis() click to toggle source
# File lib/geo3d/quaternion.rb, line 155
def axis
  Vector.new( *(normalize / Math.sin( angle / 2.0 )).to_a ).zero_w
end
conjugate() click to toggle source
# File lib/geo3d/quaternion.rb, line 195
def conjugate
  self.class.new -x, -y, -z, w
end
dot(quat) click to toggle source
# File lib/geo3d/quaternion.rb, line 175
def dot quat
  x * quat.x + y * quat.y + z * quat.z + w * quat.w
end
identity?() click to toggle source
# File lib/geo3d/quaternion.rb, line 208
def identity?
  self == self.class.identity
end
inverse() click to toggle source
# File lib/geo3d/quaternion.rb, line 199
def inverse
  norm = length_squared
  if norm.zero?
    self.class.new 0, 0, 0, 0
  else
    conjugate / norm
  end
end
length() click to toggle source
# File lib/geo3d/quaternion.rb, line 171
def length
  Math.sqrt length_squared
end
length_squared() click to toggle source
# File lib/geo3d/quaternion.rb, line 167
def length_squared
  dot self
end
normalize() click to toggle source
# File lib/geo3d/quaternion.rb, line 189
def normalize
  q = self.class.new x, y, z, w
  q.normalize!
  q
end
normalize!() click to toggle source
# File lib/geo3d/quaternion.rb, line 179
def normalize!
  len = length
  if length > 0
    @x /= len
    @y /= len
    @z /= len
    @w /= len
  end
end
to_a() click to toggle source
# File lib/geo3d/quaternion.rb, line 13
def to_a
  [x,y,z,w]
end
to_matrix() click to toggle source
# File lib/geo3d/quaternion.rb, line 140
def to_matrix
  v = normalize
  matrix = Matrix.identity
  matrix._11 = 1.0 - 2.0 * (v.y * v.y + v.z * v.z)
  matrix._12 = 2.0 * (v.x * v.y + v.z * v.w)
  matrix._13 = 2.0 * (v.x * v.z - v.y * v.w)
  matrix._21 = 2.0 * (v.x * v.y - v.z * v.w)
  matrix._22 = 1.0 - 2.0 * (v.x * v.x + v.z * v.z)
  matrix._23 = 2.0 * (v.y * v.z + v.x * v.w)
  matrix._31 = 2.0 * (v.x * v.z + v.y * v.w)
  matrix._32 = 2.0 * (v.y * v.z - v.x * v.w)
  matrix._33 = 1.0 - 2.0 * (v.x * v.x + v.y * v.y)
  matrix
end
w=(v) click to toggle source
# File lib/geo3d/quaternion.rb, line 29
def w= v
  @w = v.to_f
end
x=(v) click to toggle source
# File lib/geo3d/quaternion.rb, line 17
def x= v
  @x = v.to_f
end
y=(v) click to toggle source
# File lib/geo3d/quaternion.rb, line 21
def y= v
  @y = v.to_f
end
z=(v) click to toggle source
# File lib/geo3d/quaternion.rb, line 25
def z= v
  @z = v.to_f
end