rmath3d_plain 1.0.2 → 1.2.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 3625f1baf42745a3e10bcba93e504b9c83764180
4
- data.tar.gz: e1f7590e0aa500ab797a31434cd1b3a397e2840f
2
+ SHA256:
3
+ metadata.gz: 4afeec14769aedc4dc064924600f42123b7db3001dd1d9b04887ea72226a6e62
4
+ data.tar.gz: 65f26f341e1c5c13e2e1971131132c7d641e1ac2cc1ee1abc1cc9a92c47f2731
5
5
  SHA512:
6
- metadata.gz: aba8c4dae29be93bf0beb77cc11c4a401db89fdf8e7b608d41dff379bbec96c6702c14669c23933e24df05c5d79d0500e322659f6c12a8a5818c72a09646a0c9
7
- data.tar.gz: 2b9c55755c9aa514735e63129df3d37b6486b3b83746b549ddae0a3c87e9bb0cc77ce140632b115dbf750c8aeb68535ae500106b27d9fb4fa581f9aeadcfcc69
6
+ metadata.gz: dc52e86e9d990b0bfe033c399dbcf5da0b2eefd2309b37ce539bfaf420c58fbd8a526e4723c511d92ab5f473ea7257a696126f39b79606342dcfb91840273759
7
+ data.tar.gz: a197442846a593aa7d54a63609aa9ba3eebebdd6a2fa7b984def5741f077ec3e6322770164d2e200718769635f24a1cd58b3cc1ceb5a9bf1770336e81d7a822a
data/ChangeLog CHANGED
@@ -1,3 +1,29 @@
1
+ 2020-06-21 vaiorabbit <http://twitter.com/vaiorabbit>
2
+
3
+ * rmath3d.c, rmath3d_plain.rb (RMtx4): Added argument 'ndc_homogeneous' for projection matrix APIs.
4
+ Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal)
5
+ https://www.slideshare.net/Mark_Kilgard/opengl-32-and-more/26-Direct3D_vs_OpenGL_Coordinate_System
6
+ https://metashapes.com/blog/opengl-metal-projection-matrix-problem/
7
+ * rmath3d_plain.rb: Removed Fixnum and Bignum symbols (deprecated and unified into Integer class since Ruby 2.4)
8
+
9
+ 2017-07-22 vaiorabbit <http://twitter.com/vaiorabbit>
10
+
11
+ * Added 'Integer' type for argument type branching (constant ::Fixnum is deprecated since ruby 2.4).
12
+
13
+ 2015-08-23 vaiorabbit <http://twitter.com/vaiorabbit>
14
+
15
+ * rmath3d.c (def ==): Removed control path returning Qnil.
16
+ * rmath3d_plain.rb (def ==): Removed control path returning Qnil.
17
+
18
+ 2015-05-02 vaiorabbit <http://twitter.com/vaiorabbit>
19
+
20
+ * Ruby 1.9.3 and prior versions are no longer supported. Ref.: https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended/
21
+ * rmath3d.c: Data_Get_Struct -> TypedData_Get_Struct, etc.
22
+
23
+ 2015-04-12 vaiorabbit <http://twitter.com/vaiorabbit>
24
+
25
+ * RVec2.c|h, RMtx2.c|h: Added.
26
+
1
27
  2014-05-17 vaiorabbit <http://twitter.com/vaiorabbit>
2
28
 
3
29
  * ext/rmath3d/rmath3d.c: Fixed memory management
@@ -1,5 +1,5 @@
1
1
  rmath3d : Ruby math module for 3D Applications
2
- Copyright (c) 2008-2014 vaiorabbit <http://twitter.com/vaiorabbit>
2
+ Copyright (c) 2008-2020 vaiorabbit <http://twitter.com/vaiorabbit>
3
3
 
4
4
  This software is provided 'as-is', without any express or implied
5
5
  warranty. In no event will the authors be held liable for any damages
data/README.md CHANGED
@@ -4,18 +4,23 @@
4
4
 
5
5
  rmath3d is a math module for 3D game programming and computer graphics.
6
6
 
7
- * Last Update: May 17, 2014
7
+ * Last Update: Jun 21, 2020
8
8
  * Since: Jul 20, 2008
9
9
 
10
+ * rmath3d (C Extension Library Implementation) [![Gem Version](https://badge.fury.io/rb/rmath3d.svg)](https://badge.fury.io/rb/rmath3d) [![Gem](https://img.shields.io/gem/dt/rmath3d.svg)](https://rubygems.org/gems/rmath3d)
11
+ * rmath3d_plain (Pure Ruby Implementation) [![Gem Version](https://badge.fury.io/rb/rmath3d_plain.svg)](https://badge.fury.io/rb/rmath3d_plain) [![Gem](https://img.shields.io/gem/dt/rmath3d_plain.svg)](https://rubygems.org/gems/rmath3d_plain)
12
+
10
13
  ## Features ##
11
14
 
12
15
  ### Supports frequently-used vector and matrix classes ###
13
16
 
17
+ * RMtx2 (2x2 matrix)
14
18
  * RMtx3 (3x3 matrix)
15
19
  * RMtx4 (4x4 matrix)
16
20
  * RQuat (Quaternion)
17
- * RVec3 (3 element vector)
18
- * RVec4 (4 element vector)
21
+ * RVec2 (2-element vector)
22
+ * RVec3 (3-element vector)
23
+ * RVec4 (4-element vector)
19
24
 
20
25
  ### Two implementations that are interchangeable with each other ###
21
26
 
@@ -33,6 +38,9 @@ Notice: This library provides native extension. You must setup develop environme
33
38
  * I used: DevKit-mingw64-32-4.7.2-20130224-1151-sfx.exe
34
39
  * Unpack the archive -> "> ruby dk.rb init" -> edit config.yml (just add your ruby foldier) -> "> ruby dk.rb install"
35
40
  * Ref.: http://blog.mattwynne.net/2010/10/12/installing-ruby-gems-with-native-extensions-on-windows/
41
+ * ruby 2.2.2p95 (2015-04-13 revision 50295) [x86_64-darwin14]
42
+ * Ruby 1.9.3 and prior versions are no longer supported.
43
+ * Ref.: https://www.ruby-lang.org/en/news/2015/02/23/support-for-ruby-1-9-3-has-ended/
36
44
 
37
45
  ## Building rmath3d.{so|bundle} ##
38
46
 
@@ -3,62 +3,59 @@ module RMath3D
3
3
  TOLERANCE = 1.0e-15
4
4
 
5
5
  #
6
- # Document-class: RMath3D::RMtx3
7
- # provies 3x3 matrix arithmetic.
6
+ # Document-class: RMath3D::RMtx2
7
+ # provies 2x2 matrix arithmetic.
8
8
  #
9
9
  # <b>Notice</b>
10
10
  # * elements are stored in column-major order.
11
11
  #
12
- class RMtx3
12
+ class RMtx2
13
13
 
14
14
  #
15
15
  # call-seq:
16
- # RMtx3.new -> ((1,0,0),(0,1,0),(0,0,1))
17
- # RMtx3.new(e) -> ((e,e,e), (e,e,e), (e,e,e))
18
- # RMtx3.new( other ) : Copy Constructor
19
- # RMtx3.new( e0, e1, ..., e8 ) -> ((e0,e1,e2), (e3,e4,e5), (e6,e7,e8))
16
+ # RMtx2.new -> ((1,0),(0,1))
17
+ # RMtx2.new(e) -> ((e,e), (e,e))
18
+ # RMtx2.new( other ) : Copy Constructor
19
+ # RMtx2.new( e0, e1, e2, e3 ) -> ((e0,e1), (e2,e3))
20
20
  #
21
- # Creates a new 3x3 matrix.
21
+ # Creates a new 2x2 matrix.
22
22
  #
23
23
  def initialize( *a )
24
24
  # [NOTE] elemetns are stored in column-major order.
25
25
  @e = []
26
26
  case a.length
27
27
  when 0
28
- @e = [ 0.0, 0.0, 0.0,
29
- 0.0, 0.0, 0.0,
30
- 0.0, 0.0, 0.0 ]
28
+ @e = [ 0.0, 0.0,
29
+ 0.0, 0.0 ]
31
30
  when 1
32
31
  case a[0]
33
- when Fixnum, Float
34
- @e = [ a[0], a[0], a[0],
35
- a[0], a[0], a[0],
36
- a[0], a[0], a[0] ]
37
- when RMtx3
32
+ when Float, Integer
33
+ @e = [ a[0], a[0],
34
+ a[0], a[0] ]
35
+ when RMtx2
38
36
  # Copy Constructor
39
- @e = [ a[0].e00, a[0].e10, a[0].e20,
40
- a[0].e01, a[0].e11, a[0].e21,
41
- a[0].e02, a[0].e12, a[0].e22 ]
37
+ @e = [ a[0].e00, a[0].e10,
38
+ a[0].e01, a[0].e11 ]
42
39
  else
43
- raise TypeError, "RMtx3#initialize : Unknown type #{a[0].class}."
40
+ raise TypeError, "RMtx2#initialize : Unknown type #{a[0].class}."
44
41
  return nil
45
42
  end
46
- when 9
43
+ when 4
47
44
  # Element-wise setter
48
- for row in 0...3 do
49
- for col in 0...3 do
50
- index = 3*row + col
45
+ for row in 0...2 do
46
+ for col in 0...2 do
47
+ index = 2*row + col
51
48
  case a[index]
52
- when Fixnum, Float
49
+ when Float, Integer
53
50
  setElement( row, col, a[index] )
54
51
  else
55
- raise TypeError, "RMtx3#initialize : Unknown type #{a[0].class}."
52
+ raise TypeError, "RMtx2#initialize : Unknown type #{a[0].class}."
56
53
  return nil
57
54
  end
58
55
  end
59
56
  end
60
57
  else
61
- raise RuntimeError, "RMtx3#initialize : wrong # of arguments (#{a.length})"
58
+ raise RuntimeError, "RMtx2#initialize : wrong # of arguments (#{a.length})"
62
59
  return nil
63
60
  end
64
61
 
@@ -71,9 +68,8 @@ module RMath3D
71
68
  # Returns human-readable string.
72
69
  #
73
70
  def to_s
74
- "( #{@e[0]}, #{@e[3]}, #{@e[6]} )\n" +
75
- "( #{@e[1]}, #{@e[4]}, #{@e[7]} )\n" +
76
- "( #{@e[2]}, #{@e[5]}, #{@e[8]} )\n"
71
+ "( #{@e[0]}, #{@e[2]} )\n" +
72
+ "( #{@e[1]}, #{@e[3]} )\n"
77
73
  end
78
74
 
79
75
  #
@@ -92,28 +88,28 @@ module RMath3D
92
88
  #
93
89
  def coerce
94
90
  case arg
95
- when Fixnum, Float, Bignum
91
+ when Float, Integer
96
92
  return [ self, arg ]
97
93
  else
98
- raise TypeError, "RMtx3#coerce : #{arg.self} can't be coerced into #{self.class}."
94
+ raise TypeError, "RMtx2#coerce : #{arg.self} can't be coerced into #{self.class}."
99
95
  return nil
100
96
  end
101
97
  end
102
98
 
103
99
  #
104
- # call-seq: setElements( e0, e1, ..., e8 )
100
+ # call-seq: setElements( e0, e1, e2, e3 )
105
101
  #
106
- # Stores given 9 new values.
102
+ # Stores given 4 new values.
107
103
  #
108
104
  def setElements( *a )
109
- if a.length != 9
110
- raise RuntimeError, "RMtx3#setElements : wrong # of arguments (#{a.length})"
105
+ if a.length != 4
106
+ raise RuntimeError, "RMtx2#setElements : wrong # of arguments (#{a.length})"
111
107
  return nil
112
108
  end
113
109
 
114
- for row in 0...3 do
115
- for col in 0...3 do
116
- index = 3*row + col
110
+ for row in 0...2 do
111
+ for col in 0...2 do
112
+ index = 2*row + col
117
113
  setElement( row, col, a[index] )
118
114
  end
119
115
  end
@@ -126,7 +122,7 @@ module RMath3D
126
122
  #
127
123
  def []=(row,col,value)
128
124
  # [NOTE] elemetns are stored in column-major order.
129
- @e[col*3+row] = value
125
+ @e[col*2+row] = value
130
126
  end
131
127
  alias_method :setElement, :'[]='
132
128
 
@@ -137,7 +133,7 @@ module RMath3D
137
133
  #
138
134
  def [](row,col)
139
135
  # [NOTE] elemetns are stored in column-major order.
140
- return @e[col*3+row]
136
+ return @e[col*2+row]
141
137
  end
142
138
  alias_method :getElement, :'[]'
143
139
 
@@ -145,79 +141,57 @@ module RMath3D
145
141
  def e00() getElement(0,0) end
146
142
  # Returns the element at row 0 and column 1.
147
143
  def e01() getElement(0,1) end
148
- # Returns the element at row 0 and column 2.
149
- def e02() getElement(0,2) end
150
144
  # Returns the element at row 1 and column 0.
151
145
  def e10() getElement(1,0) end
152
146
  # Returns the element at row 1 and column 1.
153
147
  def e11() getElement(1,1) end
154
- # Returns the element at row 1 and column 2.
155
- def e12() getElement(1,2) end
156
- # Returns the element at row 2 and column 0.
157
- def e20() getElement(2,0) end
158
- # Returns the element at row 2 and column 1.
159
- def e21() getElement(2,1) end
160
- # Returns the element at row 2 and column 2.
161
- def e22() getElement(2,2) end
162
148
 
163
149
  # Replaces the element at row 0 and column 0 by +value+.
164
150
  def e00=(value) setElement(0,0,value) end
165
151
  # Replaces the element at row 0 and column 1 by +value+.
166
152
  def e01=(value) setElement(0,1,value) end
167
- # Replaces the element at row 0 and column 2 by +value+.
168
- def e02=(value) setElement(0,2,value) end
169
153
  # Replaces the element at row 1 and column 0 by +value+.
170
154
  def e10=(value) setElement(1,0,value) end
171
155
  # Replaces the element at row 1 and column 1 by +value+.
172
156
  def e11=(value) setElement(1,1,value) end
173
- # Replaces the element at row 1 and column 2 by +value+.
174
- def e12=(value) setElement(1,2,value) end
175
- # Replaces the element at row 2 and column 0 by +value+.
176
- def e20=(value) setElement(2,0,value) end
177
- # Replaces the element at row 2 and column 1 by +value+.
178
- def e21=(value) setElement(2,1,value) end
179
- # Replaces the element at row 2 and column 2 by +value+.
180
- def e22=(value) setElement(2,2,value) end
181
157
 
182
158
 
183
159
  #
184
- # call-seq: mtx3.getRow(r) -> RVec3
160
+ # call-seq: mtx2.getRow(r) -> RVec2
185
161
  #
186
162
  # Returns +r+-th row vector.
187
163
  #
188
164
  def getRow( row )
189
- return RVec3.new( self[row,0], self[row,1], self[row,2] )
165
+ return RVec2.new( self[row,0], self[row,1] )
190
166
  end
191
167
 
192
168
  #
193
- # call-seq: mtx3.getColumn(c) -> RVec3
169
+ # call-seq: mtx2.getColumn(c) -> RVec2
194
170
  #
195
171
  # Returns +c+-th column vector.
196
172
  #
197
173
  def getColumn( column )
198
- return RVec3.new( self[0,column], self[1,column], self[2,column] )
174
+ return RVec2.new( self[0,column], self[1,column] )
199
175
  end
200
176
 
201
177
  #
202
- # call-seq: mtx3.setRow(v,r)
178
+ # call-seq: mtx2.setRow(v,r)
203
179
  #
204
180
  # Returns sets +r+-th row by vector +v+.
205
181
  #
206
182
  def setRow( v, row )
207
183
  self[row,0] = v.x
208
184
  self[row,1] = v.y
209
- self[row,2] = v.z
210
185
  end
211
186
 
212
187
  #
213
- # call-seq: mtx3.setColumn(v,c)
188
+ # call-seq: mtx2.setColumn(v,c)
214
189
  #
215
190
  # Returns sets +c+-th column by vector +v+.
216
191
  #
217
192
  def setColumn( v, column )
218
193
  self[0,column] = v.x
219
194
  self[1,column] = v.y
220
- self[2,column] = v.z
221
195
  end
222
196
 
223
197
  #
@@ -226,7 +200,7 @@ module RMath3D
226
200
  # Clears all elements by 0.0
227
201
  #
228
202
  def setZero
229
- 9.times do |i|
203
+ 4.times do |i|
230
204
  @e[i] = 0.0
231
205
  end
232
206
  return self
@@ -238,9 +212,9 @@ module RMath3D
238
212
  # Sets as identity matrix.
239
213
  #
240
214
  def setIdentity
241
- for row in 0...3 do
242
- for col in 0...3 do
243
- index = 3*row + col
215
+ for row in 0...2 do
216
+ for col in 0...2 do
217
+ index = 2*row + col
244
218
  if ( row == col )
245
219
  setElement( row, col, 1.0 )
246
220
  else
@@ -257,9 +231,7 @@ module RMath3D
257
231
  # Calculates determinant.
258
232
  #
259
233
  def getDeterminant
260
- e00 * (e11*e22 - e12*e21) -
261
- e01 * (e10*e22 - e12*e20) +
262
- e02 * (e10*e21 - e11*e20)
234
+ e00 * e11 - e01 * e10
263
235
  end
264
236
 
265
237
  #
@@ -268,9 +240,8 @@ module RMath3D
268
240
  # Returns transposed matrix.
269
241
  #
270
242
  def getTransposed
271
- return RMtx3.new( @e[0], @e[1], @e[2],
272
- @e[3], @e[4], @e[5],
273
- @e[6], @e[7], @e[8] )
243
+ return RMtx2.new( @e[0], @e[1],
244
+ @e[2], @e[3] )
274
245
  end
275
246
 
276
247
  #
@@ -279,9 +250,7 @@ module RMath3D
279
250
  # Transposeas its elements.
280
251
  #
281
252
  def transpose!
282
- @e[1], @e[3] = @e[3], @e[1]
283
- @e[2], @e[6] = @e[6], @e[2]
284
- @e[5], @e[7] = @e[7], @e[5]
253
+ @e[1], @e[2] = @e[2], @e[1]
285
254
  end
286
255
 
287
256
  #
@@ -290,27 +259,21 @@ module RMath3D
290
259
  # Returns the inverse.
291
260
  #
292
261
  def getInverse
293
- result = RMtx3.new
294
-
295
- result.e00 = (self.e11*self.e22 - self.e12*self.e21)
296
- result.e01 = -(self.e01*self.e22 - self.e02*self.e21)
297
- result.e02 = (self.e01*self.e12 - self.e02*self.e11)
298
-
299
- result.e10 = -(self.e10*self.e22 - self.e12*self.e20)
300
- result.e11 = (self.e00*self.e22 - self.e02*self.e20)
301
- result.e12 = -(self.e00*self.e12 - self.e02*self.e10)
302
-
303
- result.e20 = (self.e10*self.e21 - self.e11*self.e20)
304
- result.e21 = -(self.e00*self.e21 - self.e01*self.e20)
305
- result.e22 = (self.e00*self.e11 - self.e01*self.e10)
306
-
307
- det = e00 * result.e00 + e01 * result.e10 + e02 * result.e20
262
+ det = getDeterminant()
308
263
 
309
264
  if ( det.abs < TOLERANCE )
310
- raise RuntimeError, "RMtx3#getInverse : det.abs < TOLERANCE"
265
+ raise RuntimeError, "RMtx2#getInverse : det.abs < TOLERANCE"
311
266
  return nil
312
267
  end
313
268
 
269
+ result = RMtx2.new
270
+
271
+ result.e00 = self.e11
272
+ result.e01 = -self.e01
273
+
274
+ result.e10 = -self.e10
275
+ result.e11 = self.e00
276
+
314
277
  d = 1.0 / det
315
278
 
316
279
  result.mul!( d )
@@ -324,84 +287,38 @@ module RMath3D
324
287
  # Makes itself as the inverse of the original matrix.
325
288
  #
326
289
  def invert!
327
- elements = Array.new( 9 )
328
-
329
- elements[3*0+0] = (self.e11*self.e22 - self.e12*self.e21)
330
- elements[3*0+1] = -(self.e01*self.e22 - self.e02*self.e21)
331
- elements[3*0+2] = (self.e01*self.e12 - self.e02*self.e11)
332
-
333
- elements[3*1+0] = -(self.e10*self.e22 - self.e12*self.e20)
334
- elements[3*1+1] = (self.e00*self.e22 - self.e02*self.e20)
335
- elements[3*1+2] = -(self.e00*self.e12 - self.e02*self.e10)
336
-
337
- elements[3*2+0] = (self.e10*self.e21 - self.e11*self.e20)
338
- elements[3*2+1] = -(self.e00*self.e21 - self.e01*self.e20)
339
- elements[3*2+2] = (self.e00*self.e11 - self.e01*self.e10)
340
-
341
- det = e00 * elements[3*0+0] + e01 * elements[3*1+0] + e02 * elements[3*2+0]
290
+ det = getDeterminant()
342
291
 
343
292
  if ( det.abs < TOLERANCE )
344
- raise RuntimeError, "RMtx3#invert! : det.abs < TOLERANCE"
293
+ raise RuntimeError, "RMtx2#invert! : det.abs < TOLERANCE"
345
294
  return nil
346
295
  end
347
296
 
348
- d = 1.0 / det
349
-
350
- setElement( 0, 0, d * elements[3*0+0] )
351
- setElement( 0, 1, d * elements[3*0+1] )
352
- setElement( 0, 2, d * elements[3*0+2] )
353
- setElement( 1, 0, d * elements[3*1+0] )
354
- setElement( 1, 1, d * elements[3*1+1] )
355
- setElement( 1, 2, d * elements[3*1+2] )
356
- setElement( 2, 0, d * elements[3*2+0] )
357
- setElement( 2, 1, d * elements[3*2+1] )
358
- setElement( 2, 2, d * elements[3*2+2] )
359
-
360
- return self
361
- end
297
+ elements = Array.new( 4 )
362
298
 
363
- #
364
- # call-seq: rotationX(radian) -> self
365
- #
366
- # Makes a matrix that rotates around the x-axis.
367
- #
368
- def rotationX( radian )
369
- s = Math.sin( radian )
370
- c = Math.cos( radian )
299
+ elements[2*0+0] = self.e11
300
+ elements[2*0+1] = -self.e01
371
301
 
372
- setIdentity()
373
- self.e11 = c
374
- self.e12 = -s
375
- self.e21 = s
376
- self.e22 = c
302
+ elements[2*1+0] = -self.e10
303
+ elements[2*1+1] = self.e00
377
304
 
378
- return self
379
- end
305
+ d = 1.0 / det
380
306
 
381
- #
382
- # call-seq: rotationY(radian) -> self
383
- #
384
- # Makes a matrix that rotates around the y-axis.
385
- #
386
- def rotationY( radian )
387
- s = Math.sin( radian )
388
- c = Math.cos( radian )
307
+ setElement( 0, 0, d * elements[2*0+0] )
308
+ setElement( 0, 1, d * elements[2*0+1] )
389
309
 
390
- setIdentity()
391
- self.e00 = c
392
- self.e02 = s
393
- self.e20 = -s
394
- self.e22 = c
310
+ setElement( 1, 0, d * elements[2*1+0] )
311
+ setElement( 1, 1, d * elements[2*1+1] )
395
312
 
396
313
  return self
397
314
  end
398
315
 
399
316
  #
400
- # call-seq: rotationZ(radian) -> self
317
+ # call-seq: rotation(radian) -> self
401
318
  #
402
319
  # Makes a matrix that rotates around the z-axis.
403
320
  #
404
- def rotationZ( radian )
321
+ def rotation( radian )
405
322
  s = Math.sin( radian )
406
323
  c = Math.cos( radian )
407
324
 
@@ -415,88 +332,14 @@ module RMath3D
415
332
  end
416
333
 
417
334
  #
418
- # call-seq: rotationAxis(axis,radian) -> self
419
- #
420
- # Makes a matrix that rotates around the +axis+.
421
- #
422
- def rotationAxis( axis, radian )
423
- if ( axis.class != RVec3 )
424
- raise TypeError, "RMtx3#rotationAxis : Unknown type #{axis.class} given as axis."
425
- return nil
426
- end
427
- s = Math.sin( radian )
428
- c = Math.cos( radian )
429
- omc = 1.0 - c
430
- x = axis.x.to_f
431
- y = axis.y.to_f
432
- z = axis.z.to_f
433
-
434
- self.e00 = x*x*omc + c
435
- self.e01 = x*y*omc - z*s
436
- self.e02 = z*x*omc + y*s
437
- self.e10 = x*y*omc + z*s
438
- self.e11 = y*y*omc + c
439
- self.e12 = y*z*omc - x*s
440
- self.e20 = z*x*omc - y*s
441
- self.e21 = y*z*omc + x*s
442
- self.e22 = z*z*omc + c
443
-
444
- return self
445
- end
446
-
447
- #
448
- # call-seq: rotationQuaternion(q) -> self
449
- #
450
- # Makes a rotation matrix from a normalized quaternion +q+.
451
- #
452
- def rotationQuaternion( q )
453
- if ( q.class != RQuat )
454
- raise TypeError, "RMtx3#rotationQuaternion : Unknown type #{q.class} given as RQuat."
455
- return nil
456
- end
457
- x = q.x
458
- y = q.y
459
- z = q.z
460
- w = q.w
461
-
462
- x2 = 2.0 * x
463
- y2 = 2.0 * y
464
- z2 = 2.0 * z
465
-
466
- xx2 = x * x2
467
- yy2 = y * y2
468
- zz2 = z * z2
469
-
470
- yz2 = y * z2
471
- wx2 = w * x2
472
- xy2 = x * y2
473
- wz2 = w * z2
474
- xz2 = x * z2
475
- wy2 = w * y2
476
-
477
- self.e00 = 1.0 - yy2 - zz2
478
- self.e10 = xy2 + wz2
479
- self.e20 = xz2 - wy2
480
- self.e01 = xy2 - wz2
481
- self.e11 = 1.0 - xx2 - zz2
482
- self.e21 = yz2 + wx2
483
- self.e02 = xz2 + wy2
484
- self.e12 = yz2 - wx2
485
- self.e22 = 1.0 - xx2 - yy2
486
-
487
- return self
488
- end
489
-
490
- #
491
- # call-seq: scaling(sx,sy,sz) -> self
335
+ # call-seq: scaling(sx,sy) -> self
492
336
  #
493
337
  # Makes itself as a scaling matrix.
494
338
  #
495
- def scaling( sx, sy, sz )
339
+ def scaling( sx, sy )
496
340
  setIdentity()
497
341
  setElement( 0, 0, sx )
498
342
  setElement( 1, 1, sy )
499
- setElement( 2, 2, sz )
500
343
 
501
344
  return self
502
345
  end
@@ -516,7 +359,7 @@ module RMath3D
516
359
  # -mtx : Unary minus operator.
517
360
  #
518
361
  def -@
519
- return RMtx3.new( self * -1.0 )
362
+ return RMtx2.new( self * -1.0 )
520
363
  end
521
364
 
522
365
  #
@@ -525,14 +368,14 @@ module RMath3D
525
368
  # mtx1 + mtx2 : Binary plus operator.
526
369
  #
527
370
  def +( arg )
528
- if ( arg.class != RMtx3 )
529
- raise TypeError, "RMtx3#+(arg) : Unknown type #{arg.class} given as RMtx3."
371
+ if ( arg.class != RMtx2 )
372
+ raise TypeError, "RMtx2#+(arg) : Unknown type #{arg.class} given as RMtx2."
530
373
  return nil
531
374
  end
532
375
 
533
- result = RMtx3.new
534
- for row in 0...3 do
535
- for col in 0...3 do
376
+ result = RMtx2.new
377
+ for row in 0...2 do
378
+ for col in 0...2 do
536
379
  result.setElement( row, col, getElement(row,col) + arg.getElement(row,col) )
537
380
  end
538
381
  end
@@ -546,14 +389,14 @@ module RMath3D
546
389
  # mtx1 - mtx2 : Binary minus operator.
547
390
  #
548
391
  def -( arg )
549
- if ( arg.class != RMtx3 )
550
- raise TypeError, "RMtx3#-(arg) : Unknown type #{arg.class} given as RMtx3."
392
+ if ( arg.class != RMtx2 )
393
+ raise TypeError, "RMtx2#-(arg) : Unknown type #{arg.class} given as RMtx2."
551
394
  return nil
552
395
  end
553
396
 
554
- result = RMtx3.new
555
- for row in 0...3 do
556
- for col in 0...3 do
397
+ result = RMtx2.new
398
+ for row in 0...2 do
399
+ for col in 0...2 do
557
400
  result.setElement( row, col, getElement(row,col) - arg.getElement(row,col) )
558
401
  end
559
402
  end
@@ -568,17 +411,16 @@ module RMath3D
568
411
  #
569
412
  def *( arg )
570
413
  case arg
571
- when Fixnum, Float, Bignum
572
- return RMtx3.new( arg*self.e00, arg*self.e01, arg*self.e02,
573
- arg*self.e10, arg*self.e11, arg*self.e12,
574
- arg*self.e20, arg*self.e21, arg*self.e22 )
575
-
576
- when RMtx3
577
- result = RMtx3.new
578
- for row in 0...3 do
579
- for col in 0...3 do
414
+ when Float, Integer
415
+ return RMtx2.new( arg*self.e00, arg*self.e01,
416
+ arg*self.e10, arg*self.e11 )
417
+
418
+ when RMtx2
419
+ result = RMtx2.new
420
+ for row in 0...2 do
421
+ for col in 0...2 do
580
422
  sum = 0.0
581
- for i in 0...3 do
423
+ for i in 0...2 do
582
424
  sum += getElement( row, i ) * arg.getElement( i, col )
583
425
  end
584
426
  result.setElement( row, col, sum )
@@ -587,7 +429,7 @@ module RMath3D
587
429
  return result
588
430
 
589
431
  else
590
- raise TypeError, "RMtx3#*(arg) : Unknown type #{arg.class} given."
432
+ raise TypeError, "RMtx2#*(arg) : Unknown type #{arg.class} given."
591
433
  return nil
592
434
  end
593
435
  end
@@ -598,19 +440,18 @@ module RMath3D
598
440
  # mtx1 == mtx2 : evaluates equality.
599
441
  #
600
442
  def ==( other )
601
- if ( other.class != RMtx3 )
602
- raise TypeError, "RMtx3#==(other) : Unknown type #{other.class} given as RMtx3."
603
- return nil
604
- end
605
-
606
- for row in 0...3 do
607
- for col in 0...3 do
608
- if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
609
- return false
443
+ if other.class == RMtx2
444
+ for row in 0...2 do
445
+ for col in 0...2 do
446
+ if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
447
+ return false
448
+ end
610
449
  end
611
450
  end
451
+ return true
452
+ else
453
+ return false
612
454
  end
613
- return true
614
455
  end
615
456
 
616
457
  #
@@ -619,14 +460,14 @@ module RMath3D
619
460
  # mtx1 += mtx2 : appends the elements of +mtx2+ into corresponding +mtx1+ elements.
620
461
  #
621
462
  def add!( other )
622
- if ( other.class != RMtx3 )
623
- raise TypeError, "RMtx3#add! : Unknown type #{other.class} given as RMtx3."
463
+ if ( other.class != RMtx2 )
464
+ raise TypeError, "RMtx2#add! : Unknown type #{other.class} given as RMtx2."
624
465
  return nil
625
466
  end
626
467
 
627
- result = RMtx3.new
628
- for row in 0...3 do
629
- for col in 0...3 do
468
+ result = RMtx2.new
469
+ for row in 0...2 do
470
+ for col in 0...2 do
630
471
  self.setElement( row, col, getElement(row,col) + other.getElement(row,col) )
631
472
  end
632
473
  end
@@ -640,14 +481,14 @@ module RMath3D
640
481
  # mtx1 -= mtx2 : subtracts the elements of +mtx2+ from corresponding +mtx1+ elements.
641
482
  #
642
483
  def sub!( other )
643
- if ( other.class != RMtx3 )
644
- raise TypeError, "RMtx3#sub! : Unknown type #{other.class} given as RMtx3."
484
+ if ( other.class != RMtx2 )
485
+ raise TypeError, "RMtx2#sub! : Unknown type #{other.class} given as RMtx2."
645
486
  return nil
646
487
  end
647
488
 
648
- result = RMtx3.new
649
- for row in 0...3 do
650
- for col in 0...3 do
489
+ result = RMtx2.new
490
+ for row in 0...2 do
491
+ for col in 0...2 do
651
492
  self.setElement( row, col, getElement(row,col) - other.getElement(row,col) )
652
493
  end
653
494
  end
@@ -662,24 +503,19 @@ module RMath3D
662
503
  #
663
504
  def mul!( other )
664
505
  case other
665
- when Fixnum, Float, Bignum
506
+ when Float, Integer
666
507
  self.e00 = other*self.e00
667
508
  self.e01 = other*self.e01
668
- self.e02 = other*self.e02
669
509
  self.e10 = other*self.e10
670
510
  self.e11 = other*self.e11
671
- self.e12 = other*self.e12
672
- self.e20 = other*self.e20
673
- self.e21 = other*self.e21
674
- self.e22 = other*self.e22
675
511
 
676
512
  return self
677
- when RMtx3
678
- result = RMtx3.new
679
- for row in 0...3 do
680
- for col in 0...3 do
513
+ when RMtx2
514
+ result = RMtx2.new
515
+ for row in 0...2 do
516
+ for col in 0...2 do
681
517
  sum = 0.0
682
- for i in 0...3 do
518
+ for i in 0...2 do
683
519
  sum += getElement( row, i ) * other.getElement( i, col )
684
520
  end
685
521
  result.setElement( row, col, sum )
@@ -688,13 +524,8 @@ module RMath3D
688
524
 
689
525
  self.e00 = result.e00
690
526
  self.e01 = result.e01
691
- self.e02 = result.e02
692
527
  self.e10 = result.e10
693
528
  self.e11 = result.e11
694
- self.e12 = result.e12
695
- self.e20 = result.e20
696
- self.e21 = result.e21
697
- self.e22 = result.e22
698
529
 
699
530
  return self
700
531
  end
@@ -702,65 +533,62 @@ module RMath3D
702
533
  end
703
534
 
704
535
  #
705
- # Document-class: RMath3D::RMtx4
706
- # provies 4x4 matrix arithmetic.
536
+ # Document-class: RMath3D::RMtx3
537
+ # provies 3x3 matrix arithmetic.
707
538
  #
708
539
  # <b>Notice</b>
709
540
  # * elements are stored in column-major order.
710
541
  #
711
- class RMtx4
542
+ class RMtx3
712
543
 
713
544
  #
714
545
  # call-seq:
715
- # RMtx4.new -> ((1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1))
716
- # RMtx4.new(e) -> ((e,e,e,e),(e,e,e,e),(e,e,e,e),(e,e,e,e))
717
- # RMtx4.new( other ) : Copy Constructor
718
- # RMtx4.new( e0, e1, ..., e15 ) -> ((e0,e1,e2,e3),(e4,e5,e6,e7),(e8,e9,e10,e11),(e12,e13,e14,e15))
546
+ # RMtx3.new -> ((1,0,0),(0,1,0),(0,0,1))
547
+ # RMtx3.new(e) -> ((e,e,e), (e,e,e), (e,e,e))
548
+ # RMtx3.new( other ) : Copy Constructor
549
+ # RMtx3.new( e0, e1, ..., e8 ) -> ((e0,e1,e2), (e3,e4,e5), (e6,e7,e8))
719
550
  #
720
- # Creates a new 4x4 matrix.
551
+ # Creates a new 3x3 matrix.
721
552
  #
722
553
  def initialize( *a )
723
554
  # [NOTE] elemetns are stored in column-major order.
724
555
  @e = []
725
556
  case a.length
726
557
  when 0
727
- @e = [ 0.0, 0.0, 0.0, 0.0,
728
- 0.0, 0.0, 0.0, 0.0,
729
- 0.0, 0.0, 0.0, 0.0,
730
- 0.0, 0.0, 0.0, 0.0 ]
558
+ @e = [ 0.0, 0.0, 0.0,
559
+ 0.0, 0.0, 0.0,
560
+ 0.0, 0.0, 0.0 ]
731
561
  when 1
732
562
  case a[0]
733
- when Fixnum, Float
734
- @e = [ a[0], a[0], a[0], a[0],
735
- a[0], a[0], a[0], a[0],
736
- a[0], a[0], a[0], a[0],
737
- a[0], a[0], a[0], a[0] ]
738
- when RMtx4
563
+ when Float, Integer
564
+ @e = [ a[0], a[0], a[0],
565
+ a[0], a[0], a[0],
566
+ a[0], a[0], a[0] ]
567
+ when RMtx3
739
568
  # Copy Constructor
740
- @e = [ a[0].e00, a[0].e10, a[0].e20, a[0].e30,
741
- a[0].e01, a[0].e11, a[0].e21, a[0].e31,
742
- a[0].e02, a[0].e12, a[0].e22, a[0].e32,
743
- a[0].e03, a[0].e13, a[0].e23, a[0].e33 ]
569
+ @e = [ a[0].e00, a[0].e10, a[0].e20,
570
+ a[0].e01, a[0].e11, a[0].e21,
571
+ a[0].e02, a[0].e12, a[0].e22 ]
744
572
  else
745
- raise TypeError, "RMtx4#initialize : Unknown type #{a[0].class}."
573
+ raise TypeError, "RMtx3#initialize : Unknown type #{a[0].class}."
746
574
  return nil
747
575
  end
748
- when 16
576
+ when 9
749
577
  # Element-wise setter
750
- for row in 0...4 do
751
- for col in 0...4 do
752
- index = 4*row + col
578
+ for row in 0...3 do
579
+ for col in 0...3 do
580
+ index = 3*row + col
753
581
  case a[index]
754
- when Fixnum, Float
582
+ when Float, Integer
755
583
  setElement( row, col, a[index] )
756
584
  else
757
- raise TypeError, "RMtx4#initialize : Unknown type #{a[0].class}."
585
+ raise TypeError, "RMtx3#initialize : Unknown type #{a[0].class}."
758
586
  return nil
759
587
  end
760
588
  end
761
589
  end
762
590
  else
763
- raise RuntimeError, "RMtx4#initialize : wrong # of arguments (#{a.length})"
591
+ raise RuntimeError, "RMtx3#initialize : wrong # of arguments (#{a.length})"
764
592
  return nil
765
593
  end
766
594
 
@@ -773,10 +601,9 @@ module RMath3D
773
601
  # Returns human-readable string.
774
602
  #
775
603
  def to_s
776
- "( #{@e[0]}, #{@e[4]}, #{@e[8]}, #{@e[12]} )\n" +
777
- "( #{@e[1]}, #{@e[5]}, #{@e[9]}, #{@e[13]} )\n" +
778
- "( #{@e[2]}, #{@e[6]}, #{@e[10]}, #{@e[14]} )\n" +
779
- "( #{@e[3]}, #{@e[7]}, #{@e[11]}, #{@e[15]} )\n"
604
+ "( #{@e[0]}, #{@e[3]}, #{@e[6]} )\n" +
605
+ "( #{@e[1]}, #{@e[4]}, #{@e[7]} )\n" +
606
+ "( #{@e[2]}, #{@e[5]}, #{@e[8]} )\n"
780
607
  end
781
608
 
782
609
  #
@@ -795,28 +622,28 @@ module RMath3D
795
622
  #
796
623
  def coerce
797
624
  case arg
798
- when Fixnum, Float, Bignum
625
+ when Float, Integer
799
626
  return [ self, arg ]
800
627
  else
801
- raise TypeError, "RMtx4#coerce : #{arg.self} can't be coerced into #{self.class}."
628
+ raise TypeError, "RMtx3#coerce : #{arg.self} can't be coerced into #{self.class}."
802
629
  return nil
803
630
  end
804
631
  end
805
632
 
806
633
  #
807
- # call-seq: setElements( e0, e1, ..., e15 )
634
+ # call-seq: setElements( e0, e1, ..., e8 )
808
635
  #
809
- # Stores given 16 new values.
636
+ # Stores given 9 new values.
810
637
  #
811
638
  def setElements( *a )
812
- if a.length != 16
813
- raise RuntimeError, "RMtx4#setElements : wrong # of arguments (#{a.length})"
639
+ if a.length != 9
640
+ raise RuntimeError, "RMtx3#setElements : wrong # of arguments (#{a.length})"
814
641
  return nil
815
642
  end
816
643
 
817
- for row in 0...4 do
818
- for col in 0...4 do
819
- index = 4*row + col
644
+ for row in 0...3 do
645
+ for col in 0...3 do
646
+ index = 3*row + col
820
647
  setElement( row, col, a[index] )
821
648
  end
822
649
  end
@@ -829,7 +656,7 @@ module RMath3D
829
656
  #
830
657
  def []=(row,col,value)
831
658
  # [NOTE] elemetns are stored in column-major order.
832
- @e[col*4+row] = value
659
+ @e[col*3+row] = value
833
660
  end
834
661
  alias_method :setElement, :'[]='
835
662
 
@@ -840,7 +667,7 @@ module RMath3D
840
667
  #
841
668
  def [](row,col)
842
669
  # [NOTE] elemetns are stored in column-major order.
843
- return @e[col*4+row]
670
+ return @e[col*3+row]
844
671
  end
845
672
  alias_method :getElement, :'[]'
846
673
 
@@ -850,32 +677,18 @@ module RMath3D
850
677
  def e01() getElement(0,1) end
851
678
  # Returns the element at row 0 and column 2.
852
679
  def e02() getElement(0,2) end
853
- # Returns the element at row 0 and column 3.
854
- def e03() getElement(0,3) end
855
680
  # Returns the element at row 1 and column 0.
856
681
  def e10() getElement(1,0) end
857
682
  # Returns the element at row 1 and column 1.
858
683
  def e11() getElement(1,1) end
859
684
  # Returns the element at row 1 and column 2.
860
685
  def e12() getElement(1,2) end
861
- # Returns the element at row 1 and column 3.
862
- def e13() getElement(1,3) end
863
686
  # Returns the element at row 2 and column 0.
864
687
  def e20() getElement(2,0) end
865
688
  # Returns the element at row 2 and column 1.
866
689
  def e21() getElement(2,1) end
867
690
  # Returns the element at row 2 and column 2.
868
691
  def e22() getElement(2,2) end
869
- # Returns the element at row 2 and column 3.
870
- def e23() getElement(2,3) end
871
- # Returns the element at row 3 and column 0.
872
- def e30() getElement(3,0) end
873
- # Returns the element at row 3 and column 1.
874
- def e31() getElement(3,1) end
875
- # Returns the element at row 3 and column 2.
876
- def e32() getElement(3,2) end
877
- # Returns the element at row 3 and column 3.
878
- def e33() getElement(3,3) end
879
692
 
880
693
  # Replaces the element at row 0 and column 0 by +value+.
881
694
  def e00=(value) setElement(0,0,value) end
@@ -883,53 +696,40 @@ module RMath3D
883
696
  def e01=(value) setElement(0,1,value) end
884
697
  # Replaces the element at row 0 and column 2 by +value+.
885
698
  def e02=(value) setElement(0,2,value) end
886
- # Replaces the element at row 0 and column 3 by +value+.
887
- def e03=(value) setElement(0,3,value) end
888
699
  # Replaces the element at row 1 and column 0 by +value+.
889
700
  def e10=(value) setElement(1,0,value) end
890
701
  # Replaces the element at row 1 and column 1 by +value+.
891
702
  def e11=(value) setElement(1,1,value) end
892
703
  # Replaces the element at row 1 and column 2 by +value+.
893
704
  def e12=(value) setElement(1,2,value) end
894
- # Replaces the element at row 1 and column 3 by +value+.
895
- def e13=(value) setElement(1,3,value) end
896
705
  # Replaces the element at row 2 and column 0 by +value+.
897
706
  def e20=(value) setElement(2,0,value) end
898
707
  # Replaces the element at row 2 and column 1 by +value+.
899
708
  def e21=(value) setElement(2,1,value) end
900
709
  # Replaces the element at row 2 and column 2 by +value+.
901
710
  def e22=(value) setElement(2,2,value) end
902
- # Replaces the element at row 2 and column 3 by +value+.
903
- def e23=(value) setElement(2,3,value) end
904
- # Replaces the element at row 3 and column 0 by +value+.
905
- def e30=(value) setElement(3,0,value) end
906
- # Replaces the element at row 3 and column 1 by +value+.
907
- def e31=(value) setElement(3,1,value) end
908
- # Replaces the element at row 3 and column 2 by +value+.
909
- def e32=(value) setElement(3,2,value) end
910
- # Replaces the element at row 3 and column 3 by +value+.
911
- def e33=(value) setElement(3,3,value) end
711
+
912
712
 
913
713
  #
914
- # call-seq: mtx4.getRow(r) -> RVec4
714
+ # call-seq: mtx3.getRow(r) -> RVec3
915
715
  #
916
716
  # Returns +r+-th row vector.
917
717
  #
918
718
  def getRow( row )
919
- return RVec4.new( self[row,0], self[row,1], self[row,2], self[row,3] )
719
+ return RVec3.new( self[row,0], self[row,1], self[row,2] )
920
720
  end
921
721
 
922
722
  #
923
- # call-seq: mtx4.getColumn(c) -> RVec4
723
+ # call-seq: mtx3.getColumn(c) -> RVec3
924
724
  #
925
725
  # Returns +c+-th column vector.
926
726
  #
927
727
  def getColumn( column )
928
- return RVec4.new( self[0,column], self[1,column], self[2,column], self[3,column] )
728
+ return RVec3.new( self[0,column], self[1,column], self[2,column] )
929
729
  end
930
730
 
931
731
  #
932
- # call-seq: mtx4.setRow(v,r)
732
+ # call-seq: mtx3.setRow(v,r)
933
733
  #
934
734
  # Returns sets +r+-th row by vector +v+.
935
735
  #
@@ -937,11 +737,10 @@ module RMath3D
937
737
  self[row,0] = v.x
938
738
  self[row,1] = v.y
939
739
  self[row,2] = v.z
940
- self[row,3] = v.w
941
740
  end
942
741
 
943
742
  #
944
- # call-seq: mtx4.setColumn(v,c)
743
+ # call-seq: mtx3.setColumn(v,c)
945
744
  #
946
745
  # Returns sets +c+-th column by vector +v+.
947
746
  #
@@ -949,35 +748,15 @@ module RMath3D
949
748
  self[0,column] = v.x
950
749
  self[1,column] = v.y
951
750
  self[2,column] = v.z
952
- self[3,column] = v.w
953
- end
954
-
955
- def getUpper3x3
956
- return RMtx3.new( self.e00, self.e01, self.e02,
957
- self.e10, self.e11, self.e12,
958
- self.e20, self.e21, self.e22 )
959
- end
960
-
961
- def setUpper3x3( mtx3x3 )
962
- self.e00 = mtx3x3.e00
963
- self.e01 = mtx3x3.e01
964
- self.e02 = mtx3x3.e02
965
- self.e10 = mtx3x3.e10
966
- self.e11 = mtx3x3.e11
967
- self.e12 = mtx3x3.e12
968
- self.e20 = mtx3x3.e20
969
- self.e21 = mtx3x3.e21
970
- self.e22 = mtx3x3.e22
971
-
972
- return self
973
751
  end
974
752
 
753
+ #
975
754
  # call-seq: setZero
976
755
  #
977
756
  # Clears all elements by 0.0
978
757
  #
979
758
  def setZero
980
- 16.times do |i|
759
+ 9.times do |i|
981
760
  @e[i] = 0.0
982
761
  end
983
762
  return self
@@ -989,9 +768,9 @@ module RMath3D
989
768
  # Sets as identity matrix.
990
769
  #
991
770
  def setIdentity
992
- for row in 0...4 do
993
- for col in 0...4 do
994
- index = 4*row + col
771
+ for row in 0...3 do
772
+ for col in 0...3 do
773
+ index = 3*row + col
995
774
  if ( row == col )
996
775
  setElement( row, col, 1.0 )
997
776
  else
@@ -1002,23 +781,15 @@ module RMath3D
1002
781
  return self
1003
782
  end
1004
783
 
1005
- def det3( _e00,_e01,_e02, _e10,_e11,_e12, _e20,_e21,_e22 )
1006
- _e00 * (_e11*_e22 - _e12*_e21) -
1007
- _e01 * (_e10*_e22 - _e12*_e20) +
1008
- _e02 * (_e10*_e21 - _e11*_e20)
1009
- end
1010
- private :det3
1011
-
1012
784
  #
1013
785
  # call-seq: getDeterminant -> determinant
1014
786
  #
1015
787
  # Calculates determinant.
1016
788
  #
1017
789
  def getDeterminant
1018
- e00 * det3( e11,e12,e13, e21,e22,e23, e31,e32,e33 ) -
1019
- e01 * det3( e10,e12,e13, e20,e22,e23, e30,e32,e33 ) +
1020
- e02 * det3( e10,e11,e13, e20,e21,e23, e30,e31,e33 ) -
1021
- e03 * det3( e10,e11,e12, e20,e21,e22, e30,e31,e32 )
790
+ e00 * (e11*e22 - e12*e21) -
791
+ e01 * (e10*e22 - e12*e20) +
792
+ e02 * (e10*e21 - e11*e20)
1022
793
  end
1023
794
 
1024
795
  #
@@ -1027,10 +798,9 @@ module RMath3D
1027
798
  # Returns transposed matrix.
1028
799
  #
1029
800
  def getTransposed
1030
- return RMtx4.new( @e[ 0], @e[ 1], @e[ 2], @e[ 3],
1031
- @e[ 4], @e[ 5], @e[ 6], @e[ 7],
1032
- @e[ 8], @e[ 9], @e[10], @e[11],
1033
- @e[12], @e[13], @e[14], @e[15] )
801
+ return RMtx3.new( @e[0], @e[1], @e[2],
802
+ @e[3], @e[4], @e[5],
803
+ @e[6], @e[7], @e[8] )
1034
804
  end
1035
805
 
1036
806
  #
@@ -1039,12 +809,9 @@ module RMath3D
1039
809
  # Transposeas its elements.
1040
810
  #
1041
811
  def transpose!
1042
- @e[ 1], @e[ 4] = @e[ 4], @e[ 1]
1043
- @e[ 2], @e[ 8] = @e[ 8], @e[ 2]
1044
- @e[ 3], @e[12] = @e[12], @e[ 3]
1045
- @e[ 6], @e[ 9] = @e[ 9], @e[ 6]
1046
- @e[ 7], @e[13] = @e[13], @e[ 7]
1047
- @e[11], @e[14] = @e[14], @e[11]
812
+ @e[1], @e[3] = @e[3], @e[1]
813
+ @e[2], @e[6] = @e[6], @e[2]
814
+ @e[5], @e[7] = @e[7], @e[5]
1048
815
  end
1049
816
 
1050
817
  #
@@ -1053,32 +820,24 @@ module RMath3D
1053
820
  # Returns the inverse.
1054
821
  #
1055
822
  def getInverse
1056
- result = RMtx4.new
1057
-
1058
- result.e00 = det3( e11,e12,e13, e21,e22,e23, e31,e32,e33 )
1059
- result.e01 = -det3( e01,e02,e03, e21,e22,e23, e31,e32,e33 )
1060
- result.e02 = det3( e01,e02,e03, e11,e12,e13, e31,e32,e33 )
1061
- result.e03 = -det3( e01,e02,e03, e11,e12,e13, e21,e22,e23 )
823
+ result = RMtx3.new
1062
824
 
1063
- result.e10 = -det3( e10,e12,e13, e20,e22,e23, e30,e32,e33 )
1064
- result.e11 = det3( e00,e02,e03, e20,e22,e23, e30,e32,e33 )
1065
- result.e12 = -det3( e00,e02,e03, e10,e12,e13, e30,e32,e33 )
1066
- result.e13 = det3( e00,e02,e03, e10,e12,e13, e20,e22,e23 )
825
+ result.e00 = (self.e11*self.e22 - self.e12*self.e21)
826
+ result.e01 = -(self.e01*self.e22 - self.e02*self.e21)
827
+ result.e02 = (self.e01*self.e12 - self.e02*self.e11)
1067
828
 
1068
- result.e20 = det3( e10,e11,e13, e20,e21,e23, e30,e31,e33 )
1069
- result.e21 = -det3( e00,e01,e03, e20,e21,e23, e30,e31,e33 )
1070
- result.e22 = det3( e00,e01,e03, e10,e11,e13, e30,e31,e33 )
1071
- result.e23 = -det3( e00,e01,e03, e10,e11,e13, e20,e21,e23 )
829
+ result.e10 = -(self.e10*self.e22 - self.e12*self.e20)
830
+ result.e11 = (self.e00*self.e22 - self.e02*self.e20)
831
+ result.e12 = -(self.e00*self.e12 - self.e02*self.e10)
1072
832
 
1073
- result.e30 = -det3( e10,e11,e12, e20,e21,e22, e30,e31,e32 )
1074
- result.e31 = det3( e00,e01,e02, e20,e21,e22, e30,e31,e32 )
1075
- result.e32 = -det3( e00,e01,e02, e10,e11,e12, e30,e31,e32 )
1076
- result.e33 = det3( e00,e01,e02, e10,e11,e12, e20,e21,e22 )
833
+ result.e20 = (self.e10*self.e21 - self.e11*self.e20)
834
+ result.e21 = -(self.e00*self.e21 - self.e01*self.e20)
835
+ result.e22 = (self.e00*self.e11 - self.e01*self.e10)
1077
836
 
1078
- det = e00 * result.e00 + e01 * result.e10 + e02 * result.e20 + e03 * result.e30
837
+ det = e00 * result.e00 + e01 * result.e10 + e02 * result.e20
1079
838
 
1080
839
  if ( det.abs < TOLERANCE )
1081
- raise RuntimeError, "RMtx4#getInverse : det.abs < TOLERANCE"
840
+ raise RuntimeError, "RMtx3#getInverse : det.abs < TOLERANCE"
1082
841
  return nil
1083
842
  end
1084
843
 
@@ -1095,70 +854,38 @@ module RMath3D
1095
854
  # Makes itself as the inverse of the original matrix.
1096
855
  #
1097
856
  def invert!
1098
- elements = Array.new( 16 )
857
+ elements = Array.new( 9 )
1099
858
 
1100
- elements[4*0+0] = det3( self.e11,self.e12,self.e13, self.e21,self.e22,self.e23, self.e31,self.e32,self.e33 )
1101
- elements[4*0+1] = -det3( self.e01,self.e02,self.e03, self.e21,self.e22,self.e23, self.e31,self.e32,self.e33 )
1102
- elements[4*0+2] = det3( self.e01,self.e02,self.e03, self.e11,self.e12,self.e13, self.e31,self.e32,self.e33 )
1103
- elements[4*0+3] = -det3( self.e01,self.e02,self.e03, self.e11,self.e12,self.e13, self.e21,self.e22,self.e23 )
1104
-
1105
- elements[4*1+0] = -det3( self.e10,self.e12,self.e13, self.e20,self.e22,self.e23, self.e30,self.e32,self.e33 )
1106
- elements[4*1+1] = det3( self.e00,self.e02,self.e03, self.e20,self.e22,self.e23, self.e30,self.e32,self.e33 )
1107
- elements[4*1+2] = -det3( self.e00,self.e02,self.e03, self.e10,self.e12,self.e13, self.e30,self.e32,self.e33 )
1108
- elements[4*1+3] = det3( self.e00,self.e02,self.e03, self.e10,self.e12,self.e13, self.e20,self.e22,self.e23 )
859
+ elements[3*0+0] = (self.e11*self.e22 - self.e12*self.e21)
860
+ elements[3*0+1] = -(self.e01*self.e22 - self.e02*self.e21)
861
+ elements[3*0+2] = (self.e01*self.e12 - self.e02*self.e11)
1109
862
 
1110
- elements[4*2+0] = det3( self.e10,self.e11,self.e13, self.e20,self.e21,self.e23, self.e30,self.e31,self.e33 )
1111
- elements[4*2+1] = -det3( self.e00,self.e01,self.e03, self.e20,self.e21,self.e23, self.e30,self.e31,self.e33 )
1112
- elements[4*2+2] = det3( self.e00,self.e01,self.e03, self.e10,self.e11,self.e13, self.e30,self.e31,self.e33 )
1113
- elements[4*2+3] = -det3( self.e00,self.e01,self.e03, self.e10,self.e11,self.e13, self.e20,self.e21,self.e23 )
863
+ elements[3*1+0] = -(self.e10*self.e22 - self.e12*self.e20)
864
+ elements[3*1+1] = (self.e00*self.e22 - self.e02*self.e20)
865
+ elements[3*1+2] = -(self.e00*self.e12 - self.e02*self.e10)
1114
866
 
1115
- elements[4*3+0] = -det3( self.e10,self.e11,self.e12, self.e20,self.e21,self.e22, self.e30,self.e31,self.e32 )
1116
- elements[4*3+1] = det3( self.e00,self.e01,self.e02, self.e20,self.e21,self.e22, self.e30,self.e31,self.e32 )
1117
- elements[4*3+2] = -det3( self.e00,self.e01,self.e02, self.e10,self.e11,self.e12, self.e30,self.e31,self.e32 )
1118
- elements[4*3+3] = det3( self.e00,self.e01,self.e02, self.e10,self.e11,self.e12, self.e20,self.e21,self.e22 )
867
+ elements[3*2+0] = (self.e10*self.e21 - self.e11*self.e20)
868
+ elements[3*2+1] = -(self.e00*self.e21 - self.e01*self.e20)
869
+ elements[3*2+2] = (self.e00*self.e11 - self.e01*self.e10)
1119
870
 
1120
- det = e00 * elements[4*0+0] + e01 * elements[4*1+0] + e02 * elements[4*2+0] + e03 * elements[4*3+0]
871
+ det = e00 * elements[3*0+0] + e01 * elements[3*1+0] + e02 * elements[3*2+0]
1121
872
 
1122
- if ( det.abs< TOLERANCE )
1123
- raise RuntimeError, "RMtx4invert! : det.abs < TOLERANCE"
873
+ if ( det.abs < TOLERANCE )
874
+ raise RuntimeError, "RMtx3#invert! : det.abs < TOLERANCE"
1124
875
  return nil
1125
876
  end
1126
877
 
1127
878
  d = 1.0 / det
1128
879
 
1129
- setElement( 0, 0, d * elements[4*0+0] )
1130
- setElement( 0, 1, d * elements[4*0+1] )
1131
- setElement( 0, 2, d * elements[4*0+2] )
1132
- setElement( 0, 3, d * elements[4*0+3] )
1133
-
1134
- setElement( 1, 0, d * elements[4*1+0] )
1135
- setElement( 1, 1, d * elements[4*1+1] )
1136
- setElement( 1, 2, d * elements[4*1+2] )
1137
- setElement( 1, 3, d * elements[4*1+3] )
1138
-
1139
- setElement( 2, 0, d * elements[4*2+0] )
1140
- setElement( 2, 1, d * elements[4*2+1] )
1141
- setElement( 2, 2, d * elements[4*2+2] )
1142
- setElement( 2, 3, d * elements[4*2+3] )
1143
-
1144
- setElement( 3, 0, d * elements[4*3+0] )
1145
- setElement( 3, 1, d * elements[4*3+1] )
1146
- setElement( 3, 2, d * elements[4*3+2] )
1147
- setElement( 3, 3, d * elements[4*3+3] )
1148
-
1149
- return self
1150
- end
1151
-
1152
- #
1153
- # call-seq: translation(tx,ty,tz) -> self
1154
- #
1155
- # Makes itself as a translation matrix.
1156
- #
1157
- def translation( tx, ty, tz )
1158
- setIdentity()
1159
- self.e03 = tx
1160
- self.e13 = ty
1161
- self.e23 = tz
880
+ setElement( 0, 0, d * elements[3*0+0] )
881
+ setElement( 0, 1, d * elements[3*0+1] )
882
+ setElement( 0, 2, d * elements[3*0+2] )
883
+ setElement( 1, 0, d * elements[3*1+0] )
884
+ setElement( 1, 1, d * elements[3*1+1] )
885
+ setElement( 1, 2, d * elements[3*1+2] )
886
+ setElement( 2, 0, d * elements[3*2+0] )
887
+ setElement( 2, 1, d * elements[3*2+1] )
888
+ setElement( 2, 2, d * elements[3*2+2] )
1162
889
 
1163
890
  return self
1164
891
  end
@@ -1224,7 +951,7 @@ module RMath3D
1224
951
  #
1225
952
  def rotationAxis( axis, radian )
1226
953
  if ( axis.class != RVec3 )
1227
- raise TypeError, "RMtx4#rotationAxis : Unknown type #{axis.class} given as axis."
954
+ raise TypeError, "RMtx3#rotationAxis : Unknown type #{axis.class} given as axis."
1228
955
  return nil
1229
956
  end
1230
957
  s = Math.sin( radian )
@@ -1234,8 +961,6 @@ module RMath3D
1234
961
  y = axis.y.to_f
1235
962
  z = axis.z.to_f
1236
963
 
1237
- setIdentity()
1238
-
1239
964
  self.e00 = x*x*omc + c
1240
965
  self.e01 = x*y*omc - z*s
1241
966
  self.e02 = z*x*omc + y*s
@@ -1256,7 +981,7 @@ module RMath3D
1256
981
  #
1257
982
  def rotationQuaternion( q )
1258
983
  if ( q.class != RQuat )
1259
- raise TypeError, "RMtx4#rotationQuaternion : Unknown type #{q.class} given as RQuat."
984
+ raise TypeError, "RMtx3#rotationQuaternion : Unknown type #{q.class} given as RQuat."
1260
985
  return nil
1261
986
  end
1262
987
  x = q.x
@@ -1279,8 +1004,6 @@ module RMath3D
1279
1004
  xz2 = x * z2
1280
1005
  wy2 = w * y2
1281
1006
 
1282
- setIdentity()
1283
-
1284
1007
  self.e00 = 1.0 - yy2 - zz2
1285
1008
  self.e10 = xy2 + wz2
1286
1009
  self.e20 = xz2 - wy2
@@ -1308,150 +1031,6 @@ module RMath3D
1308
1031
  return self
1309
1032
  end
1310
1033
 
1311
- #
1312
- # call-seq: lookAtRH(eye,at,up) -> self
1313
- #
1314
- # Builds a viewing matrix for a right-handed coordinate system from:
1315
- # * eye position (+eye+: RVec3)
1316
- # * a point looking at (+at+: RVec3)
1317
- # * up vector (+up+: RVec3)
1318
- #
1319
- def lookAtRH( eye, at, up )
1320
- setIdentity()
1321
-
1322
- axis_z = (eye - at).normalize!
1323
- axis_x = RVec3.cross( up, axis_z ).normalize!
1324
- axis_y = RVec3.cross( axis_z, axis_x )
1325
-
1326
- self.e00 = axis_x[0]
1327
- self.e01 = axis_x[1]
1328
- self.e02 = axis_x[2]
1329
- self.e03 = -RVec3.dot( axis_x, eye )
1330
-
1331
- self.e10 = axis_y[0]
1332
- self.e11 = axis_y[1]
1333
- self.e12 = axis_y[2]
1334
- self.e13 = -RVec3.dot( axis_y, eye )
1335
-
1336
- self.e20 = axis_z[0]
1337
- self.e21 = axis_z[1]
1338
- self.e22 = axis_z[2]
1339
- self.e23 = -RVec3.dot( axis_z, eye )
1340
-
1341
- return self
1342
- end
1343
-
1344
- #
1345
- # call-seq: perspectiveRH(width,height,znear,zfar) -> self
1346
- #
1347
- # Builds a perspective projection matrix for a right-handed coordinate system from:
1348
- # * View volume width (+width+)
1349
- # * View volume height (+height+)
1350
- # * Near clip plane distance (+znear+)
1351
- # * Far clip plane distance (+zfar+)
1352
- #
1353
- def perspectiveRH( width, height, znear, zfar )
1354
- perspectiveOffCenterRH(-width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar )
1355
- return self
1356
- end
1357
-
1358
- #
1359
- # call-seq: perspectiveFovRH(fovy,aspect,znear,zfar) -> self
1360
- #
1361
- # Builds a perspective projection matrix for a right-handed coordinate system from:
1362
- # * Field of view in y direction (+fovy+ radian)
1363
- # * Aspect ratio (+aspect+)
1364
- # * Near clip plane distance (+znear+)
1365
- # * Far clip plane distance (+zfar+)
1366
- #
1367
- def perspectiveFovRH( fovy_radian, aspect, znear, zfar )
1368
- f = Math::tan( fovy_radian / 2.0 )
1369
- f = 1.0 / f
1370
-
1371
- setIdentity()
1372
- setElement( 0, 0, f / aspect )
1373
- setElement( 1, 1, f )
1374
- setElement( 2, 2, (zfar+znear)/(znear-zfar) )
1375
- setElement( 2, 3, 2*zfar*znear/(znear-zfar) )
1376
- setElement( 3, 2, -1.0 )
1377
- setElement( 3, 3, 0.0 )
1378
-
1379
- return self
1380
- end
1381
-
1382
- #
1383
- # call-seq: perspectiveOffCenterRH(left,right,bottom,top,znear,zfar) -> self
1384
- #
1385
- # Builds a perspective projection matrix for a right-handed coordinate system from:
1386
- # * Minimum value of the view volume width (+left+)
1387
- # * Maximum value of the view volume width (+right+)
1388
- # * Minimum value of the view volume height (+bottom+)
1389
- # * Maximum value of the view volume height (+top+)
1390
- # * Near clip plane distance (+znear+)
1391
- # * Far clip plane distance (+zfar+)
1392
- #
1393
- def perspectiveOffCenterRH( left, right, bottom, top, znear, zfar )
1394
- a = (right+left) / (right-left)
1395
- b = (top+bottom) / (top-bottom)
1396
- c = -(zfar+znear) / (zfar-znear)
1397
- d = -(2*znear*zfar) / (zfar-znear)
1398
-
1399
- setIdentity()
1400
-
1401
- setElement( 0, 0, 2*znear/(right-left) )
1402
- setElement( 0, 2, a )
1403
- setElement( 1, 1, 2*znear/(top-bottom) )
1404
- setElement( 1, 2, b )
1405
- setElement( 2, 2, c )
1406
- setElement( 2, 3, d )
1407
- setElement( 3, 2, -1.0 )
1408
- setElement( 3, 3, 0.0 )
1409
-
1410
- return self
1411
- end
1412
-
1413
- #
1414
- # call-seq: orthoRH(width,height,znear,zfar) -> self
1415
- #
1416
- # Builds a orthogonal projection matrix for a right-handed coordinate system from:
1417
- # * View volume width (+width+)
1418
- # * View volume height (+height+)
1419
- # * Near clip plane distance (+znear+)
1420
- # * Far clip plane distance (+zfar+)
1421
- #
1422
- def orthoRH( width, height, znear, zfar )
1423
- orthoOffCenterRH( -width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar )
1424
- return self
1425
- end
1426
-
1427
- #
1428
- # call-seq: orthoOffCenterRH(left,right,bottom,top,znear,zfar) -> self
1429
- #
1430
- # Builds a orthogonal projection matrix for a right-handed coordinate system from:
1431
- # * Minimum value of the view volume width (+left+)
1432
- # * Maximum value of the view volume width (+right+)
1433
- # * Minimum value of the view volume height (+bottom+)
1434
- # * Maximum value of the view volume height (+top+)
1435
- # * Near clip plane distance (+znear+)
1436
- # * Far clip plane distance (+zfar+)
1437
- #
1438
- def orthoOffCenterRH( left, right, bottom, top, znear, zfar )
1439
- tx = (right+left) / (right-left)
1440
- ty = (top+bottom) / (top-bottom)
1441
- tz = (zfar+znear) / (zfar-znear)
1442
-
1443
- setIdentity()
1444
-
1445
- setElement( 0, 0, 2.0/(right-left) )
1446
- setElement( 0, 3, tx )
1447
- setElement( 1, 1, 2.0/(top-bottom) )
1448
- setElement( 1, 3, ty )
1449
- setElement( 2, 2, -2.0/(zfar-znear) )
1450
- setElement( 2, 3, tz )
1451
-
1452
- return self
1453
- end
1454
-
1455
1034
  #
1456
1035
  # call-seq: +
1457
1036
  #
@@ -1467,7 +1046,7 @@ module RMath3D
1467
1046
  # -mtx : Unary minus operator.
1468
1047
  #
1469
1048
  def -@
1470
- return RMtx4.new( self * -1.0 )
1049
+ return RMtx3.new( self * -1.0 )
1471
1050
  end
1472
1051
 
1473
1052
  #
@@ -1476,14 +1055,14 @@ module RMath3D
1476
1055
  # mtx1 + mtx2 : Binary plus operator.
1477
1056
  #
1478
1057
  def +( arg )
1479
- if ( arg.class != RMtx4 )
1480
- raise TypeError, "RMtx4#+(arg) : Unknown type #{arg.class} given as RMtx4."
1058
+ if ( arg.class != RMtx3 )
1059
+ raise TypeError, "RMtx3#+(arg) : Unknown type #{arg.class} given as RMtx3."
1481
1060
  return nil
1482
1061
  end
1483
1062
 
1484
- result = RMtx4.new
1485
- for row in 0...4 do
1486
- for col in 0...4 do
1063
+ result = RMtx3.new
1064
+ for row in 0...3 do
1065
+ for col in 0...3 do
1487
1066
  result.setElement( row, col, getElement(row,col) + arg.getElement(row,col) )
1488
1067
  end
1489
1068
  end
@@ -1497,14 +1076,14 @@ module RMath3D
1497
1076
  # mtx1 - mtx2 : Binary minus operator.
1498
1077
  #
1499
1078
  def -( arg )
1500
- if ( arg.class != RMtx4 )
1501
- raise TypeError, "RMtx4#-(arg) : Unknown type #{arg.class} given as RMtx4."
1079
+ if ( arg.class != RMtx3 )
1080
+ raise TypeError, "RMtx3#-(arg) : Unknown type #{arg.class} given as RMtx3."
1502
1081
  return nil
1503
1082
  end
1504
1083
 
1505
- result = RMtx4.new
1506
- for row in 0...4 do
1507
- for col in 0...4 do
1084
+ result = RMtx3.new
1085
+ for row in 0...3 do
1086
+ for col in 0...3 do
1508
1087
  result.setElement( row, col, getElement(row,col) - arg.getElement(row,col) )
1509
1088
  end
1510
1089
  end
@@ -1519,18 +1098,17 @@ module RMath3D
1519
1098
  #
1520
1099
  def *( arg )
1521
1100
  case arg
1522
- when Fixnum, Float, Bignum
1523
- return RMtx4.new( arg*self.e00, arg*self.e01, arg*self.e02, arg*self.e03,
1524
- arg*self.e10, arg*self.e11, arg*self.e12, arg*self.e13,
1525
- arg*self.e20, arg*self.e21, arg*self.e22, arg*self.e23,
1526
- arg*self.e30, arg*self.e31, arg*self.e32, arg*self.e33 )
1101
+ when Float, Integer
1102
+ return RMtx3.new( arg*self.e00, arg*self.e01, arg*self.e02,
1103
+ arg*self.e10, arg*self.e11, arg*self.e12,
1104
+ arg*self.e20, arg*self.e21, arg*self.e22 )
1527
1105
 
1528
- when RMtx4
1529
- result = RMtx4.new
1530
- for row in 0...4 do
1531
- for col in 0...4 do
1106
+ when RMtx3
1107
+ result = RMtx3.new
1108
+ for row in 0...3 do
1109
+ for col in 0...3 do
1532
1110
  sum = 0.0
1533
- for i in 0...4 do
1111
+ for i in 0...3 do
1534
1112
  sum += getElement( row, i ) * arg.getElement( i, col )
1535
1113
  end
1536
1114
  result.setElement( row, col, sum )
@@ -1539,7 +1117,7 @@ module RMath3D
1539
1117
  return result
1540
1118
 
1541
1119
  else
1542
- raise TypeError, "RMtx4#*(arg) : Unknown type #{arg.class} given."
1120
+ raise TypeError, "RMtx3#*(arg) : Unknown type #{arg.class} given."
1543
1121
  return nil
1544
1122
  end
1545
1123
  end
@@ -1550,19 +1128,18 @@ module RMath3D
1550
1128
  # mtx1 == mtx2 : evaluates equality.
1551
1129
  #
1552
1130
  def ==( other )
1553
- if ( other.class != RMtx4 )
1554
- raise TypeError, "RMtx4#==(other) : Unknown type #{other.class} given as RMtx4."
1555
- return nil
1556
- end
1557
-
1558
- for row in 0...4 do
1559
- for col in 0...4 do
1560
- if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
1561
- return false
1562
- end
1563
- end
1131
+ if other.class == RMtx3
1132
+ for row in 0...3 do
1133
+ for col in 0...3 do
1134
+ if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
1135
+ return false
1136
+ end
1137
+ end
1138
+ end
1139
+ return true
1140
+ else
1141
+ return false
1564
1142
  end
1565
- return true
1566
1143
  end
1567
1144
 
1568
1145
  #
@@ -1571,14 +1148,14 @@ module RMath3D
1571
1148
  # mtx1 += mtx2 : appends the elements of +mtx2+ into corresponding +mtx1+ elements.
1572
1149
  #
1573
1150
  def add!( other )
1574
- if ( other.class != RMtx4 )
1575
- raise TypeError, "RMtx4#add! : Unknown type #{other.class} given as RMtx4."
1151
+ if ( other.class != RMtx3 )
1152
+ raise TypeError, "RMtx3#add! : Unknown type #{other.class} given as RMtx3."
1576
1153
  return nil
1577
1154
  end
1578
1155
 
1579
- result = RMtx4.new
1580
- for row in 0...4 do
1581
- for col in 0...4 do
1156
+ result = RMtx3.new
1157
+ for row in 0...3 do
1158
+ for col in 0...3 do
1582
1159
  self.setElement( row, col, getElement(row,col) + other.getElement(row,col) )
1583
1160
  end
1584
1161
  end
@@ -1592,14 +1169,14 @@ module RMath3D
1592
1169
  # mtx1 -= mtx2 : subtracts the elements of +mtx2+ from corresponding +mtx1+ elements.
1593
1170
  #
1594
1171
  def sub!( other )
1595
- if ( other.class != RMtx4 )
1596
- raise TypeError, "RMtx4#sub! : Unknown type #{other.class} given as RMtx4."
1172
+ if ( other.class != RMtx3 )
1173
+ raise TypeError, "RMtx3#sub! : Unknown type #{other.class} given as RMtx3."
1597
1174
  return nil
1598
1175
  end
1599
1176
 
1600
- result = RMtx4.new
1601
- for row in 0...4 do
1602
- for col in 0...4 do
1177
+ result = RMtx3.new
1178
+ for row in 0...3 do
1179
+ for col in 0...3 do
1603
1180
  self.setElement( row, col, getElement(row,col) - other.getElement(row,col) )
1604
1181
  end
1605
1182
  end
@@ -1614,35 +1191,24 @@ module RMath3D
1614
1191
  #
1615
1192
  def mul!( other )
1616
1193
  case other
1617
- when Fixnum, Float, Bignum
1194
+ when Float, Integer
1618
1195
  self.e00 = other*self.e00
1619
1196
  self.e01 = other*self.e01
1620
1197
  self.e02 = other*self.e02
1621
- self.e03 = other*self.e03
1622
-
1623
1198
  self.e10 = other*self.e10
1624
1199
  self.e11 = other*self.e11
1625
1200
  self.e12 = other*self.e12
1626
- self.e13 = other*self.e13
1627
-
1628
1201
  self.e20 = other*self.e20
1629
1202
  self.e21 = other*self.e21
1630
1203
  self.e22 = other*self.e22
1631
- self.e23 = other*self.e23
1632
-
1633
- self.e30 = other*self.e30
1634
- self.e31 = other*self.e31
1635
- self.e32 = other*self.e32
1636
- self.e33 = other*self.e33
1637
1204
 
1638
1205
  return self
1639
-
1640
- when RMtx4
1641
- result = RMtx4.new
1642
- for row in 0...4 do
1643
- for col in 0...4 do
1206
+ when RMtx3
1207
+ result = RMtx3.new
1208
+ for row in 0...3 do
1209
+ for col in 0...3 do
1644
1210
  sum = 0.0
1645
- for i in 0...4 do
1211
+ for i in 0...3 do
1646
1212
  sum += getElement( row, i ) * other.getElement( i, col )
1647
1213
  end
1648
1214
  result.setElement( row, col, sum )
@@ -1652,22 +1218,12 @@ module RMath3D
1652
1218
  self.e00 = result.e00
1653
1219
  self.e01 = result.e01
1654
1220
  self.e02 = result.e02
1655
- self.e03 = result.e03
1656
-
1657
1221
  self.e10 = result.e10
1658
1222
  self.e11 = result.e11
1659
1223
  self.e12 = result.e12
1660
- self.e13 = result.e13
1661
-
1662
1224
  self.e20 = result.e20
1663
1225
  self.e21 = result.e21
1664
1226
  self.e22 = result.e22
1665
- self.e23 = result.e23
1666
-
1667
- self.e30 = result.e30
1668
- self.e31 = result.e31
1669
- self.e32 = result.e32
1670
- self.e33 = result.e33
1671
1227
 
1672
1228
  return self
1673
1229
  end
@@ -1675,49 +1231,68 @@ module RMath3D
1675
1231
  end
1676
1232
 
1677
1233
  #
1678
- # Document-class: RMath3D::RQuat
1679
- # provies quaternion arithmetic.
1234
+ # Document-class: RMath3D::RMtx4
1235
+ # provies 4x4 matrix arithmetic.
1680
1236
  #
1681
- class RQuat
1237
+ # <b>Notice</b>
1238
+ # * elements are stored in column-major order.
1239
+ #
1240
+ class RMtx4
1682
1241
 
1683
1242
  #
1684
1243
  # call-seq:
1685
- # RQuat.new -> (0,0,0,0)
1686
- # RQuat.new(e) -> (e,e,e,e)
1687
- # RQuat.new( other ) : Copy Constructor
1688
- # RQuat.new( e0, e1, e2, e3 ) -> (e0,e1,e2,e3)
1244
+ # RMtx4.new -> ((1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1))
1245
+ # RMtx4.new(e) -> ((e,e,e,e),(e,e,e,e),(e,e,e,e),(e,e,e,e))
1246
+ # RMtx4.new( other ) : Copy Constructor
1247
+ # RMtx4.new( e0, e1, ..., e15 ) -> ((e0,e1,e2,e3),(e4,e5,e6,e7),(e8,e9,e10,e11),(e12,e13,e14,e15))
1689
1248
  #
1690
- # Creates a new quaternion.
1249
+ # Creates a new 4x4 matrix.
1691
1250
  #
1692
1251
  def initialize( *a )
1252
+ # [NOTE] elemetns are stored in column-major order.
1693
1253
  @e = []
1694
1254
  case a.length
1695
1255
  when 0
1696
- @e = [0.0, 0.0, 0.0, 0.0]
1256
+ @e = [ 0.0, 0.0, 0.0, 0.0,
1257
+ 0.0, 0.0, 0.0, 0.0,
1258
+ 0.0, 0.0, 0.0, 0.0,
1259
+ 0.0, 0.0, 0.0, 0.0 ]
1697
1260
  when 1
1698
1261
  case a[0]
1699
- when Fixnum, Float
1700
- @e = [ a[0], a[0], a[0], a[0] ]
1701
- when RQuat
1702
- @e = [ a[0].x, a[0].y, a[0].z, a[0].w ]
1262
+ when Float, Integer
1263
+ @e = [ a[0], a[0], a[0], a[0],
1264
+ a[0], a[0], a[0], a[0],
1265
+ a[0], a[0], a[0], a[0],
1266
+ a[0], a[0], a[0], a[0] ]
1267
+ when RMtx4
1268
+ # Copy Constructor
1269
+ @e = [ a[0].e00, a[0].e10, a[0].e20, a[0].e30,
1270
+ a[0].e01, a[0].e11, a[0].e21, a[0].e31,
1271
+ a[0].e02, a[0].e12, a[0].e22, a[0].e32,
1272
+ a[0].e03, a[0].e13, a[0].e23, a[0].e33 ]
1703
1273
  else
1704
- raise TypeError, "RQuat#initialize : Unknown type #{a[0].class}."
1274
+ raise TypeError, "RMtx4#initialize : Unknown type #{a[0].class}."
1705
1275
  return nil
1706
1276
  end
1707
- when 4
1708
- a.each_with_index do |elem, index|
1709
- case elem
1710
- when Fixnum, Float
1711
- @e[index] = elem
1712
- else
1713
- raise TypeError, "RQuat#initialize : Unknown type #{elem.class}."
1714
- return nil
1277
+ when 16
1278
+ # Element-wise setter
1279
+ for row in 0...4 do
1280
+ for col in 0...4 do
1281
+ index = 4*row + col
1282
+ case a[index]
1283
+ when Float, Integer
1284
+ setElement( row, col, a[index] )
1285
+ else
1286
+ raise TypeError, "RMtx4#initialize : Unknown type #{a[0].class}."
1287
+ return nil
1288
+ end
1715
1289
  end
1716
1290
  end
1717
1291
  else
1718
- raise RuntimeError, "RQuat#initialize : wrong # of arguments (#{a.length})"
1292
+ raise RuntimeError, "RMtx4#initialize : wrong # of arguments (#{a.length})"
1719
1293
  return nil
1720
1294
  end
1295
+
1721
1296
  return self
1722
1297
  end
1723
1298
 
@@ -1727,7 +1302,10 @@ module RMath3D
1727
1302
  # Returns human-readable string.
1728
1303
  #
1729
1304
  def to_s
1730
- return "( #{@e[0]}, #{@e[1]}, #{@e[2]}, #{@e[3]} )\n"
1305
+ "( #{@e[0]}, #{@e[4]}, #{@e[8]}, #{@e[12]} )\n" +
1306
+ "( #{@e[1]}, #{@e[5]}, #{@e[9]}, #{@e[13]} )\n" +
1307
+ "( #{@e[2]}, #{@e[6]}, #{@e[10]}, #{@e[14]} )\n" +
1308
+ "( #{@e[3]}, #{@e[7]}, #{@e[11]}, #{@e[15]} )\n"
1731
1309
  end
1732
1310
 
1733
1311
  #
@@ -1744,266 +1322,1722 @@ module RMath3D
1744
1322
  #
1745
1323
  # Resolves type mismatch.
1746
1324
  #
1747
- def coerce( arg )
1325
+ def coerce
1748
1326
  case arg
1749
- when Fixnum, Float, Bignum
1327
+ when Float, Integer
1750
1328
  return [ self, arg ]
1751
1329
  else
1752
- raise TypeError, "RQuat#coerce : #{arg.self} can't be coerced into #{self.class}."
1330
+ raise TypeError, "RMtx4#coerce : #{arg.self} can't be coerced into #{self.class}."
1753
1331
  return nil
1754
1332
  end
1755
1333
  end
1756
1334
 
1757
1335
  #
1758
- # call-seq: setElements( e0, e1, e2, e3 )
1336
+ # call-seq: setElements( e0, e1, ..., e15 )
1759
1337
  #
1760
- # Stores given 4 new values.
1338
+ # Stores given 16 new values.
1761
1339
  #
1762
- def setElements( x, y, z, w )
1763
- self.x = x
1764
- self.y = y
1765
- self.z = z
1766
- self.w = w
1340
+ def setElements( *a )
1341
+ if a.length != 16
1342
+ raise RuntimeError, "RMtx4#setElements : wrong # of arguments (#{a.length})"
1343
+ return nil
1344
+ end
1345
+
1346
+ for row in 0...4 do
1347
+ for col in 0...4 do
1348
+ index = 4*row + col
1349
+ setElement( row, col, a[index] )
1350
+ end
1351
+ end
1767
1352
  end
1768
1353
 
1769
1354
  #
1770
- # call-seq: quat[i]= value
1355
+ # call-seq: [row,col]= value
1771
1356
  #
1772
- # Stores +value+ at +i+.
1357
+ # Stores +value+ at (+row+,+col+).
1773
1358
  #
1774
- def []=(i,value)
1775
- @e[i] = value
1359
+ def []=(row,col,value)
1360
+ # [NOTE] elemetns are stored in column-major order.
1361
+ @e[col*4+row] = value
1776
1362
  end
1363
+ alias_method :setElement, :'[]='
1777
1364
 
1778
1365
  #
1779
- # call-seq: x= value
1366
+ # call-seq: [row,col] -> value
1780
1367
  #
1781
- # Stores +value+ as +x+.
1368
+ # Returns the element at (+row+,+col+).
1782
1369
  #
1783
- def x=(value) @e[0] = value end
1370
+ def [](row,col)
1371
+ # [NOTE] elemetns are stored in column-major order.
1372
+ return @e[col*4+row]
1373
+ end
1374
+ alias_method :getElement, :'[]'
1375
+
1376
+ # Returns the element at row 0 and column 0.
1377
+ def e00() getElement(0,0) end
1378
+ # Returns the element at row 0 and column 1.
1379
+ def e01() getElement(0,1) end
1380
+ # Returns the element at row 0 and column 2.
1381
+ def e02() getElement(0,2) end
1382
+ # Returns the element at row 0 and column 3.
1383
+ def e03() getElement(0,3) end
1384
+ # Returns the element at row 1 and column 0.
1385
+ def e10() getElement(1,0) end
1386
+ # Returns the element at row 1 and column 1.
1387
+ def e11() getElement(1,1) end
1388
+ # Returns the element at row 1 and column 2.
1389
+ def e12() getElement(1,2) end
1390
+ # Returns the element at row 1 and column 3.
1391
+ def e13() getElement(1,3) end
1392
+ # Returns the element at row 2 and column 0.
1393
+ def e20() getElement(2,0) end
1394
+ # Returns the element at row 2 and column 1.
1395
+ def e21() getElement(2,1) end
1396
+ # Returns the element at row 2 and column 2.
1397
+ def e22() getElement(2,2) end
1398
+ # Returns the element at row 2 and column 3.
1399
+ def e23() getElement(2,3) end
1400
+ # Returns the element at row 3 and column 0.
1401
+ def e30() getElement(3,0) end
1402
+ # Returns the element at row 3 and column 1.
1403
+ def e31() getElement(3,1) end
1404
+ # Returns the element at row 3 and column 2.
1405
+ def e32() getElement(3,2) end
1406
+ # Returns the element at row 3 and column 3.
1407
+ def e33() getElement(3,3) end
1408
+
1409
+ # Replaces the element at row 0 and column 0 by +value+.
1410
+ def e00=(value) setElement(0,0,value) end
1411
+ # Replaces the element at row 0 and column 1 by +value+.
1412
+ def e01=(value) setElement(0,1,value) end
1413
+ # Replaces the element at row 0 and column 2 by +value+.
1414
+ def e02=(value) setElement(0,2,value) end
1415
+ # Replaces the element at row 0 and column 3 by +value+.
1416
+ def e03=(value) setElement(0,3,value) end
1417
+ # Replaces the element at row 1 and column 0 by +value+.
1418
+ def e10=(value) setElement(1,0,value) end
1419
+ # Replaces the element at row 1 and column 1 by +value+.
1420
+ def e11=(value) setElement(1,1,value) end
1421
+ # Replaces the element at row 1 and column 2 by +value+.
1422
+ def e12=(value) setElement(1,2,value) end
1423
+ # Replaces the element at row 1 and column 3 by +value+.
1424
+ def e13=(value) setElement(1,3,value) end
1425
+ # Replaces the element at row 2 and column 0 by +value+.
1426
+ def e20=(value) setElement(2,0,value) end
1427
+ # Replaces the element at row 2 and column 1 by +value+.
1428
+ def e21=(value) setElement(2,1,value) end
1429
+ # Replaces the element at row 2 and column 2 by +value+.
1430
+ def e22=(value) setElement(2,2,value) end
1431
+ # Replaces the element at row 2 and column 3 by +value+.
1432
+ def e23=(value) setElement(2,3,value) end
1433
+ # Replaces the element at row 3 and column 0 by +value+.
1434
+ def e30=(value) setElement(3,0,value) end
1435
+ # Replaces the element at row 3 and column 1 by +value+.
1436
+ def e31=(value) setElement(3,1,value) end
1437
+ # Replaces the element at row 3 and column 2 by +value+.
1438
+ def e32=(value) setElement(3,2,value) end
1439
+ # Replaces the element at row 3 and column 3 by +value+.
1440
+ def e33=(value) setElement(3,3,value) end
1784
1441
 
1785
1442
  #
1786
- # call-seq: y= value
1443
+ # call-seq: mtx4.getRow(r) -> RVec4
1787
1444
  #
1788
- # Stores +value+ as +y+.
1445
+ # Returns +r+-th row vector.
1789
1446
  #
1790
- def y=(value) @e[1] = value end
1447
+ def getRow( row )
1448
+ return RVec4.new( self[row,0], self[row,1], self[row,2], self[row,3] )
1449
+ end
1791
1450
 
1792
1451
  #
1793
- # call-seq: z= value
1452
+ # call-seq: mtx4.getColumn(c) -> RVec4
1794
1453
  #
1795
- # Stores +value+ as +z+.
1454
+ # Returns +c+-th column vector.
1796
1455
  #
1797
- def z=(value) @e[2] = value end
1456
+ def getColumn( column )
1457
+ return RVec4.new( self[0,column], self[1,column], self[2,column], self[3,column] )
1458
+ end
1798
1459
 
1799
1460
  #
1800
- # call-seq: w= value
1461
+ # call-seq: mtx4.setRow(v,r)
1801
1462
  #
1802
- # Stores +value+ as +w+.
1463
+ # Returns sets +r+-th row by vector +v+.
1803
1464
  #
1804
- def w=(value) @e[3] = value end
1465
+ def setRow( v, row )
1466
+ self[row,0] = v.x
1467
+ self[row,1] = v.y
1468
+ self[row,2] = v.z
1469
+ self[row,3] = v.w
1470
+ end
1471
+
1472
+ #
1473
+ # call-seq: mtx4.setColumn(v,c)
1474
+ #
1475
+ # Returns sets +c+-th column by vector +v+.
1476
+ #
1477
+ def setColumn( v, column )
1478
+ self[0,column] = v.x
1479
+ self[1,column] = v.y
1480
+ self[2,column] = v.z
1481
+ self[3,column] = v.w
1482
+ end
1483
+
1484
+ def getUpper3x3
1485
+ return RMtx3.new( self.e00, self.e01, self.e02,
1486
+ self.e10, self.e11, self.e12,
1487
+ self.e20, self.e21, self.e22 )
1488
+ end
1489
+
1490
+ def setUpper3x3( mtx3x3 )
1491
+ self.e00 = mtx3x3.e00
1492
+ self.e01 = mtx3x3.e01
1493
+ self.e02 = mtx3x3.e02
1494
+ self.e10 = mtx3x3.e10
1495
+ self.e11 = mtx3x3.e11
1496
+ self.e12 = mtx3x3.e12
1497
+ self.e20 = mtx3x3.e20
1498
+ self.e21 = mtx3x3.e21
1499
+ self.e22 = mtx3x3.e22
1500
+
1501
+ return self
1502
+ end
1503
+
1504
+ # call-seq: setZero
1505
+ #
1506
+ # Clears all elements by 0.0
1507
+ #
1508
+ def setZero
1509
+ 16.times do |i|
1510
+ @e[i] = 0.0
1511
+ end
1512
+ return self
1513
+ end
1514
+
1515
+ #
1516
+ # call-seq: setIdentity
1517
+ #
1518
+ # Sets as identity matrix.
1519
+ #
1520
+ def setIdentity
1521
+ for row in 0...4 do
1522
+ for col in 0...4 do
1523
+ index = 4*row + col
1524
+ if ( row == col )
1525
+ setElement( row, col, 1.0 )
1526
+ else
1527
+ setElement( row, col, 0.0 )
1528
+ end
1529
+ end
1530
+ end
1531
+ return self
1532
+ end
1533
+
1534
+ def det3( _e00,_e01,_e02, _e10,_e11,_e12, _e20,_e21,_e22 )
1535
+ _e00 * (_e11*_e22 - _e12*_e21) -
1536
+ _e01 * (_e10*_e22 - _e12*_e20) +
1537
+ _e02 * (_e10*_e21 - _e11*_e20)
1538
+ end
1539
+ private :det3
1540
+
1541
+ #
1542
+ # call-seq: getDeterminant -> determinant
1543
+ #
1544
+ # Calculates determinant.
1545
+ #
1546
+ def getDeterminant
1547
+ e00 * det3( e11,e12,e13, e21,e22,e23, e31,e32,e33 ) -
1548
+ e01 * det3( e10,e12,e13, e20,e22,e23, e30,e32,e33 ) +
1549
+ e02 * det3( e10,e11,e13, e20,e21,e23, e30,e31,e33 ) -
1550
+ e03 * det3( e10,e11,e12, e20,e21,e22, e30,e31,e32 )
1551
+ end
1552
+
1553
+ #
1554
+ # call-seq: getTransposed
1555
+ #
1556
+ # Returns transposed matrix.
1557
+ #
1558
+ def getTransposed
1559
+ return RMtx4.new( @e[ 0], @e[ 1], @e[ 2], @e[ 3],
1560
+ @e[ 4], @e[ 5], @e[ 6], @e[ 7],
1561
+ @e[ 8], @e[ 9], @e[10], @e[11],
1562
+ @e[12], @e[13], @e[14], @e[15] )
1563
+ end
1564
+
1565
+ #
1566
+ # call-seq: transpose!
1567
+ #
1568
+ # Transposeas its elements.
1569
+ #
1570
+ def transpose!
1571
+ @e[ 1], @e[ 4] = @e[ 4], @e[ 1]
1572
+ @e[ 2], @e[ 8] = @e[ 8], @e[ 2]
1573
+ @e[ 3], @e[12] = @e[12], @e[ 3]
1574
+ @e[ 6], @e[ 9] = @e[ 9], @e[ 6]
1575
+ @e[ 7], @e[13] = @e[13], @e[ 7]
1576
+ @e[11], @e[14] = @e[14], @e[11]
1577
+ end
1578
+
1579
+ #
1580
+ # call-seq: getInverse -> inverse
1581
+ #
1582
+ # Returns the inverse.
1583
+ #
1584
+ def getInverse
1585
+ result = RMtx4.new
1586
+
1587
+ result.e00 = det3( e11,e12,e13, e21,e22,e23, e31,e32,e33 )
1588
+ result.e01 = -det3( e01,e02,e03, e21,e22,e23, e31,e32,e33 )
1589
+ result.e02 = det3( e01,e02,e03, e11,e12,e13, e31,e32,e33 )
1590
+ result.e03 = -det3( e01,e02,e03, e11,e12,e13, e21,e22,e23 )
1591
+
1592
+ result.e10 = -det3( e10,e12,e13, e20,e22,e23, e30,e32,e33 )
1593
+ result.e11 = det3( e00,e02,e03, e20,e22,e23, e30,e32,e33 )
1594
+ result.e12 = -det3( e00,e02,e03, e10,e12,e13, e30,e32,e33 )
1595
+ result.e13 = det3( e00,e02,e03, e10,e12,e13, e20,e22,e23 )
1596
+
1597
+ result.e20 = det3( e10,e11,e13, e20,e21,e23, e30,e31,e33 )
1598
+ result.e21 = -det3( e00,e01,e03, e20,e21,e23, e30,e31,e33 )
1599
+ result.e22 = det3( e00,e01,e03, e10,e11,e13, e30,e31,e33 )
1600
+ result.e23 = -det3( e00,e01,e03, e10,e11,e13, e20,e21,e23 )
1601
+
1602
+ result.e30 = -det3( e10,e11,e12, e20,e21,e22, e30,e31,e32 )
1603
+ result.e31 = det3( e00,e01,e02, e20,e21,e22, e30,e31,e32 )
1604
+ result.e32 = -det3( e00,e01,e02, e10,e11,e12, e30,e31,e32 )
1605
+ result.e33 = det3( e00,e01,e02, e10,e11,e12, e20,e21,e22 )
1606
+
1607
+ det = e00 * result.e00 + e01 * result.e10 + e02 * result.e20 + e03 * result.e30
1608
+
1609
+ if ( det.abs < TOLERANCE )
1610
+ raise RuntimeError, "RMtx4#getInverse : det.abs < TOLERANCE"
1611
+ return nil
1612
+ end
1613
+
1614
+ d = 1.0 / det
1615
+
1616
+ result.mul!( d )
1617
+
1618
+ return result
1619
+ end
1620
+
1621
+ #
1622
+ # call-seq: invert! -> self
1623
+ #
1624
+ # Makes itself as the inverse of the original matrix.
1625
+ #
1626
+ def invert!
1627
+ elements = Array.new( 16 )
1628
+
1629
+ elements[4*0+0] = det3( self.e11,self.e12,self.e13, self.e21,self.e22,self.e23, self.e31,self.e32,self.e33 )
1630
+ elements[4*0+1] = -det3( self.e01,self.e02,self.e03, self.e21,self.e22,self.e23, self.e31,self.e32,self.e33 )
1631
+ elements[4*0+2] = det3( self.e01,self.e02,self.e03, self.e11,self.e12,self.e13, self.e31,self.e32,self.e33 )
1632
+ elements[4*0+3] = -det3( self.e01,self.e02,self.e03, self.e11,self.e12,self.e13, self.e21,self.e22,self.e23 )
1633
+
1634
+ elements[4*1+0] = -det3( self.e10,self.e12,self.e13, self.e20,self.e22,self.e23, self.e30,self.e32,self.e33 )
1635
+ elements[4*1+1] = det3( self.e00,self.e02,self.e03, self.e20,self.e22,self.e23, self.e30,self.e32,self.e33 )
1636
+ elements[4*1+2] = -det3( self.e00,self.e02,self.e03, self.e10,self.e12,self.e13, self.e30,self.e32,self.e33 )
1637
+ elements[4*1+3] = det3( self.e00,self.e02,self.e03, self.e10,self.e12,self.e13, self.e20,self.e22,self.e23 )
1638
+
1639
+ elements[4*2+0] = det3( self.e10,self.e11,self.e13, self.e20,self.e21,self.e23, self.e30,self.e31,self.e33 )
1640
+ elements[4*2+1] = -det3( self.e00,self.e01,self.e03, self.e20,self.e21,self.e23, self.e30,self.e31,self.e33 )
1641
+ elements[4*2+2] = det3( self.e00,self.e01,self.e03, self.e10,self.e11,self.e13, self.e30,self.e31,self.e33 )
1642
+ elements[4*2+3] = -det3( self.e00,self.e01,self.e03, self.e10,self.e11,self.e13, self.e20,self.e21,self.e23 )
1643
+
1644
+ elements[4*3+0] = -det3( self.e10,self.e11,self.e12, self.e20,self.e21,self.e22, self.e30,self.e31,self.e32 )
1645
+ elements[4*3+1] = det3( self.e00,self.e01,self.e02, self.e20,self.e21,self.e22, self.e30,self.e31,self.e32 )
1646
+ elements[4*3+2] = -det3( self.e00,self.e01,self.e02, self.e10,self.e11,self.e12, self.e30,self.e31,self.e32 )
1647
+ elements[4*3+3] = det3( self.e00,self.e01,self.e02, self.e10,self.e11,self.e12, self.e20,self.e21,self.e22 )
1648
+
1649
+ det = e00 * elements[4*0+0] + e01 * elements[4*1+0] + e02 * elements[4*2+0] + e03 * elements[4*3+0]
1650
+
1651
+ if ( det.abs< TOLERANCE )
1652
+ raise RuntimeError, "RMtx4invert! : det.abs < TOLERANCE"
1653
+ return nil
1654
+ end
1655
+
1656
+ d = 1.0 / det
1657
+
1658
+ setElement( 0, 0, d * elements[4*0+0] )
1659
+ setElement( 0, 1, d * elements[4*0+1] )
1660
+ setElement( 0, 2, d * elements[4*0+2] )
1661
+ setElement( 0, 3, d * elements[4*0+3] )
1662
+
1663
+ setElement( 1, 0, d * elements[4*1+0] )
1664
+ setElement( 1, 1, d * elements[4*1+1] )
1665
+ setElement( 1, 2, d * elements[4*1+2] )
1666
+ setElement( 1, 3, d * elements[4*1+3] )
1667
+
1668
+ setElement( 2, 0, d * elements[4*2+0] )
1669
+ setElement( 2, 1, d * elements[4*2+1] )
1670
+ setElement( 2, 2, d * elements[4*2+2] )
1671
+ setElement( 2, 3, d * elements[4*2+3] )
1672
+
1673
+ setElement( 3, 0, d * elements[4*3+0] )
1674
+ setElement( 3, 1, d * elements[4*3+1] )
1675
+ setElement( 3, 2, d * elements[4*3+2] )
1676
+ setElement( 3, 3, d * elements[4*3+3] )
1677
+
1678
+ return self
1679
+ end
1680
+
1681
+ #
1682
+ # call-seq: translation(tx,ty,tz) -> self
1683
+ #
1684
+ # Makes itself as a translation matrix.
1685
+ #
1686
+ def translation( tx, ty, tz )
1687
+ setIdentity()
1688
+ self.e03 = tx
1689
+ self.e13 = ty
1690
+ self.e23 = tz
1691
+
1692
+ return self
1693
+ end
1694
+
1695
+ #
1696
+ # call-seq: rotationX(radian) -> self
1697
+ #
1698
+ # Makes a matrix that rotates around the x-axis.
1699
+ #
1700
+ def rotationX( radian )
1701
+ s = Math.sin( radian )
1702
+ c = Math.cos( radian )
1703
+
1704
+ setIdentity()
1705
+ self.e11 = c
1706
+ self.e12 = -s
1707
+ self.e21 = s
1708
+ self.e22 = c
1709
+
1710
+ return self
1711
+ end
1712
+
1713
+ #
1714
+ # call-seq: rotationY(radian) -> self
1715
+ #
1716
+ # Makes a matrix that rotates around the y-axis.
1717
+ #
1718
+ def rotationY( radian )
1719
+ s = Math.sin( radian )
1720
+ c = Math.cos( radian )
1721
+
1722
+ setIdentity()
1723
+ self.e00 = c
1724
+ self.e02 = s
1725
+ self.e20 = -s
1726
+ self.e22 = c
1727
+
1728
+ return self
1729
+ end
1730
+
1731
+ #
1732
+ # call-seq: rotationZ(radian) -> self
1733
+ #
1734
+ # Makes a matrix that rotates around the z-axis.
1735
+ #
1736
+ def rotationZ( radian )
1737
+ s = Math.sin( radian )
1738
+ c = Math.cos( radian )
1739
+
1740
+ setIdentity()
1741
+ self.e00 = c
1742
+ self.e01 = -s
1743
+ self.e10 = s
1744
+ self.e11 = c
1745
+
1746
+ return self
1747
+ end
1748
+
1749
+ #
1750
+ # call-seq: rotationAxis(axis,radian) -> self
1751
+ #
1752
+ # Makes a matrix that rotates around the +axis+.
1753
+ #
1754
+ def rotationAxis( axis, radian )
1755
+ if ( axis.class != RVec3 )
1756
+ raise TypeError, "RMtx4#rotationAxis : Unknown type #{axis.class} given as axis."
1757
+ return nil
1758
+ end
1759
+ s = Math.sin( radian )
1760
+ c = Math.cos( radian )
1761
+ omc = 1.0 - c
1762
+ x = axis.x.to_f
1763
+ y = axis.y.to_f
1764
+ z = axis.z.to_f
1765
+
1766
+ setIdentity()
1767
+
1768
+ self.e00 = x*x*omc + c
1769
+ self.e01 = x*y*omc - z*s
1770
+ self.e02 = z*x*omc + y*s
1771
+ self.e10 = x*y*omc + z*s
1772
+ self.e11 = y*y*omc + c
1773
+ self.e12 = y*z*omc - x*s
1774
+ self.e20 = z*x*omc - y*s
1775
+ self.e21 = y*z*omc + x*s
1776
+ self.e22 = z*z*omc + c
1777
+
1778
+ return self
1779
+ end
1780
+
1781
+ #
1782
+ # call-seq: rotationQuaternion(q) -> self
1783
+ #
1784
+ # Makes a rotation matrix from a normalized quaternion +q+.
1785
+ #
1786
+ def rotationQuaternion( q )
1787
+ if ( q.class != RQuat )
1788
+ raise TypeError, "RMtx4#rotationQuaternion : Unknown type #{q.class} given as RQuat."
1789
+ return nil
1790
+ end
1791
+ x = q.x
1792
+ y = q.y
1793
+ z = q.z
1794
+ w = q.w
1795
+
1796
+ x2 = 2.0 * x
1797
+ y2 = 2.0 * y
1798
+ z2 = 2.0 * z
1799
+
1800
+ xx2 = x * x2
1801
+ yy2 = y * y2
1802
+ zz2 = z * z2
1803
+
1804
+ yz2 = y * z2
1805
+ wx2 = w * x2
1806
+ xy2 = x * y2
1807
+ wz2 = w * z2
1808
+ xz2 = x * z2
1809
+ wy2 = w * y2
1810
+
1811
+ setIdentity()
1812
+
1813
+ self.e00 = 1.0 - yy2 - zz2
1814
+ self.e10 = xy2 + wz2
1815
+ self.e20 = xz2 - wy2
1816
+ self.e01 = xy2 - wz2
1817
+ self.e11 = 1.0 - xx2 - zz2
1818
+ self.e21 = yz2 + wx2
1819
+ self.e02 = xz2 + wy2
1820
+ self.e12 = yz2 - wx2
1821
+ self.e22 = 1.0 - xx2 - yy2
1822
+
1823
+ return self
1824
+ end
1825
+
1826
+ #
1827
+ # call-seq: scaling(sx,sy,sz) -> self
1828
+ #
1829
+ # Makes itself as a scaling matrix.
1830
+ #
1831
+ def scaling( sx, sy, sz )
1832
+ setIdentity()
1833
+ setElement( 0, 0, sx )
1834
+ setElement( 1, 1, sy )
1835
+ setElement( 2, 2, sz )
1836
+
1837
+ return self
1838
+ end
1839
+
1840
+ #
1841
+ # call-seq: lookAtLH(eye,at,up) -> self
1842
+ #
1843
+ # Builds a viewing matrix for a left-handed coordinate system from:
1844
+ # * eye position (+eye+: RVec3)
1845
+ # * a point looking at (+at+: RVec3)
1846
+ # * up vector (+up+: RVec3)
1847
+ #
1848
+ def lookAtLH( eye, at, up )
1849
+ setIdentity()
1850
+
1851
+ axis_z = (at - eye).normalize!
1852
+ axis_x = RVec3.cross( up, axis_z ).normalize!
1853
+ axis_y = RVec3.cross( axis_z, axis_x )
1854
+
1855
+ self.e00 = axis_x[0]
1856
+ self.e01 = axis_x[1]
1857
+ self.e02 = axis_x[2]
1858
+ self.e03 = -RVec3.dot( axis_x, eye )
1859
+
1860
+ self.e10 = axis_y[0]
1861
+ self.e11 = axis_y[1]
1862
+ self.e12 = axis_y[2]
1863
+ self.e13 = -RVec3.dot( axis_y, eye )
1864
+
1865
+ self.e20 = axis_z[0]
1866
+ self.e21 = axis_z[1]
1867
+ self.e22 = axis_z[2]
1868
+ self.e23 = -RVec3.dot( axis_z, eye )
1869
+
1870
+ return self
1871
+ end
1872
+
1873
+ #
1874
+ # call-seq: lookAtRH(eye,at,up) -> self
1875
+ #
1876
+ # Builds a viewing matrix for a right-handed coordinate system from:
1877
+ # * eye position (+eye+: RVec3)
1878
+ # * a point looking at (+at+: RVec3)
1879
+ # * up vector (+up+: RVec3)
1880
+ #
1881
+ def lookAtRH( eye, at, up )
1882
+ setIdentity()
1883
+
1884
+ axis_z = (eye - at).normalize!
1885
+ axis_x = RVec3.cross( up, axis_z ).normalize!
1886
+ axis_y = RVec3.cross( axis_z, axis_x )
1887
+
1888
+ self.e00 = axis_x[0]
1889
+ self.e01 = axis_x[1]
1890
+ self.e02 = axis_x[2]
1891
+ self.e03 = -RVec3.dot( axis_x, eye )
1892
+
1893
+ self.e10 = axis_y[0]
1894
+ self.e11 = axis_y[1]
1895
+ self.e12 = axis_y[2]
1896
+ self.e13 = -RVec3.dot( axis_y, eye )
1897
+
1898
+ self.e20 = axis_z[0]
1899
+ self.e21 = axis_z[1]
1900
+ self.e22 = axis_z[2]
1901
+ self.e23 = -RVec3.dot( axis_z, eye )
1902
+
1903
+ return self
1904
+ end
1905
+
1906
+ #
1907
+ # call-seq: perspectiveRH(width,height,znear,zfar,ndc_convention) -> self
1908
+ #
1909
+ # Builds a perspective projection matrix for a right-handed coordinate system from:
1910
+ # * View volume width (+width+)
1911
+ # * View volume height (+height+)
1912
+ # * Near clip plane distance (+znear+)
1913
+ # * Far clip plane distance (+zfar+)
1914
+ # * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
1915
+ #
1916
+ def perspectiveRH( width, height, znear, zfar, ndc_homogeneous = true)
1917
+ perspectiveOffCenterRH(-width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar, ndc_homogeneous )
1918
+ return self
1919
+ end
1920
+
1921
+ #
1922
+ # call-seq: perspectiveFovRH(fovy,aspect,znear,zfar,ndc_homogeneous) -> self
1923
+ #
1924
+ # Builds a perspective projection matrix for a right-handed coordinate system from:
1925
+ # * Field of view in y direction (+fovy+ radian)
1926
+ # * Aspect ratio (+aspect+)
1927
+ # * Near clip plane distance (+znear+)
1928
+ # * Far clip plane distance (+zfar+)
1929
+ # * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
1930
+ #
1931
+ def perspectiveFovRH( fovy_radian, aspect, znear, zfar, ndc_homogeneous = true)
1932
+ f = Math::tan( fovy_radian / 2.0 )
1933
+ f = 1.0 / f
1934
+
1935
+ c = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -zfar / (zfar-znear)
1936
+ d = ndc_homogeneous ? -(2*znear*zfar) / (zfar-znear) : -(znear*zfar) / (zfar-znear)
1937
+
1938
+ setIdentity()
1939
+ setElement( 0, 0, f / aspect )
1940
+ setElement( 1, 1, f )
1941
+ setElement( 2, 2, c )
1942
+ setElement( 2, 3, d )
1943
+ setElement( 3, 2, -1.0 )
1944
+ setElement( 3, 3, 0.0 )
1945
+
1946
+ return self
1947
+ end
1948
+
1949
+ #
1950
+ # call-seq: perspectiveOffCenterRH(left,right,bottom,top,znear,zfar) -> self
1951
+ #
1952
+ # Builds a perspective projection matrix for a right-handed coordinate system from:
1953
+ # * Minimum value of the view volume width (+left+)
1954
+ # * Maximum value of the view volume width (+right+)
1955
+ # * Minimum value of the view volume height (+bottom+)
1956
+ # * Maximum value of the view volume height (+top+)
1957
+ # * Near clip plane distance (+znear+)
1958
+ # * Far clip plane distance (+zfar+)
1959
+ # * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
1960
+ #
1961
+ def perspectiveOffCenterRH( left, right, bottom, top, znear, zfar, ndc_homogeneous = true)
1962
+ a = (right+left) / (right-left)
1963
+ b = (top+bottom) / (top-bottom)
1964
+ c = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -zfar / (zfar-znear)
1965
+ d = ndc_homogeneous ? -(2*znear*zfar) / (zfar-znear) : -(znear*zfar) / (zfar-znear)
1966
+
1967
+ setIdentity()
1968
+
1969
+ setElement( 0, 0, 2*znear/(right-left) )
1970
+ setElement( 0, 2, a )
1971
+ setElement( 1, 1, 2*znear/(top-bottom) )
1972
+ setElement( 1, 2, b )
1973
+ setElement( 2, 2, c )
1974
+ setElement( 2, 3, d )
1975
+ setElement( 3, 2, -1.0 )
1976
+ setElement( 3, 3, 0.0 )
1977
+
1978
+ return self
1979
+ end
1980
+
1981
+ #
1982
+ # call-seq: orthoRH(width,height,znear,zfar) -> self
1983
+ #
1984
+ # Builds a orthogonal projection matrix for a right-handed coordinate system from:
1985
+ # * View volume width (+width+)
1986
+ # * View volume height (+height+)
1987
+ # * Near clip plane distance (+znear+)
1988
+ # * Far clip plane distance (+zfar+)
1989
+ # * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
1990
+ #
1991
+ def orthoRH( width, height, znear, zfar, ndc_homogeneous = true)
1992
+ orthoOffCenterRH( -width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar, ndc_homogeneous )
1993
+ return self
1994
+ end
1995
+
1996
+ #
1997
+ # call-seq: orthoOffCenterRH(left,right,bottom,top,znear,zfar) -> self
1998
+ #
1999
+ # Builds a orthogonal projection matrix for a right-handed coordinate system from:
2000
+ # * Minimum value of the view volume width (+left+)
2001
+ # * Maximum value of the view volume width (+right+)
2002
+ # * Minimum value of the view volume height (+bottom+)
2003
+ # * Maximum value of the view volume height (+top+)
2004
+ # * Near clip plane distance (+znear+)
2005
+ # * Far clip plane distance (+zfar+)
2006
+ # * Set true for the environment with Z coordinate ranges from -1 to +1 (OpenGL), and false otherwise (Direct3D, Metal) (+ndc_homogeneous+)
2007
+ #
2008
+ def orthoOffCenterRH( left, right, bottom, top, znear, zfar, ndc_homogeneous = true)
2009
+ tx = -(right+left) / (right-left)
2010
+ ty = -(top+bottom) / (top-bottom)
2011
+ tz = ndc_homogeneous ? -(zfar+znear) / (zfar-znear) : -znear / (zfar-znear)
2012
+
2013
+ setIdentity()
2014
+
2015
+ setElement( 0, 0, 2.0/(right-left) )
2016
+ setElement( 0, 3, tx )
2017
+ setElement( 1, 1, 2.0/(top-bottom) )
2018
+ setElement( 1, 3, ty )
2019
+ setElement( 2, 2, -(ndc_homogeneous ? 2.0 : 1.0)/(zfar-znear) )
2020
+ setElement( 2, 3, tz )
2021
+
2022
+ return self
2023
+ end
2024
+
2025
+ #
2026
+ # call-seq: +
2027
+ #
2028
+ # +mtx : Unary plus operator.
2029
+ #
2030
+ def +@
2031
+ return self
2032
+ end
2033
+
2034
+ #
2035
+ # call-seq: -
2036
+ #
2037
+ # -mtx : Unary minus operator.
2038
+ #
2039
+ def -@
2040
+ return RMtx4.new( self * -1.0 )
2041
+ end
2042
+
2043
+ #
2044
+ # call-seq: +
2045
+ #
2046
+ # mtx1 + mtx2 : Binary plus operator.
2047
+ #
2048
+ def +( arg )
2049
+ if ( arg.class != RMtx4 )
2050
+ raise TypeError, "RMtx4#+(arg) : Unknown type #{arg.class} given as RMtx4."
2051
+ return nil
2052
+ end
2053
+
2054
+ result = RMtx4.new
2055
+ for row in 0...4 do
2056
+ for col in 0...4 do
2057
+ result.setElement( row, col, getElement(row,col) + arg.getElement(row,col) )
2058
+ end
2059
+ end
2060
+
2061
+ return result
2062
+ end
2063
+
2064
+ #
2065
+ # call-seq: -
2066
+ #
2067
+ # mtx1 - mtx2 : Binary minus operator.
2068
+ #
2069
+ def -( arg )
2070
+ if ( arg.class != RMtx4 )
2071
+ raise TypeError, "RMtx4#-(arg) : Unknown type #{arg.class} given as RMtx4."
2072
+ return nil
2073
+ end
2074
+
2075
+ result = RMtx4.new
2076
+ for row in 0...4 do
2077
+ for col in 0...4 do
2078
+ result.setElement( row, col, getElement(row,col) - arg.getElement(row,col) )
2079
+ end
2080
+ end
2081
+
2082
+ return result
2083
+ end
2084
+
2085
+ #
2086
+ # call-seq: *
2087
+ #
2088
+ # mtx1 * mtx2 : Binary multiply operator.
2089
+ #
2090
+ def *( arg )
2091
+ case arg
2092
+ when Float, Integer
2093
+ return RMtx4.new( arg*self.e00, arg*self.e01, arg*self.e02, arg*self.e03,
2094
+ arg*self.e10, arg*self.e11, arg*self.e12, arg*self.e13,
2095
+ arg*self.e20, arg*self.e21, arg*self.e22, arg*self.e23,
2096
+ arg*self.e30, arg*self.e31, arg*self.e32, arg*self.e33 )
2097
+
2098
+ when RMtx4
2099
+ result = RMtx4.new
2100
+ for row in 0...4 do
2101
+ for col in 0...4 do
2102
+ sum = 0.0
2103
+ for i in 0...4 do
2104
+ sum += getElement( row, i ) * arg.getElement( i, col )
2105
+ end
2106
+ result.setElement( row, col, sum )
2107
+ end
2108
+ end
2109
+ return result
2110
+
2111
+ else
2112
+ raise TypeError, "RMtx4#*(arg) : Unknown type #{arg.class} given."
2113
+ return nil
2114
+ end
2115
+ end
2116
+
2117
+ #
2118
+ # call-seq: ==
2119
+ #
2120
+ # mtx1 == mtx2 : evaluates equality.
2121
+ #
2122
+ def ==( other )
2123
+ if other.class == RMtx4
2124
+ for row in 0...4 do
2125
+ for col in 0...4 do
2126
+ if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
2127
+ return false
2128
+ end
2129
+ end
2130
+ end
2131
+ return true
2132
+ else
2133
+ return false
2134
+ end
2135
+ end
2136
+
2137
+ #
2138
+ # call-seq: mtx1.add!( mtx2 )
2139
+ #
2140
+ # mtx1 += mtx2 : appends the elements of +mtx2+ into corresponding +mtx1+ elements.
2141
+ #
2142
+ def add!( other )
2143
+ if ( other.class != RMtx4 )
2144
+ raise TypeError, "RMtx4#add! : Unknown type #{other.class} given as RMtx4."
2145
+ return nil
2146
+ end
2147
+
2148
+ result = RMtx4.new
2149
+ for row in 0...4 do
2150
+ for col in 0...4 do
2151
+ self.setElement( row, col, getElement(row,col) + other.getElement(row,col) )
2152
+ end
2153
+ end
2154
+
2155
+ return self
2156
+ end
2157
+
2158
+ #
2159
+ # call-seq: mtx1.sub!( mtx2 )
2160
+ #
2161
+ # mtx1 -= mtx2 : subtracts the elements of +mtx2+ from corresponding +mtx1+ elements.
2162
+ #
2163
+ def sub!( other )
2164
+ if ( other.class != RMtx4 )
2165
+ raise TypeError, "RMtx4#sub! : Unknown type #{other.class} given as RMtx4."
2166
+ return nil
2167
+ end
2168
+
2169
+ result = RMtx4.new
2170
+ for row in 0...4 do
2171
+ for col in 0...4 do
2172
+ self.setElement( row, col, getElement(row,col) - other.getElement(row,col) )
2173
+ end
2174
+ end
2175
+
2176
+ return self
2177
+ end
2178
+
2179
+ #
2180
+ # call-seq: mtx1.mul!( mtx2 )
2181
+ #
2182
+ # mtx1 *= mtx2
2183
+ #
2184
+ def mul!( other )
2185
+ case other
2186
+ when Float, Integer
2187
+ self.e00 = other*self.e00
2188
+ self.e01 = other*self.e01
2189
+ self.e02 = other*self.e02
2190
+ self.e03 = other*self.e03
2191
+
2192
+ self.e10 = other*self.e10
2193
+ self.e11 = other*self.e11
2194
+ self.e12 = other*self.e12
2195
+ self.e13 = other*self.e13
2196
+
2197
+ self.e20 = other*self.e20
2198
+ self.e21 = other*self.e21
2199
+ self.e22 = other*self.e22
2200
+ self.e23 = other*self.e23
2201
+
2202
+ self.e30 = other*self.e30
2203
+ self.e31 = other*self.e31
2204
+ self.e32 = other*self.e32
2205
+ self.e33 = other*self.e33
2206
+
2207
+ return self
2208
+
2209
+ when RMtx4
2210
+ result = RMtx4.new
2211
+ for row in 0...4 do
2212
+ for col in 0...4 do
2213
+ sum = 0.0
2214
+ for i in 0...4 do
2215
+ sum += getElement( row, i ) * other.getElement( i, col )
2216
+ end
2217
+ result.setElement( row, col, sum )
2218
+ end
2219
+ end
2220
+
2221
+ self.e00 = result.e00
2222
+ self.e01 = result.e01
2223
+ self.e02 = result.e02
2224
+ self.e03 = result.e03
2225
+
2226
+ self.e10 = result.e10
2227
+ self.e11 = result.e11
2228
+ self.e12 = result.e12
2229
+ self.e13 = result.e13
2230
+
2231
+ self.e20 = result.e20
2232
+ self.e21 = result.e21
2233
+ self.e22 = result.e22
2234
+ self.e23 = result.e23
2235
+
2236
+ self.e30 = result.e30
2237
+ self.e31 = result.e31
2238
+ self.e32 = result.e32
2239
+ self.e33 = result.e33
2240
+
2241
+ return self
2242
+ end
2243
+ end
2244
+ end
2245
+
2246
+ #
2247
+ # Document-class: RMath3D::RQuat
2248
+ # provies quaternion arithmetic.
2249
+ #
2250
+ class RQuat
2251
+
2252
+ #
2253
+ # call-seq:
2254
+ # RQuat.new -> (0,0,0,0)
2255
+ # RQuat.new(e) -> (e,e,e,e)
2256
+ # RQuat.new( other ) : Copy Constructor
2257
+ # RQuat.new( e0, e1, e2, e3 ) -> (e0,e1,e2,e3)
2258
+ #
2259
+ # Creates a new quaternion.
2260
+ #
2261
+ def initialize( *a )
2262
+ @e = []
2263
+ case a.length
2264
+ when 0
2265
+ @e = [0.0, 0.0, 0.0, 0.0]
2266
+ when 1
2267
+ case a[0]
2268
+ when Float, Integer
2269
+ @e = [ a[0], a[0], a[0], a[0] ]
2270
+ when RQuat
2271
+ @e = [ a[0].x, a[0].y, a[0].z, a[0].w ]
2272
+ else
2273
+ raise TypeError, "RQuat#initialize : Unknown type #{a[0].class}."
2274
+ return nil
2275
+ end
2276
+ when 4
2277
+ a.each_with_index do |elem, index|
2278
+ case elem
2279
+ when Float, Integer
2280
+ @e[index] = elem
2281
+ else
2282
+ raise TypeError, "RQuat#initialize : Unknown type #{elem.class}."
2283
+ return nil
2284
+ end
2285
+ end
2286
+ else
2287
+ raise RuntimeError, "RQuat#initialize : wrong # of arguments (#{a.length})"
2288
+ return nil
2289
+ end
2290
+ return self
2291
+ end
2292
+
2293
+ #
2294
+ # call-seq: to_s
2295
+ #
2296
+ # Returns human-readable string.
2297
+ #
2298
+ def to_s
2299
+ return "( #{@e[0]}, #{@e[1]}, #{@e[2]}, #{@e[3]} )"
2300
+ end
2301
+
2302
+ #
2303
+ # call-seq: to_a
2304
+ #
2305
+ # Returns its elements as a new Array.
2306
+ #
2307
+ def to_a
2308
+ return @e
2309
+ end
2310
+
2311
+ #
2312
+ # call-seq: coerse(other)
2313
+ #
2314
+ # Resolves type mismatch.
2315
+ #
2316
+ def coerce( arg )
2317
+ case arg
2318
+ when Float, Integer
2319
+ return [ self, arg ]
2320
+ else
2321
+ raise TypeError, "RQuat#coerce : #{arg.self} can't be coerced into #{self.class}."
2322
+ return nil
2323
+ end
2324
+ end
2325
+
2326
+ #
2327
+ # call-seq: setElements( e0, e1, e2, e3 )
2328
+ #
2329
+ # Stores given 4 new values.
2330
+ #
2331
+ def setElements( x, y, z, w )
2332
+ self.x = x
2333
+ self.y = y
2334
+ self.z = z
2335
+ self.w = w
2336
+ end
2337
+
2338
+ #
2339
+ # call-seq: quat[i]= value
2340
+ #
2341
+ # Stores +value+ at +i+.
2342
+ #
2343
+ def []=(i,value)
2344
+ @e[i] = value
2345
+ end
2346
+
2347
+ #
2348
+ # call-seq: x= value
2349
+ #
2350
+ # Stores +value+ as +x+.
2351
+ #
2352
+ def x=(value) @e[0] = value end
2353
+
2354
+ #
2355
+ # call-seq: y= value
2356
+ #
2357
+ # Stores +value+ as +y+.
2358
+ #
2359
+ def y=(value) @e[1] = value end
2360
+
2361
+ #
2362
+ # call-seq: z= value
2363
+ #
2364
+ # Stores +value+ as +z+.
2365
+ #
2366
+ def z=(value) @e[2] = value end
2367
+
2368
+ #
2369
+ # call-seq: w= value
2370
+ #
2371
+ # Stores +value+ as +w+.
2372
+ #
2373
+ def w=(value) @e[3] = value end
2374
+
2375
+ #
2376
+ # call-seq: xyz= vXYZ
2377
+ #
2378
+ # Copies the values of +vXYZ+(RVec3) into +x+, +y+ and +z+.
2379
+ #
2380
+ def xyz=( arg )
2381
+ if arg.class != RVec3
2382
+ raise TypeError, "RQuat#xyz= : Unknown type #{arg.class}."
2383
+ return nil
2384
+ end
2385
+ @e[0] = arg.x
2386
+ @e[1] = arg.y
2387
+ @e[2] = arg.z
2388
+ end
2389
+
2390
+ #
2391
+ # call-seq: quat[i] -> value
2392
+ #
2393
+ # Returns the element at +i+.
2394
+ #
2395
+ def [](i)
2396
+ @e[i]
2397
+ end
2398
+
2399
+
2400
+ #
2401
+ # call-seq: x -> value
2402
+ #
2403
+ # Returns the value of +x+.
2404
+ #
2405
+ def x() return @e[0] end
2406
+
2407
+ #
2408
+ # call-seq: y -> value
2409
+ #
2410
+ # Returns the value of +y+.
2411
+ #
2412
+ def y() return @e[1] end
2413
+
2414
+ #
2415
+ # call-seq: z -> value
2416
+ #
2417
+ # Returns the value of +z+.
2418
+ #
2419
+ def z() return @e[2] end
2420
+
2421
+ #
2422
+ # call-seq: w -> value
2423
+ #
2424
+ # Returns the value of +w+.
2425
+ #
2426
+ def w() return @e[3] end
2427
+
2428
+ #
2429
+ # call-seq: xyz -> RVec3
2430
+ #
2431
+ # Returns the values of +x+, +y+ and +z+ with new RVec3(+x+,+y+,+z+).
2432
+ #
2433
+ def xyz()
2434
+ return RVec3.new( @e[0], @e[1], @e[2] )
2435
+ end
2436
+
2437
+ #
2438
+ # call-seq: getLength
2439
+ #
2440
+ # Returns the Euclidean length.
2441
+ #
2442
+ def getLength
2443
+ return Math.sqrt( @e[0]*@e[0] + @e[1]*@e[1] + @e[2]*@e[2] + @e[3]*@e[3] )
2444
+ end
2445
+
2446
+ #
2447
+ # call-seq: getLengthSq
2448
+ #
2449
+ # Returns the squared Euclidean length.
2450
+ #
2451
+ def getLengthSq
2452
+ return (@e[0]*@e[0] + @e[1]*@e[1] + @e[2]*@e[2] + @e[3]*@e[3]).to_f
2453
+ end
2454
+
2455
+ #
2456
+ # call-seq: RQuat.dot(q_a,q_b) -> value
2457
+ #
2458
+ # Calculates the dot product of +q_a+ and +q_b+.
2459
+ #
2460
+ def RQuat.dot( q1, q2 )
2461
+ if q1.class != RQuat || q2.class != RQuat
2462
+ raise TypeError, "RQuat#dot : Unknown type q1:#{q2.class}, q2:#{q2.class}."
2463
+ return nil
2464
+ end
2465
+ return q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w
2466
+ end
2467
+
2468
+ #
2469
+ # call-seq: RQuat.slerp( q_a, q_b, t ) -> interpolated quaternion
2470
+ #
2471
+ # Calculates the spherical linear interpolation between +q_a+ and
2472
+ # +q_b+ at time +t+ (0.0~1.0).
2473
+ #
2474
+ def RQuat.slerp( q1, q2, t )
2475
+ if q1.class != RQuat || q2.class != RQuat
2476
+ raise TypeError, "RQuat#slerp : Unknown type q1:#{q2.class}, q2:#{q2.class}."
2477
+ return nil
2478
+ end
2479
+ s1 = 0.0
2480
+ s2 = 0.0
2481
+ it = 1.0 - t
2482
+ cosine = RQuat.dot( q1, q2 )
2483
+
2484
+ qn1 = q1
2485
+ qn2 = q2
2486
+
2487
+ if ( cosine < 0.0 )
2488
+ cosine *= -1.0
2489
+ qn1 *= -1.0
2490
+ end
2491
+
2492
+ if ( (1.0 - cosine) > TOLERANCE )
2493
+ theta = Math.acos( cosine )
2494
+ sin_theta = Math.sin( theta )
2495
+
2496
+ s1 = Math.sin( it * theta ) / sin_theta
2497
+ s2 = Math.sin( t * theta ) / sin_theta
2498
+ else
2499
+ s1 = it
2500
+ s2 = t
2501
+ end
2502
+
2503
+ qn1 *= s1
2504
+ qn2 *= s2
2505
+ qResult = qn1 + qn2
2506
+
2507
+ return qResult
2508
+ end
2509
+
2510
+ #
2511
+ # call-seq: setIdentity
2512
+ #
2513
+ # Sets as identity quaternion.
2514
+ #
2515
+ def setIdentity
2516
+ self.x = 0.0
2517
+ self.y = 0.0
2518
+ self.z = 0.0
2519
+ self.w = 1.0
2520
+ return self
2521
+ end
2522
+
2523
+ #
2524
+ # call-seq: getConjugated
2525
+ #
2526
+ # Returns its conjugate quaternion.
2527
+ #
2528
+ def getConjugated
2529
+ return RQuat.new( -@e[0], -@e[1], -@e[2], @e[3] )
2530
+ end
2531
+
2532
+ #
2533
+ # call-seq: conjugate!
2534
+ #
2535
+ # Conjugates itself.
2536
+ #
2537
+ def conjugate!
2538
+ @e[0] *= -1.0
2539
+ @e[1] *= -1.0
2540
+ @e[2] *= -1.0
2541
+ return self
2542
+ end
2543
+
2544
+ #
2545
+ # call-seq: getInverse -> inverse quaternion
2546
+ #
2547
+ # Returns the inverse.
2548
+ #
2549
+ def getInverse
2550
+ length_sq = getLengthSq()
2551
+ return RQuat.new( -@e[0]/length_sq, -@e[1]/length_sq, -@e[2]/length_sq, @e[3]/length_sq )
2552
+ end
2553
+
2554
+ #
2555
+ # call-seq: invert! -> self
2556
+ #
2557
+ # Inverts itself.
2558
+ #
2559
+ def invert!
2560
+ length_sq = getLengthSq()
2561
+ @e[0] /= -length_sq
2562
+ @e[1] /= -length_sq
2563
+ @e[2] /= -length_sq
2564
+ @e[3] /= length_sq
2565
+ return self
2566
+ end
2567
+
2568
+ #
2569
+ # call-seq: getNormalized -> RQuat
2570
+ #
2571
+ # Returns normalized quaternion.
2572
+ #
2573
+ def getNormalized
2574
+ length = getLength()
2575
+ return RQuat.new( @e[0]/length, @e[1]/length, @e[2]/length, @e[3]/length )
2576
+ end
2577
+
2578
+ #
2579
+ # call-seq: normalize! -> self
2580
+ #
2581
+ # Normalizes itself.
2582
+ #
2583
+ def normalize!
2584
+ length = getLength()
2585
+ @e[0] /= length
2586
+ @e[1] /= length
2587
+ @e[2] /= length
2588
+ @e[3] /= length
2589
+ return self
2590
+ end
2591
+
2592
+ #
2593
+ # call-seq: +
2594
+ #
2595
+ # +quat : Unary plus operator.
2596
+ #
2597
+ def +@
2598
+ return self
2599
+ end
2600
+
2601
+ #
2602
+ # call-seq: -
2603
+ #
2604
+ # -quat : Unary minus operator.
2605
+ #
2606
+ def -@
2607
+ return RQuat.new( -@e[0], -@e[1], -@e[2], -@e[3] )
2608
+ end
2609
+
2610
+ #
2611
+ # call-seq: +
2612
+ #
2613
+ # quat1 + quat2 : Binary plus operator.
2614
+ #
2615
+ def +( arg )
2616
+ if arg.class != RQuat
2617
+ raise TypeError, "RQuat#+ : Unknown type #{arg.class}."
2618
+ return nil
2619
+ end
2620
+ RQuat.new( x+arg.x, y+arg.y, z+arg.z, w+arg.w )
2621
+ end
2622
+
2623
+ #
2624
+ # call-seq: -
2625
+ #
2626
+ # quat1 - quat2 : Binary minus operator.
2627
+ #
2628
+ def -( arg )
2629
+ if arg.class != RQuat
2630
+ raise TypeError, "RQuat#- : Unknown type #{arg.class}."
2631
+ return nil
2632
+ end
2633
+ RQuat.new( x-arg.x, y-arg.y, z-arg.z, w-arg.w )
2634
+ end
2635
+
2636
+ #
2637
+ # call-seq: *
2638
+ #
2639
+ # quat1 * quat2 : Binary multiply operator.
2640
+ #
2641
+ def *( arg )
2642
+ case arg
2643
+ when RQuat
2644
+ q1x = self.x
2645
+ q1y = self.y
2646
+ q1z = self.z
2647
+ q1w = self.w
2648
+ q2x = arg.x
2649
+ q2y = arg.y
2650
+ q2z = arg.z
2651
+ q2w = arg.w
2652
+ x = q1w*q2x + q1x*q2w + q1y*q2z - q1z*q2y
2653
+ y = q1w*q2y - q1x*q2z + q1y*q2w + q1z*q2x
2654
+ z = q1w*q2z + q1x*q2y - q1y*q2x + q1z*q2w
2655
+ w = q1w*q2w - q1x*q2x - q1y*q2y - q1z*q2z
2656
+ return RQuat.new( x, y, z, w )
2657
+ when Float, Integer
2658
+ return RQuat.new( @e[0]*arg, @e[1]*arg, @e[2]*arg, @e[3]*arg )
2659
+ else
2660
+ raise TypeError, "RQuat#* : Unknown type #{arg}."
2661
+ return nil
2662
+ end
2663
+ end
2664
+
2665
+ #
2666
+ # call-seq: ==
2667
+ #
2668
+ # quat1 == quat2 : evaluates equality.
2669
+ #
2670
+ def ==( other )
2671
+ if other.class == RQuat
2672
+ if (x-other.x).abs<=Float::EPSILON &&
2673
+ (y-other.y).abs<=Float::EPSILON &&
2674
+ (z-other.z).abs<=Float::EPSILON &&
2675
+ (w-other.w).abs<=Float::EPSILON
2676
+ return true
2677
+ else
2678
+ return false
2679
+ end
2680
+ else
2681
+ return false
2682
+ end
2683
+ end
2684
+
2685
+ #
2686
+ # call-seq: quat1.add!( quat2 )
2687
+ #
2688
+ # quat1 += quat2 : appends the elements of +quat2+ into corresponding +quat1+ elements.
2689
+ #
2690
+ def add!( other )
2691
+ if other.class != RQuat
2692
+ raise TypeError, "RQ#add! : Unknown type #{other.class}."
2693
+ return nil
2694
+ end
2695
+
2696
+ self.x += other.x
2697
+ self.y += other.y
2698
+ self.z += other.z
2699
+ self.w += other.w
2700
+
2701
+ return self
2702
+ end
2703
+
2704
+ #
2705
+ # call-seq: quat1.sub!( quat2 )
2706
+ #
2707
+ # quat1 -= quat2 : subtracts the elements of +quat2+ from corresponding +quat1+ elements.
2708
+ #
2709
+ def sub!( other )
2710
+ if other.class != RQuat
2711
+ raise TypeError, "RQuat#sub! : Unknown type #{other.class}."
2712
+ return nil
2713
+ end
2714
+
2715
+ self.x -= other.x
2716
+ self.y -= other.y
2717
+ self.z -= other.z
2718
+ self.w -= other.w
2719
+
2720
+ return self
2721
+ end
1805
2722
 
1806
2723
  #
1807
- # call-seq: xyz= vXYZ
2724
+ # call-seq: quat1.mul!( quat2 )
1808
2725
  #
1809
- # Copies the values of +vXYZ+(RVec3) into +x+, +y+ and +z+.
2726
+ # quat1 *= quat2
1810
2727
  #
1811
- def xyz=( arg )
1812
- if arg.class != RVec3
1813
- raise TypeError, "RQuat#xyz= : Unknown type #{arg.class}."
2728
+ def mul!( other )
2729
+ case other
2730
+ when RQuat
2731
+ q1x = self.x
2732
+ q1y = self.y
2733
+ q1z = self.z
2734
+ q1w = self.w
2735
+ q2x = other.x
2736
+ q2y = other.y
2737
+ q2z = other.z
2738
+ q2w = other.w
2739
+
2740
+ x = q1w*q2x + q1x*q2w + q1y*q2z - q1z*q2y
2741
+ y = q1w*q2y - q1x*q2z + q1y*q2w + q1z*q2x
2742
+ z = q1w*q2z + q1x*q2y - q1y*q2x + q1z*q2w
2743
+ w = q1w*q2w - q1x*q2x - q1y*q2y - q1z*q2z
2744
+
2745
+ self.x = x
2746
+ self.y = y
2747
+ self.z = z
2748
+ self.w = w
2749
+
2750
+ return self
2751
+
2752
+ when Float, Integer
2753
+ self.x *= other
2754
+ self.y *= other
2755
+ self.z *= other
2756
+ self.w *= other
2757
+ return self
2758
+
2759
+ else
2760
+ raise TypeError, "RQuat#mul! : Unknown type #{other.class}."
1814
2761
  return nil
1815
2762
  end
1816
- @e[0] = arg.x
1817
- @e[1] = arg.y
1818
- @e[2] = arg.z
1819
2763
  end
1820
2764
 
1821
2765
  #
1822
- # call-seq: quat[i] -> value
2766
+ # call-seq: rotationMarix(mtx4) -> self
1823
2767
  #
1824
- # Returns the element at +i+.
2768
+ # Makes a rotation quaternion from a rotation matrix +mtx4+ (RMtx4).
1825
2769
  #
1826
- def [](i)
1827
- @e[i]
1828
- end
2770
+ def rotationMatrix( mtx )
2771
+ if mtx.class != RMtx3 && mtx.class != RMtx4
2772
+ raise TypeError, "RQuat#rotationMatrix : Unknown type #{mtx.class}."
2773
+ return nil
2774
+ end
2775
+
2776
+ diag00 = mtx.getElement(0,0)
2777
+ diag11 = mtx.getElement(1,1)
2778
+ diag22 = mtx.getElement(2,2)
2779
+
2780
+ if ( diag00 + diag11 + diag22 > 0.0 )
2781
+ t = diag00 + diag11 + diag22 + 1.0
2782
+ s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2783
+ self.w = s * t
2784
+ self.z = (mtx.getElement(1,0) - mtx.getElement(0,1)) * s
2785
+ self.y = (mtx.getElement(0,2) - mtx.getElement(2,0)) * s
2786
+ self.x = (mtx.getElement(2,1) - mtx.getElement(1,2)) * s
2787
+ elsif ( diag00 > diag11 && diag00 > diag22 )
2788
+ t = diag00 - diag11 - diag22 + 1.0
2789
+ s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2790
+ self.x = s * t
2791
+ self.y = (mtx.getElement(1,0) + mtx.getElement(0,1)) * s
2792
+ self.z = (mtx.getElement(0,2) + mtx.getElement(2,0)) * s
2793
+ self.w = (mtx.getElement(2,1) - mtx.getElement(1,2)) * s
2794
+ elsif ( diag11 > diag22 )
2795
+ t = -diag00 + diag11 - diag22 + 1.0
2796
+ s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2797
+ self.y = s * t
2798
+ self.x = (mtx.getElement(1,0) + mtx.getElement(0,1)) * s
2799
+ self.w = (mtx.getElement(0,2) - mtx.getElement(2,0)) * s
2800
+ self.z = (mtx.getElement(2,1) + mtx.getElement(1,2)) * s
2801
+ else
2802
+ t = -diag00 - diag11 + diag22 + 1.0
2803
+ s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2804
+ self.z = s * t
2805
+ self.w = (mtx.getElement(1,0) - mtx.getElement(0,1)) * s
2806
+ self.x = (mtx.getElement(0,2) + mtx.getElement(2,0)) * s
2807
+ self.y = (mtx.getElement(2,1) + mtx.getElement(1,2)) * s
2808
+ end
1829
2809
 
2810
+ return self
2811
+ end
1830
2812
 
1831
2813
  #
1832
- # call-seq: x -> value
2814
+ # call-seq: rotationAxis(axis,radian) -> self
1833
2815
  #
1834
- # Returns the value of +x+.
2816
+ # Makes a quaternion that rotates around the +axis+.
1835
2817
  #
1836
- def x() return @e[0] end
2818
+ def rotationAxis( axis, radian )
2819
+ if axis.class != RVec3
2820
+ raise TypeError, "RQuat#rotationAxis : Unknown type #{axis.class}."
2821
+ return nil
2822
+ end
2823
+
2824
+ s = Math.sin( radian / 2.0 )
2825
+ self.x = s * axis.x
2826
+ self.y = s * axis.y
2827
+ self.z = s * axis.z
2828
+ self.w = Math.cos( radian / 2.0 )
2829
+
2830
+ return self
2831
+ end
1837
2832
 
1838
2833
  #
1839
- # call-seq: y -> value
2834
+ # call-seq: toAxisAngle -> [axis,radian]
1840
2835
  #
1841
- # Returns the value of +y+.
2836
+ # Returns its rotation axis (RVec3) and rotation angle (in radian).
1842
2837
  #
1843
- def y() return @e[1] end
2838
+ def toAxisAngle
2839
+ axis = RVec3.new( self.x, self.y, self.z ).normalize!
2840
+ radian = 2.0 * Math.acos( self.w )
2841
+
2842
+ return [ axis, radian ]
2843
+ end
2844
+ end
2845
+
2846
+ #
2847
+ # Document-class: RMath3D::RVec2
2848
+ # provies 2 element vector arithmetic.
2849
+ #
2850
+ class RVec2
1844
2851
 
1845
2852
  #
1846
- # call-seq: z -> value
2853
+ # call-seq:
2854
+ # RVec2.new -> (0,0)
2855
+ # RVec2.new(e) -> (e,e)
2856
+ # RVec2.new( other ) : Copy Constructor
2857
+ # RVec2.new( e0, e1 ) -> (e0,e1)
1847
2858
  #
1848
- # Returns the value of +z+.
2859
+ # Creates a new 3 element vector.
1849
2860
  #
1850
- def z() return @e[2] end
2861
+ def initialize( *a )
2862
+ @e = []
2863
+ case a.length
2864
+ when 0
2865
+ @e = [0.0, 0.0]
2866
+ when 1
2867
+ case a[0]
2868
+ when Float, Integer
2869
+ @e = [ a[0], a[0] ]
2870
+ when RVec2
2871
+ @e = [ a[0].x, a[0].y ]
2872
+ else
2873
+ raise TypeError, "RVec2#initialize : Unknown type #{a[0].class}."
2874
+ return nil
2875
+ end
2876
+ when 2
2877
+ a.each_with_index do |elem, index|
2878
+ case elem
2879
+ when Float, Integer
2880
+ @e[index] = elem
2881
+ else
2882
+ raise TypeError, "RVec2#initialize : Unknown type #{elem.class}."
2883
+ return nil
2884
+ end
2885
+ end
2886
+ else
2887
+ raise RuntimeError, "RVec2#initialize : wrong # of arguments (#{a.length})"
2888
+ return nil
2889
+ end
2890
+ return self
2891
+ end
1851
2892
 
1852
2893
  #
1853
- # call-seq: w -> value
2894
+ # call-seq: to_s
1854
2895
  #
1855
- # Returns the value of +w+.
2896
+ # Returns human-readable string.
1856
2897
  #
1857
- def w() return @e[3] end
2898
+ def to_s
2899
+ return "( #{@e[0]}, #{@e[1]} )"
2900
+ end
1858
2901
 
1859
2902
  #
1860
- # call-seq: xyz -> RVec3
2903
+ # call-seq: to_a
1861
2904
  #
1862
- # Returns the values of +x+, +y+ and +z+ with new RVec3(+x+,+y+,+z+).
2905
+ # Returns its elements as a new Array.
1863
2906
  #
1864
- def xyz()
1865
- return RVec3.new( @e[0], @e[1], @e[2] )
2907
+ def to_a
2908
+ return @e
1866
2909
  end
1867
2910
 
1868
2911
  #
1869
- # call-seq: getLength
2912
+ # call-seq: coerse(other)
1870
2913
  #
1871
- # Returns the Euclidean length.
2914
+ # Resolves type mismatch.
1872
2915
  #
1873
- def getLength
1874
- return Math.sqrt( @e[0]*@e[0] + @e[1]*@e[1] + @e[2]*@e[2] + @e[3]*@e[3] )
2916
+ def coerce( arg )
2917
+ case arg
2918
+ when Float, Integer
2919
+ return [ self, arg ]
2920
+ else
2921
+ raise TypeError, "RVec2#coerce : #{arg.self} can't be coerced into #{self.class}."
2922
+ return nil
2923
+ end
1875
2924
  end
1876
2925
 
1877
2926
  #
1878
- # call-seq: getLengthSq
2927
+ # call-seq: setElements( e0, e1 )
1879
2928
  #
1880
- # Returns the squared Euclidean length.
2929
+ # Stores given 2 new values.
1881
2930
  #
1882
- def getLengthSq
1883
- return (@e[0]*@e[0] + @e[1]*@e[1] + @e[2]*@e[2] + @e[3]*@e[3]).to_f
2931
+ def setElements( x, y )
2932
+ self.x = x
2933
+ self.y = y
1884
2934
  end
1885
2935
 
1886
2936
  #
1887
- # call-seq: RQuat.dot(q_a,q_b) -> value
2937
+ # call-seq: vec2[i]= value
1888
2938
  #
1889
- # Calculates the dot product of +q_a+ and +q_b+.
2939
+ # Stores +value+ at +i+.
1890
2940
  #
1891
- def RQuat.dot( q1, q2 )
1892
- if q1.class != RQuat || q2.class != RQuat
1893
- raise TypeError, "RQuat#dot : Unknown type q1:#{q2.class}, q2:#{q2.class}."
1894
- return nil
1895
- end
1896
- return q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w
2941
+ def []=(i,value)
2942
+ @e[i] = value
1897
2943
  end
1898
2944
 
1899
2945
  #
1900
- # call-seq: RQuat.slerp( q_a, q_b, t ) -> interpolated quaternion
2946
+ # call-seq: x= value
1901
2947
  #
1902
- # Calculates the spherical linear interpolation between +q_a+ and
1903
- # +q_b+ at time +t+ (0.0~1.0).
2948
+ # Stores +value+ as +x+.
1904
2949
  #
1905
- def RQuat.slerp( q1, q2, t )
1906
- if q1.class != RQuat || q2.class != RQuat
1907
- raise TypeError, "RQuat#slerp : Unknown type q1:#{q2.class}, q2:#{q2.class}."
1908
- return nil
1909
- end
1910
- s1 = 0.0
1911
- s2 = 0.0
1912
- it = 1.0 - t
1913
- cosine = RQuat.dot( q1, q2 )
1914
-
1915
- qn1 = q1
1916
- qn2 = q2
1917
-
1918
- if ( cosine < 0.0 )
1919
- cosine *= -1.0
1920
- qn1 *= -1.0
1921
- end
2950
+ def x=(value) @e[0] = value end
1922
2951
 
1923
- if ( (1.0 - cosine) > TOLERANCE )
1924
- theta = Math.acos( cosine )
1925
- sin_theta = Math.sin( theta )
2952
+ #
2953
+ # call-seq: y= value
2954
+ #
2955
+ # Stores +value+ as +y+.
2956
+ #
2957
+ def y=(value) @e[1] = value end
1926
2958
 
1927
- s1 = Math.sin( it * theta ) / sin_theta
1928
- s2 = Math.sin( t * theta ) / sin_theta
1929
- else
1930
- s1 = it
1931
- s2 = t
1932
- end
2959
+ #
2960
+ # call-seq: vec3[i] -> value
2961
+ #
2962
+ # Returns the element at +i+.
2963
+ #
2964
+ def [](i)
2965
+ @e[i]
2966
+ end
1933
2967
 
1934
- qn1 *= s1
1935
- qn2 *= s2
1936
- qResult = qn1 + qn2
2968
+ #
2969
+ # call-seq: x -> value
2970
+ #
2971
+ # Returns the value of +x+.
2972
+ #
2973
+ def x() return @e[0] end
1937
2974
 
1938
- return qResult
1939
- end
2975
+ #
2976
+ # call-seq: y -> value
2977
+ #
2978
+ # Returns the value of +y+.
2979
+ #
2980
+ def y() return @e[1] end
1940
2981
 
1941
2982
  #
1942
- # call-seq: setIdentity
2983
+ # call-seq: getLength
1943
2984
  #
1944
- # Sets as identity quaternion.
2985
+ # Returns the Euclidean length.
1945
2986
  #
1946
- def setIdentity
1947
- self.x = 0.0
1948
- self.y = 0.0
1949
- self.z = 0.0
1950
- self.w = 1.0
1951
- return self
2987
+ def getLength
2988
+ return Math.sqrt( @e[0]*@e[0] + @e[1]*@e[1] )
1952
2989
  end
1953
2990
 
1954
2991
  #
1955
- # call-seq: getConjugated
2992
+ # call-seq: getLengthSq
1956
2993
  #
1957
- # Returns its conjugate quaternion.
2994
+ # Returns the squared Euclidean length.
1958
2995
  #
1959
- def getConjugated
1960
- return RQuat.new( -@e[0], -@e[1], -@e[2], @e[3] )
2996
+ def getLengthSq
2997
+ return (@e[0]*@e[0] + @e[1]*@e[1]).to_f
1961
2998
  end
1962
2999
 
1963
3000
  #
1964
- # call-seq: conjugate!
3001
+ # call-seq: RVec2.dot(v_a,v_b) -> value
1965
3002
  #
1966
- # Conjugates itself.
3003
+ # Calculates the dot product of +v_a+ and +v_b+.
1967
3004
  #
1968
- def conjugate!
1969
- @e[0] *= -1.0
1970
- @e[1] *= -1.0
1971
- @e[2] *= -1.0
1972
- return self
3005
+ def RVec2.dot( v1, v2 )
3006
+ return v1.x*v2.x + v1.y*v2.y
1973
3007
  end
1974
3008
 
1975
3009
  #
1976
- # call-seq: getInverse -> inverse quaternion
3010
+ # call-seq: RVec2.cross(v_a,v_b) -> value
1977
3011
  #
1978
- # Returns the inverse.
3012
+ # Calculates the cross product of +v_a+ and +v_b+.
1979
3013
  #
1980
- def getInverse
1981
- length_sq = getLengthSq()
1982
- return RQuat.new( -@e[0]/length_sq, -@e[1]/length_sq, -@e[2]/length_sq, @e[3]/length_sq )
3014
+ def RVec2.cross( v1, v2 )
3015
+ return v1.x*v2.y - v1.y*v2.x
1983
3016
  end
1984
3017
 
1985
3018
  #
1986
- # call-seq: invert! -> self
3019
+ # call-seq: transform(mtx2) -> transformed RVec2
1987
3020
  #
1988
- # Inverts itself.
3021
+ # Returns new RVec2 containing the result of the transformation of
3022
+ # RVec2(self.x,self.y) by +mtx2+ (RMtx2).
1989
3023
  #
1990
- def invert!
1991
- length_sq = getLengthSq()
1992
- @e[0] /= -length_sq
1993
- @e[1] /= -length_sq
1994
- @e[2] /= -length_sq
1995
- @e[3] /= length_sq
1996
- return self
3024
+ def transform( mtx2 )
3025
+ result = RVec2.new
3026
+ result.x = mtx2.e00 * self[0] + mtx2.e01 * self[1]
3027
+ result.y = mtx2.e10 * self[0] + mtx2.e11 * self[1]
3028
+
3029
+ return result
1997
3030
  end
1998
3031
 
1999
3032
  #
2000
- # call-seq: getNormalized -> RQuat
3033
+ # call-seq: getNormalized -> RVec2
2001
3034
  #
2002
- # Returns normalized quaternion.
3035
+ # Returns normalized vector.
2003
3036
  #
2004
3037
  def getNormalized
2005
- length = getLength()
2006
- return RQuat.new( @e[0]/length, @e[1]/length, @e[2]/length, @e[3]/length )
3038
+ l = getLength()
3039
+ l = 1.0/l
3040
+ return RVec2.new( @e[0]*l, @e[1]*l )
2007
3041
  end
2008
3042
 
2009
3043
  #
@@ -2012,18 +3046,17 @@ module RMath3D
2012
3046
  # Normalizes itself.
2013
3047
  #
2014
3048
  def normalize!
2015
- length = getLength()
2016
- @e[0] /= length
2017
- @e[1] /= length
2018
- @e[2] /= length
2019
- @e[3] /= length
3049
+ l = getLength()
3050
+ l = 1.0/l
3051
+ @e[0] *= l
3052
+ @e[1] *= l
2020
3053
  return self
2021
3054
  end
2022
3055
 
2023
3056
  #
2024
3057
  # call-seq: +
2025
3058
  #
2026
- # +quat : Unary plus operator.
3059
+ # +vec : Unary plus operator.
2027
3060
  #
2028
3061
  def +@
2029
3062
  return self
@@ -2032,63 +3065,49 @@ module RMath3D
2032
3065
  #
2033
3066
  # call-seq: -
2034
3067
  #
2035
- # -quat : Unary minus operator.
3068
+ # -vec : Unary minus operator.
2036
3069
  #
2037
3070
  def -@
2038
- return RQuat.new( -@e[0], -@e[1], -@e[2], -@e[3] )
3071
+ return RVec2.new( -@e[0], -@e[1] )
2039
3072
  end
2040
3073
 
2041
3074
  #
2042
3075
  # call-seq: +
2043
3076
  #
2044
- # quat1 + quat2 : Binary plus operator.
3077
+ # vec1 + vec2 : Binary plus operator.
2045
3078
  #
2046
3079
  def +( arg )
2047
- if arg.class != RQuat
2048
- raise TypeError, "RQuat#+ : Unknown type #{arg.class}."
3080
+ if arg.class != RVec2
3081
+ raise TypeError, "RVec2#+ : Unknown type #{arg.class}."
2049
3082
  return nil
2050
3083
  end
2051
- RQuat.new( x+arg.x, y+arg.y, z+arg.z, w+arg.w )
3084
+ RVec2.new( x+arg.x, y+arg.y )
2052
3085
  end
2053
3086
 
2054
3087
  #
2055
3088
  # call-seq: -
2056
3089
  #
2057
- # quat1 - quat2 : Binary minus operator.
3090
+ # vec1 - vec2 : Binary minus operator.
2058
3091
  #
2059
3092
  def -( arg )
2060
- if arg.class != RQuat
2061
- raise TypeError, "RQuat#- : Unknown type #{arg.class}."
3093
+ if arg.class != RVec2
3094
+ raise TypeError, "RVec2#- : Unknown type #{arg.class}."
2062
3095
  return nil
2063
3096
  end
2064
- RQuat.new( x-arg.x, y-arg.y, z-arg.z, w-arg.w )
3097
+ RVec2.new( x-arg.x, y-arg.y )
2065
3098
  end
2066
3099
 
2067
3100
  #
2068
3101
  # call-seq: *
2069
3102
  #
2070
- # quat1 * quat2 : Binary multiply operator.
3103
+ # vec1 * vec2 : Binary multiply operator.
2071
3104
  #
2072
3105
  def *( arg )
2073
3106
  case arg
2074
- when RQuat
2075
- q1x = self.x
2076
- q1y = self.y
2077
- q1z = self.z
2078
- q1w = self.w
2079
- q2x = arg.x
2080
- q2y = arg.y
2081
- q2z = arg.z
2082
- q2w = arg.w
2083
- x = q1w*q2x + q1x*q2w + q1y*q2z - q1z*q2y
2084
- y = q1w*q2y - q1x*q2z + q1y*q2w + q1z*q2x
2085
- z = q1w*q2z + q1x*q2y - q1y*q2x + q1z*q2w
2086
- w = q1w*q2w - q1x*q2x - q1y*q2y - q1z*q2z
2087
- return RQuat.new( x, y, z, w )
2088
- when Fixnum, Float
2089
- return RQuat.new( @e[0]*arg, @e[1]*arg, @e[2]*arg, @e[3]*arg )
3107
+ when Float, Integer
3108
+ return RVec2.new( @e[0]*arg, @e[1]*arg )
2090
3109
  else
2091
- raise TypeError, "RQuat#* : Unknown type #{arg}."
3110
+ raise TypeError, "RVec2#* : Unknown type #{arg}."
2092
3111
  return nil
2093
3112
  end
2094
3113
  end
@@ -2096,183 +3115,71 @@ module RMath3D
2096
3115
  #
2097
3116
  # call-seq: ==
2098
3117
  #
2099
- # quat1 == quat2 : evaluates equality.
3118
+ # vec1 == vec2 : evaluates equality.
2100
3119
  #
2101
3120
  def ==( other )
2102
- if other.class != RQuat
2103
- raise TypeError, "RQuat#== : Unknown type #{other.class}."
2104
- return nil
2105
- end
2106
-
2107
- if (x-other.x).abs<=Float::EPSILON &&
2108
- (y-other.y).abs<=Float::EPSILON &&
2109
- (z-other.z).abs<=Float::EPSILON &&
2110
- (w-other.w).abs<=Float::EPSILON
2111
- return true
3121
+ if other.class == RVec2
3122
+ if (x-other.x).abs<=Float::EPSILON &&
3123
+ (y-other.y).abs<=Float::EPSILON
3124
+ return true
3125
+ else
3126
+ return false
3127
+ end
2112
3128
  else
2113
3129
  return false
2114
3130
  end
2115
3131
  end
2116
3132
 
2117
3133
  #
2118
- # call-seq: quat1.add!( quat2 )
3134
+ # call-seq: vec1.add!( vec2 )
2119
3135
  #
2120
- # quat1 += quat2 : appends the elements of +quat2+ into corresponding +quat1+ elements.
3136
+ # vec1 += vec2 : appends the elements of +vec2+ into corresponding +vec1+ elements.
2121
3137
  #
2122
3138
  def add!( other )
2123
- if other.class != RQuat
2124
- raise TypeError, "RQ#add! : Unknown type #{other.class}."
3139
+ if other.class != RVec2
3140
+ raise TypeError, "RVec2#add! : Unknown type #{other.class}."
2125
3141
  return nil
2126
3142
  end
2127
3143
 
2128
3144
  self.x += other.x
2129
3145
  self.y += other.y
2130
- self.z += other.z
2131
- self.w += other.w
2132
3146
 
2133
3147
  return self
2134
3148
  end
2135
3149
 
2136
3150
  #
2137
- # call-seq: quat1.sub!( quat2 )
3151
+ # call-seq: vec1.sub!( vec2 )
2138
3152
  #
2139
- # quat1 -= quat2 : subtracts the elements of +quat2+ from corresponding +quat1+ elements.
3153
+ # vec1 -= vec2 : subtracts the elements of +vec2+ from corresponding +vec1+ elements.
2140
3154
  #
2141
3155
  def sub!( other )
2142
- if other.class != RQuat
2143
- raise TypeError, "RQuat#sub! : Unknown type #{other.class}."
3156
+ if other.class != RVec2
3157
+ raise TypeError, "RVec2#sub! : Unknown type #{other.class}."
2144
3158
  return nil
2145
3159
  end
2146
3160
 
2147
3161
  self.x -= other.x
2148
3162
  self.y -= other.y
2149
- self.z -= other.z
2150
- self.w -= other.w
2151
-
2152
- return self
2153
- end
2154
-
2155
- #
2156
- # call-seq: quat1.mul!( quat2 )
2157
- #
2158
- # quat1 *= quat2
2159
- #
2160
- def mul!( other )
2161
- case other
2162
- when RQuat
2163
- q1x = self.x
2164
- q1y = self.y
2165
- q1z = self.z
2166
- q1w = self.w
2167
- q2x = other.x
2168
- q2y = other.y
2169
- q2z = other.z
2170
- q2w = other.w
2171
-
2172
- x = q1w*q2x + q1x*q2w + q1y*q2z - q1z*q2y
2173
- y = q1w*q2y - q1x*q2z + q1y*q2w + q1z*q2x
2174
- z = q1w*q2z + q1x*q2y - q1y*q2x + q1z*q2w
2175
- w = q1w*q2w - q1x*q2x - q1y*q2y - q1z*q2z
2176
-
2177
- self.x = x
2178
- self.y = y
2179
- self.z = z
2180
- self.w = w
2181
-
2182
- return self
2183
-
2184
- when Fixnum, Float
2185
- self.x *= other
2186
- self.y *= other
2187
- self.z *= other
2188
- self.w *= other
2189
- return self
2190
-
2191
- else
2192
- raise TypeError, "RQuat#mul! : Unknown type #{other.class}."
2193
- return nil
2194
- end
2195
- end
2196
-
2197
- #
2198
- # call-seq: rotationMarix(mtx4) -> self
2199
- #
2200
- # Makes a rotation quaternion from a rotation matrix +mtx4+ (RMtx4).
2201
- #
2202
- def rotationMatrix( mtx )
2203
- if mtx.class != RMtx3 && mtx.class != RMtx4
2204
- raise TypeError, "RQuat#rotationMatrix : Unknown type #{mtx.class}."
2205
- return nil
2206
- end
2207
-
2208
- diag00 = mtx.getElement(0,0)
2209
- diag11 = mtx.getElement(1,1)
2210
- diag22 = mtx.getElement(2,2)
2211
-
2212
- if ( diag00 + diag11 + diag22 > 0.0 )
2213
- t = diag00 + diag11 + diag22 + 1.0
2214
- s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2215
- self.w = s * t
2216
- self.z = (mtx.getElement(1,0) - mtx.getElement(0,1)) * s
2217
- self.y = (mtx.getElement(0,2) - mtx.getElement(2,0)) * s
2218
- self.x = (mtx.getElement(2,1) - mtx.getElement(1,2)) * s
2219
- elsif ( diag00 > diag11 && diag00 > diag22 )
2220
- t = diag00 - diag11 - diag22 + 1.0
2221
- s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2222
- self.x = s * t
2223
- self.y = (mtx.getElement(1,0) + mtx.getElement(0,1)) * s
2224
- self.z = (mtx.getElement(0,2) + mtx.getElement(2,0)) * s
2225
- self.w = (mtx.getElement(2,1) - mtx.getElement(1,2)) * s
2226
- elsif ( diag11 > diag22 )
2227
- t = -diag00 + diag11 - diag22 + 1.0
2228
- s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2229
- self.y = s * t
2230
- self.x = (mtx.getElement(1,0) + mtx.getElement(0,1)) * s
2231
- self.w = (mtx.getElement(0,2) - mtx.getElement(2,0)) * s
2232
- self.z = (mtx.getElement(2,1) + mtx.getElement(1,2)) * s
2233
- else
2234
- t = -diag00 - diag11 + diag22 + 1.0
2235
- s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2236
- self.z = s * t
2237
- self.w = (mtx.getElement(1,0) - mtx.getElement(0,1)) * s
2238
- self.x = (mtx.getElement(0,2) + mtx.getElement(2,0)) * s
2239
- self.y = (mtx.getElement(2,1) + mtx.getElement(1,2)) * s
2240
- end
2241
3163
 
2242
3164
  return self
2243
3165
  end
2244
3166
 
2245
3167
  #
2246
- # call-seq: rotationAxis(axis,radian) -> self
3168
+ # call-seq: vec1.mul!( vec2 )
2247
3169
  #
2248
- # Makes a quaternion that rotates around the +axis+.
3170
+ # vec1 *= vec2
2249
3171
  #
2250
- def rotationAxis( axis, radian )
2251
- if axis.class != RVec3
2252
- raise TypeError, "RQuat#rotationAxis : Unknown type #{axis.class}."
3172
+ def mul!( arg )
3173
+ if !(arg.class == Float || arg.class == Integer)
3174
+ raise TypeError, "RVec2#mul! : Unknown type #{arg.class}."
2253
3175
  return nil
2254
3176
  end
2255
3177
 
2256
- s = Math.sin( radian / 2.0 )
2257
- self.x = s * axis.x
2258
- self.y = s * axis.y
2259
- self.z = s * axis.z
2260
- self.w = Math.cos( radian / 2.0 )
3178
+ self.x *= arg
3179
+ self.y *= arg
2261
3180
 
2262
3181
  return self
2263
3182
  end
2264
-
2265
- #
2266
- # call-seq: toAxisAngle -> [axis,radian]
2267
- #
2268
- # Returns its rotation axis (RVec3) and rotation angle (in radian).
2269
- #
2270
- def toAxisAngle
2271
- axis = RVec3.new( self.x, self.y, self.z ).normalize!
2272
- radian = 2.0 * Math.acos( self.w )
2273
-
2274
- return [ axis, radian ]
2275
- end
2276
3183
  end
2277
3184
 
2278
3185
  #
@@ -2297,7 +3204,7 @@ module RMath3D
2297
3204
  @e = [0.0, 0.0, 0.0]
2298
3205
  when 1
2299
3206
  case a[0]
2300
- when Fixnum, Float
3207
+ when Float, Integer
2301
3208
  @e = [ a[0], a[0], a[0] ]
2302
3209
  when RVec3
2303
3210
  @e = [ a[0].x, a[0].y, a[0].z ]
@@ -2308,7 +3215,7 @@ module RMath3D
2308
3215
  when 3
2309
3216
  a.each_with_index do |elem, index|
2310
3217
  case elem
2311
- when Fixnum, Float
3218
+ when Float, Integer
2312
3219
  @e[index] = elem
2313
3220
  else
2314
3221
  raise TypeError, "RVec3#initialize : Unknown type #{elem.class}."
@@ -2328,7 +3235,7 @@ module RMath3D
2328
3235
  # Returns human-readable string.
2329
3236
  #
2330
3237
  def to_s
2331
- return "( #{@e[0]}, #{@e[1]}, #{@e[2]} )\n"
3238
+ return "( #{@e[0]}, #{@e[1]}, #{@e[2]} )"
2332
3239
  end
2333
3240
 
2334
3241
  #
@@ -2347,7 +3254,7 @@ module RMath3D
2347
3254
  #
2348
3255
  def coerce( arg )
2349
3256
  case arg
2350
- when Fixnum, Float, Bignum
3257
+ when Float, Integer
2351
3258
  return [ self, arg ]
2352
3259
  else
2353
3260
  raise TypeError, "RVec3#coerce : #{arg.self} can't be coerced into #{self.class}."
@@ -2651,9 +3558,9 @@ module RMath3D
2651
3558
  t_z = q.w*self[2] + q.x*self[1] - q.y*self[0]
2652
3559
  t_w = - q.x*self[0] - q.y*self[1] - q.z*self[2]
2653
3560
 
2654
- result.x = -t_w*q.x + t_x*q.w - t_y*q.z + t_z*q.y;
2655
- result.y = -t_w*q.y + t_x*q.z + t_y*q.w - t_z*q.x;
2656
- result.z = -t_w*q.z - t_x*q.y + t_y*q.x + t_z*q.w;
3561
+ result.x = -t_w*q.x + t_x*q.w - t_y*q.z + t_z*q.y
3562
+ result.y = -t_w*q.y + t_x*q.z + t_y*q.w - t_z*q.x
3563
+ result.z = -t_w*q.z - t_x*q.y + t_y*q.x + t_z*q.w
2657
3564
 
2658
3565
  return result
2659
3566
  end
@@ -2667,9 +3574,9 @@ module RMath3D
2667
3574
  t_z = q.w*self[2] + q.x*self[1] - q.y*self[0]
2668
3575
  t_w = - q.x*self[0] - q.y*self[1] - q.z*self[2]
2669
3576
 
2670
- self.x = -t_w*q.x + t_x*q.w - t_y*q.z + t_z*q.y;
2671
- self.y = -t_w*q.y + t_x*q.z + t_y*q.w - t_z*q.x;
2672
- self.z = -t_w*q.z - t_x*q.y + t_y*q.x + t_z*q.w;
3577
+ self.x = -t_w*q.x + t_x*q.w - t_y*q.z + t_z*q.y
3578
+ self.y = -t_w*q.y + t_x*q.z + t_y*q.w - t_z*q.x
3579
+ self.z = -t_w*q.z - t_x*q.y + t_y*q.x + t_z*q.w
2673
3580
 
2674
3581
  return self
2675
3582
  end
@@ -2750,7 +3657,7 @@ module RMath3D
2750
3657
  #
2751
3658
  def *( arg )
2752
3659
  case arg
2753
- when Fixnum, Float
3660
+ when Float, Integer
2754
3661
  return RVec3.new( @e[0]*arg, @e[1]*arg, @e[2]*arg )
2755
3662
  else
2756
3663
  raise TypeError, "RVec3#* : Unknown type #{arg}."
@@ -2764,15 +3671,14 @@ module RMath3D
2764
3671
  # vec1 == vec2 : evaluates equality.
2765
3672
  #
2766
3673
  def ==( other )
2767
- if other.class != RVec3
2768
- raise TypeError, "RVec3#== : Unknown type #{other.class}."
2769
- return nil
2770
- end
2771
-
2772
- if (x-other.x).abs<=Float::EPSILON &&
2773
- (y-other.y).abs<=Float::EPSILON &&
2774
- (z-other.z).abs<=Float::EPSILON
2775
- return true
3674
+ if other.class == RVec3
3675
+ if (x-other.x).abs<=Float::EPSILON &&
3676
+ (y-other.y).abs<=Float::EPSILON &&
3677
+ (z-other.z).abs<=Float::EPSILON
3678
+ return true
3679
+ else
3680
+ return false
3681
+ end
2776
3682
  else
2777
3683
  return false
2778
3684
  end
@@ -2820,7 +3726,7 @@ module RMath3D
2820
3726
  # vec1 *= vec2
2821
3727
  #
2822
3728
  def mul!( arg )
2823
- if arg.class != Fixnum && arg.class != Float
3729
+ if !(arg.class == Float || arg.class == Integer)
2824
3730
  raise TypeError, "RVec3#mul! : Unknown type #{arg.class}."
2825
3731
  return nil
2826
3732
  end
@@ -2855,7 +3761,7 @@ module RMath3D
2855
3761
  @e = [0.0, 0.0, 0.0, 0.0]
2856
3762
  when 1
2857
3763
  case a[0]
2858
- when Fixnum, Float
3764
+ when Float, Integer
2859
3765
  @e = [ a[0], a[0], a[0], a[0] ]
2860
3766
  when RVec3
2861
3767
  @e = [ a[0].x, a[0].y, a[0].z, 0.0 ]
@@ -2868,7 +3774,7 @@ module RMath3D
2868
3774
  when 4
2869
3775
  a.each_with_index do |elem, index|
2870
3776
  case elem
2871
- when Fixnum, Float
3777
+ when Float, Integer
2872
3778
  @e[index] = elem
2873
3779
  else
2874
3780
  raise TypeError, "RVec4#initialize : Unknown type #{elem.class}."
@@ -2888,7 +3794,7 @@ module RMath3D
2888
3794
  # Returns human-readable string.
2889
3795
  #
2890
3796
  def to_s
2891
- return "( #{@e[0]}, #{@e[1]}, #{@e[2]}, #{@e[3]} )\n"
3797
+ return "( #{@e[0]}, #{@e[1]}, #{@e[2]}, #{@e[3]} )"
2892
3798
  end
2893
3799
 
2894
3800
  #
@@ -2907,7 +3813,7 @@ module RMath3D
2907
3813
  #
2908
3814
  def coerce( arg )
2909
3815
  case arg
2910
- when Fixnum, Float, Bignum
3816
+ when Float, Integer
2911
3817
  return [ self, arg ]
2912
3818
  else
2913
3819
  raise TypeError, "RVec4#coerce : #{arg.self} can't be coerced into #{self.class}."
@@ -3197,7 +4103,7 @@ module RMath3D
3197
4103
  #
3198
4104
  def *( arg )
3199
4105
  case arg
3200
- when Fixnum, Float
4106
+ when Float, Integer
3201
4107
  return RVec4.new( @e[0]*arg, @e[1]*arg, @e[2]*arg, @e[3]*arg )
3202
4108
  else
3203
4109
  raise TypeError, "RVec4#* : Unknown type #{arg}."
@@ -3211,16 +4117,15 @@ module RMath3D
3211
4117
  # vec1 == vec2 : evaluates equality.
3212
4118
  #
3213
4119
  def ==( other )
3214
- if other.class != RVec4
3215
- raise TypeError, "RVec4#== : Unknown type #{other.class}."
3216
- return nil
3217
- end
3218
-
3219
- if (x-other.x).abs<=Float::EPSILON &&
3220
- (y-other.y).abs<=Float::EPSILON &&
3221
- (z-other.z).abs<=Float::EPSILON &&
3222
- (w-other.w).abs<=Float::EPSILON
3223
- return true
4120
+ if other.class == RVec4
4121
+ if (x-other.x).abs<=Float::EPSILON &&
4122
+ (y-other.y).abs<=Float::EPSILON &&
4123
+ (z-other.z).abs<=Float::EPSILON &&
4124
+ (w-other.w).abs<=Float::EPSILON
4125
+ return true
4126
+ else
4127
+ return false
4128
+ end
3224
4129
  else
3225
4130
  return false
3226
4131
  end
@@ -3270,7 +4175,7 @@ module RMath3D
3270
4175
  # vec1 *= vec2
3271
4176
  #
3272
4177
  def mul!( other )
3273
- if other.class != Fixnum && other.class != Float
4178
+ if !(other.class == Float || other.class == Integer)
3274
4179
  raise TypeError, "RVec4#mul! : Unknown type #{other.class}."
3275
4180
  return nil
3276
4181
  end
@@ -3288,7 +4193,7 @@ end
3288
4193
 
3289
4194
  =begin
3290
4195
  RMath : Ruby math module for 3D Applications
3291
- Copyright (c) 2008- vaiorabbit <http://twitter.com/vaiorabbit>
4196
+ Copyright (c) 2008-2020 vaiorabbit <http://twitter.com/vaiorabbit>
3292
4197
 
3293
4198
  This software is provided 'as-is', without any express or implied
3294
4199
  warranty. In no event will the authors be held liable for any damages