Class: GMath3D::Quat

Inherits:
Object
  • Object
show all
Defined in:
lib/quat.rb

Overview

Quat represents quaternion.

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(x = 0.0, y = 0.0, z = 0.0, w = 0.0) ⇒ Quat

Input

x, y, z, _w_should be Numeric.

Output

return new instance of Quat.



18
19
20
21
22
23
24
25
26
27
28
# File 'lib/quat.rb', line 18

def initialize(x=0.0,y=0.0,z=0.0,w=0.0)
  Util3D.check_arg_type(Numeric, x)
  Util3D.check_arg_type(Numeric, y)
  Util3D.check_arg_type(Numeric, z)
  Util3D.check_arg_type(Numeric, w)
  super()
  @x = x
  @y = y
  @z = z
  @w = w
end

Instance Attribute Details

#wObject

Returns the value of attribute w.



12
13
14
# File 'lib/quat.rb', line 12

def w
  @w
end

#xObject

Returns the value of attribute x.



9
10
11
# File 'lib/quat.rb', line 9

def x
  @x
end

#yObject

Returns the value of attribute y.



10
11
12
# File 'lib/quat.rb', line 10

def y
  @y
end

#zObject

Returns the value of attribute z.



11
12
13
# File 'lib/quat.rb', line 11

def z
  @z
end

Class Method Details

.from_axis(axis, angle) ⇒ Object

Input

axsi should be Vector3 and angle should be Numeric.

Output

return new instance of Quat.



34
35
36
37
38
39
40
41
42
43
# File 'lib/quat.rb', line 34

def self.from_axis(axis, angle)
  Util3D.check_arg_type(Vector3, axis)
  Util3D.check_arg_type(Numeric, angle)
  s = Math.sin(0.5*angle)
  x = s * axis.x
  y = s * axis.y
  z = s * axis.z
  w = Math.cos(0.5*angle)
  return Quat.new(x,y,z,w)
end

.from_matrix(mat) ⇒ Object

Input

matrix should be Matrix which row and column size are 3.

Output

return new instance of Quat.



49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
# File 'lib/quat.rb', line 49

def self.from_matrix(mat)
  fourWSquaredMinus1 = mat[0,0] + mat[1,1] + mat[2,2]
  fourXSquaredMinus1 = mat[0,0] - mat[1,1] - mat[2,2]
  fourYSquaredMinus1 = mat[1,1] - mat[0,0] - mat[2,2]
  fourZSquaredMinus1 = mat[2,2] - mat[0,0] - mat[1,1]

  biggestIndex = 0
  fourBiggestSquaredMinus1 = fourWSquaredMinus1
  if(fourXSquaredMinus1 > fourBiggestSquaredMinus1)
    fourBiggestSquaredMinus1 = fourXSquaredMinus1
    biggestIndex = 1
  end
  if(fourYSquaredMinus1 > fourBiggestSquaredMinus1)
    fourBiggestSquaredMinus1 = fourYSquaredMinus1
    biggestIndex = 2
  end
  if(fourZSquaredMinus1 > fourBiggestSquaredMinus1)
    fourBiggestSquaredMinus1 = fourZSquaredMinus1
    biggestIndex = 3
  end

  biggestVal = Math.sqrt(fourBiggestSquaredMinus1 + 1.0) * 0.5
  multi = 0.25 / biggestVal

  case biggestIndex
  when 0
    w = biggestVal
    x = (mat[1,2] - mat[2,1]) *multi
    y = (mat[2,0] - mat[0,2]) *multi
    z = (mat[0,1] - mat[1,0]) *multi
  when 1
    x = biggestVal;
    w = (mat[1,2] - mat[2,1]) *multi
    y = (mat[0,1] + mat[1,0]) *multi
    z = (mat[2,0] + mat[0,2]) *multi
  when 2
    y = biggestVal;
    w = (mat[2,0] - mat[0,2]) *multi
    x = (mat[0,1] + mat[1,0]) *multi
    z = (mat[1,2] + mat[2,1]) *multi
  when 3
    z = biggestVal;
    w = (mat[0,1] - mat[1,0]) *multi
    x = (mat[2,0] + mat[0,2]) *multi
    y = (mat[1,2] + mat[2,1]) *multi
  end
  return Quat.new(x,y,z,w)
end

Instance Method Details

#*(rhs) ⇒ Object

Input

rsh should be Quat.

Output

return (outer products) multiplyed result as Quat.



156
157
158
159
160
161
162
163
164
165
166
167
# File 'lib/quat.rb', line 156

def *(rhs)
  Util3D.check_arg_type(Quat, rhs)

  pw = self.w; px = self.x; py = self.y; pz = self.z;
  qw = rhs.w ; qx = rhs.x ; qy = rhs.y ; qz = rhs.z;

  w = pw * qw - px * qx - py * qy - pz * qz
  x = pw * qx + px * qw + py * qz - pz * qy
  y = pw * qy - px * qz + py * qw + pz * qx
  z = pw * qz + px * qy - py * qx + pz * qw
  return Quat.new( x,y,z,w )
end

#+(rhs) ⇒ Object

Input

rhs should be Quat.

Output

return added result as Quat.



136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/quat.rb', line 136

def +(rhs)
  Util3D.check_arg_type(Quat, rhs)
  t1 = Vector3.new(self.x, self.y, self.z)
  t2 = Vector3.new(rhs.x, rhs.y, rhs.z)
  dot = t1.dot(t2)
  t3 = t2.cross(t1)

  t1 *= rhs.w
  t2 *= self.w

  tf = t1 + t2 + t3
  rtn_w = self.w * rhs.w - dot

  return Quat.new(tf.x, tf.y, tf.z, rtn_w)
end

#==(rhs) ⇒ Object

Input

rhs should be Quat.

Output

return true if rhs equals myself.



110
111
112
113
114
115
116
117
# File 'lib/quat.rb', line 110

def ==(rhs)
  return false if( !rhs.kind_of?(Quat) )
  return false if(self.x != rhs.x)
  return false if(self.y != rhs.y)
  return false if(self.z != rhs.z)
  return false if(self.w != rhs.w)
  true
end

#conjugateObject

Output

return conjugated Quat.



121
122
123
# File 'lib/quat.rb', line 121

def conjugate
  return Quat.new( -self.x, -self.y, -self.z, self.w)
end

#normalizeObject

Output

return normalized result as Quat.



127
128
129
130
# File 'lib/quat.rb', line 127

def normalize()
  mag = Math.sqrt(self.x*self.x + self.y*self.y + self.z*self.z)
  return Quat.new(self.x/mag, self.y/mag, self.z/mag, self.w/mag)
end

#to_element_sObject



98
99
100
# File 'lib/quat.rb', line 98

def to_element_s
  "[#{@x}, #{@y}, #{@z}, #{@w}]"
end

#to_sObject



102
103
104
# File 'lib/quat.rb', line 102

def to_s
  "Quat" + to_element_s
end