Class: Quaternion
- Inherits:
-
Object
- Object
- Quaternion
- Includes:
- Math
- Defined in:
- lib/quaternion.rb,
lib/quaternion/version.rb
Overview
Class for Quaternion calculation.
Constant Summary collapse
- VERSION =
:nodoc:
"0.1.1"
Class Method Summary collapse
-
.rotation(axis, theta) ⇒ Object
Returns an instance of Quaternion for rotateion aroud
axis
with angletheta
.
Instance Method Summary collapse
-
#*(other) ⇒ Object
Returns product with
other
. -
#+(other) ⇒ Object
Returns result of addition.
-
#-(other) ⇒ Object
Returns result of subtraction q1 = Quaternion.new(1.0, 2.0, 3.0, 4.0) q2 = Quaternion.new(5.0, 4.0, 3.0, 2.0) q1 - q2 # => Quaternion(-4.0; Vector[-2.0, 0.0, 2.0]).
-
#/(other) ⇒ Object
Devision by a scalar
other
. -
#==(other) ⇒ Object
Compares with other Quaternion.
-
#[](i) ⇒ Object
Returns element
i
. -
#[]=(i, var) ⇒ Object
Sets
var
to elementi
q = Quaternion.new(1.0, 2.0, 3.0, 4.0) q = 0.0 q # => Quaternion(0.0; Vector[2.0, 3.0, 4.0]). -
#conjugate ⇒ Object
Returns conjugate of
self
q = Quaternion.new(1.0, 2.0, 3.0, 4.0) q.conjugate # => Quaternion(1.0; Vector[-2.0, -3.0, -4.0]). -
#initialize(*vars) ⇒ Quaternion
constructor
Returns an instance of Quaternion.
-
#inspect ⇒ Object
(also: #to_s)
Returns string expression of self q = Quaternion.new(1.0, 2.0, 3.0, 4.0) q.inspect # => “Quaternion(1.0; Vector[2.0, 3.0, 4.0])”.
-
#inverse ⇒ Object
Returns inverse of
self
. -
#norm ⇒ Object
(also: #magnitude)
Returns norm of
self
q = Quaternion.new(1.0, 2.0, 3.0, 4.0) q.norm # => 5.477225575051661. -
#normalize ⇒ Object
Returns normailzed Quaternion q = Quaternion.new(1.0, 2.0, 3.0, 4.0) q.normalize # => Quaternion(0.18257418583505536; Vector[0.3651483716701107, 0.5477225575051661, 0.7302967433402214]).
-
#normalize! ⇒ Object
Destructive method of Quaternion#normalize.
-
#rotate(v) ⇒ Object
Rotates a point
v
.
Constructor Details
#initialize(*vars) ⇒ Quaternion
Returns an instance of Quaternion. The following code instanciate a quaternion of q0 + q1 i + q2 j + q3 k, where q0 = 1, q1 = 2, q2 = 3 and q3 = 4.
q = Quaternion.new(1.0, 2.0, 3.0, 4.0) # => Quaternion(1.0; Vector[2.0, 3.0, 4.0])
q = Quaternion.new(1.0, [2.0, 3.0, 4.0]) # => Quaternion(1.0; Vector[2.0, 3.0, 4.0])
q = Quaternion.new(1.0, Vector[2.0, 3.0, 4.0]) # => Quaternion(1.0; Vector[2.0, 3.0, 4.0])
37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
# File 'lib/quaternion.rb', line 37 def initialize *vars case vars.size when 2 @w = vars[0] case vars[1] when Vector @v = vars[1].clone when Array @v = Vector.elements(vars[1], true) else raise ArgumentError, "Invalid type" end when 4 @w = vars[0] @v = Vector.elements(vars[1..3], true) end end |
Class Method Details
.rotation(axis, theta) ⇒ Object
Returns an instance of Quaternion for rotateion aroud axis
with angle theta
.
qrot = Quaternion.rotation([1.0, 1.0, 1.0], PI/2.0)
16 17 18 19 20 21 22 23 24 25 26 27 28 |
# File 'lib/quaternion.rb', line 16 def self.rotation axis, theta case axis when Array axis = Vector.elements(axis, true) axis = axis.normalize when Vector axis = axis.normalize else raise ArgumentError, "Invalid type" end return Quaternion.new(cos(theta/2.0), axis*sin(theta/2.0)) end |
Instance Method Details
#*(other) ⇒ Object
Returns product with other
. other
can be Quaternion or Numeric.
q = Quaternion.new(1.0, 2.0, 3.0, 4.0)
q*2 # => Quarternion(2.0; Vector[4.0, 6.0, 8.0])
q1 = Quaternion.new(1.0, 4.0, 5.0, 6.0)
q*q1 # => Quaternion(-46.0, Vector[4.0, 12.0, 8.0])
156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 |
# File 'lib/quaternion.rb', line 156 def * other case other when self.class w = @w*other[:w] - @v.inner_product(other[:v]) v = @w*other[:v] + @v*other[:w] + @v.cross_product(other[:v]) return self.class.new(w, v) when Numeric w = @w*other v = @v*other return self.class.new(w, v) else raise ArgumentError, "Invalide type" end end |
#+(other) ⇒ Object
Returns result of addition.
q1 = Quaternion.new(1.0, 2.0, 3.0, 4.0)
q2 = Quaternion.new(5.0, 6.0, 7.0, 8.0)
q1 + q2 # => Quaternion(6.0; Vector[8.0, 10.0, 12.0])
129 130 131 132 133 134 |
# File 'lib/quaternion.rb', line 129 def + other w = @w + other[:w] v = @v + other[:v] return Quaternion.new(w, v) end |
#-(other) ⇒ Object
Returns result of subtraction
q1 = Quaternion.new(1.0, 2.0, 3.0, 4.0)
q2 = Quaternion.new(5.0, 4.0, 3.0, 2.0)
q1 - q2 # => Quaternion(-4.0; Vector[-2.0, 0.0, 2.0])
141 142 143 144 145 146 |
# File 'lib/quaternion.rb', line 141 def - other w = @w - other[:w] v = @v - other[:v] return Quaternion.new(w, v) end |
#/(other) ⇒ Object
Devision by a scalar other
. Returns Quaternion with each element is divided by other
.
q = Quaternion.new(1.0, 2.0, 3.0, 4.0)
q/2 # => Quaternion(0.5; Vector[1.0, 1.5, 2.0])
178 179 180 181 182 183 184 185 186 187 188 |
# File 'lib/quaternion.rb', line 178 def / other case other when Numeric w = @w/other v = @v/other return self.class.new(w, v) else raise ArgumentError, "Invalid type" end end |
#==(other) ⇒ Object
Compares with other Quaternion
112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/quaternion.rb', line 112 def == other if other.is_a?(self.class) if (@w == other[:w]) and (@v == other[:v]) return true else return false end else return false end end |
#[](i) ⇒ Object
Returns element i
.
q = Quaternion.new(1.0, 2.0, 3.0, 4.0)
q[0] # => 1.0
q[:w] # => 1.0
q[:x] # => 2.0
q[:y] # => 3.0
q[:z] # => 4.0
q[:v] # => Vector[2.0, 3.0, 4.0]
65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 |
# File 'lib/quaternion.rb', line 65 def [] i case i when :w, 0 return @w when :x, 1 return @v[0] when :y, 2 return @v[1] when :z, 3 return @v[2] when :v return @v else raise ArgumentError, "Invalid index" end end |
#[]=(i, var) ⇒ Object
Sets var
to element i
q = Quaternion.new(1.0, 2.0, 3.0, 4.0)
q[0] = 0.0
q # => Quaternion(0.0; Vector[2.0, 3.0, 4.0])
87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/quaternion.rb', line 87 def []= i, var case i when :w, 0 @w = var when :x, 1 @v = Vector.elements([var, @v[1], @v[2]]) when :y, 2 @v = Vector.elements([@v[0], var, @v[2]]) when :z, 3 @v = Vector.elements([@v[0], @v[1], var]) when :v if var.is_a?(Array) @v = Vector.elements(var, true) elsif var.is_a?(Vector) @v = var else raise ArgumentError, "Invalid type. Should be Array or Vector" end else raise ArgumentError, "Invalid index" end end |
#conjugate ⇒ Object
Returns conjugate of self
q = Quaternion.new(1.0, 2.0, 3.0, 4.0)
q.conjugate # => Quaternion(1.0; Vector[-2.0, -3.0, -4.0])
194 195 196 |
# File 'lib/quaternion.rb', line 194 def conjugate return self.class.new(@w, -@v) end |
#inspect ⇒ Object Also known as: to_s
Returns string expression of self
q = Quaternion.new(1.0, 2.0, 3.0, 4.0)
q.inspect # => "Quaternion(1.0; Vector[2.0, 3.0, 4.0])"
238 239 240 |
# File 'lib/quaternion.rb', line 238 def inspect return "Quaternion(#{@w}; #{@v})" end |
#inverse ⇒ Object
Returns inverse of self
.
q = Quaternion.new(1.0, 2.0, 3.0, 4.0)
q.inverse # => Quaternion(0.03333333333333333; Vector[-0.06666666666666667, -0.1, -0.13333333333333333])
211 212 213 |
# File 'lib/quaternion.rb', line 211 def inverse return (self.conjugate)/(self.norm**2) end |
#norm ⇒ Object Also known as: magnitude
Returns norm of self
q = Quaternion.new(1.0, 2.0, 3.0, 4.0)
q.norm # => 5.477225575051661
202 203 204 |
# File 'lib/quaternion.rb', line 202 def norm return sqrt(@w**2 + @v.inner_product(@v)) end |
#normalize ⇒ Object
Returns normailzed Quaternion
q = Quaternion.new(1.0, 2.0, 3.0, 4.0)
q.normalize # => Quaternion(0.18257418583505536; Vector[0.3651483716701107, 0.5477225575051661, 0.7302967433402214])
219 220 221 |
# File 'lib/quaternion.rb', line 219 def normalize return self/self.magnitude end |
#normalize! ⇒ Object
Destructive method of Quaternion#normalize
225 226 227 228 229 230 231 232 |
# File 'lib/quaternion.rb', line 225 def normalize! m = self.magnitude @w /= m @v /= m return self end |
#rotate(v) ⇒ Object
Rotates a point v
. This method does not check if the quaternion’s norm is 1 or not.
qrot = Quaternion.rotation([1.0, 1.0, 1.0], PI/2.0)
qrot.rotate([1.0, 0.0, 0.0]) # =>[0.3333333333333334, 0.9106836025229592, -0.24401693585629253]
248 249 250 251 252 253 254 255 256 257 258 259 |
# File 'lib/quaternion.rb', line 248 def rotate v q_v = Quaternion.new(0.0, v) res = self*q_v*(self.conjugate) case v when Array return res[:v].to_a when Vector return res[:v] end end |