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