rmath3d_plain 1.0.2 → 1.1.0

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
2
  SHA1:
3
- metadata.gz: 3625f1baf42745a3e10bcba93e504b9c83764180
4
- data.tar.gz: e1f7590e0aa500ab797a31434cd1b3a397e2840f
3
+ metadata.gz: 5b2a5f2fa521f8b303ef746634b8574967b7b703
4
+ data.tar.gz: ecfe68cac549e516052ea77ddd885051fd36fc81
5
5
  SHA512:
6
- metadata.gz: aba8c4dae29be93bf0beb77cc11c4a401db89fdf8e7b608d41dff379bbec96c6702c14669c23933e24df05c5d79d0500e322659f6c12a8a5818c72a09646a0c9
7
- data.tar.gz: 2b9c55755c9aa514735e63129df3d37b6486b3b83746b549ddae0a3c87e9bb0cc77ce140632b115dbf750c8aeb68535ae500106b27d9fb4fa581f9aeadcfcc69
6
+ metadata.gz: 1bda4cabbc91bc183b5881f5c51c0716c3fb8b0f1b3562eb8843e47c3bd3f774c69de6111c4f7412103e81b2258b3476cd7f1b974c6aaa9abbc8b05c3d447750
7
+ data.tar.gz: a58f95113e0d9e3bef1488fdf26d79c2069f3fb0654eeeaec0bd6741ceb43941ec2af3e8cd7c016d3524d5adcda99933da38e1c4496cfb7f1c1335aea23ef245
data/ChangeLog CHANGED
@@ -1,3 +1,7 @@
1
+ 2015-04-12 vaiorabbit <http://twitter.com/vaiorabbit>
2
+
3
+ * RVec2.c|h, RMtx2.c|h: Added.
4
+
1
5
  2014-05-17 vaiorabbit <http://twitter.com/vaiorabbit>
2
6
 
3
7
  * ext/rmath3d/rmath3d.c: Fixed memory management
data/LICENSE.txt CHANGED
@@ -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-2015 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,20 @@
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: Apr 12, 2015
8
8
  * Since: Jul 20, 2008
9
9
 
10
10
  ## Features ##
11
11
 
12
12
  ### Supports frequently-used vector and matrix classes ###
13
13
 
14
+ * RMtx2 (2x2 matrix)
14
15
  * RMtx3 (3x3 matrix)
15
16
  * RMtx4 (4x4 matrix)
16
17
  * RQuat (Quaternion)
17
- * RVec3 (3 element vector)
18
- * RVec4 (4 element vector)
18
+ * RVec2 (2-element vector)
19
+ * RVec3 (3-element vector)
20
+ * RVec4 (4-element vector)
19
21
 
20
22
  ### Two implementations that are interchangeable with each other ###
21
23
 
@@ -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
32
  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
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
49
  when Fixnum, Float
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
  #
@@ -95,25 +91,25 @@ module RMath3D
95
91
  when Fixnum, Float, Bignum
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
@@ -569,16 +412,15 @@ module RMath3D
569
412
  def *( arg )
570
413
  case arg
571
414
  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 )
415
+ return RMtx2.new( arg*self.e00, arg*self.e01,
416
+ arg*self.e10, arg*self.e11 )
575
417
 
576
- when RMtx3
577
- result = RMtx3.new
578
- for row in 0...3 do
579
- for col in 0...3 do
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,13 +440,13 @@ 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."
443
+ if ( other.class != RMtx2 )
444
+ raise TypeError, "RMtx2#==(other) : Unknown type #{other.class} given as RMtx2."
603
445
  return nil
604
446
  end
605
447
 
606
- for row in 0...3 do
607
- for col in 0...3 do
448
+ for row in 0...2 do
449
+ for col in 0...2 do
608
450
  if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
609
451
  return false
610
452
  end
@@ -619,14 +461,14 @@ module RMath3D
619
461
  # mtx1 += mtx2 : appends the elements of +mtx2+ into corresponding +mtx1+ elements.
620
462
  #
621
463
  def add!( other )
622
- if ( other.class != RMtx3 )
623
- raise TypeError, "RMtx3#add! : Unknown type #{other.class} given as RMtx3."
464
+ if ( other.class != RMtx2 )
465
+ raise TypeError, "RMtx2#add! : Unknown type #{other.class} given as RMtx2."
624
466
  return nil
625
467
  end
626
468
 
627
- result = RMtx3.new
628
- for row in 0...3 do
629
- for col in 0...3 do
469
+ result = RMtx2.new
470
+ for row in 0...2 do
471
+ for col in 0...2 do
630
472
  self.setElement( row, col, getElement(row,col) + other.getElement(row,col) )
631
473
  end
632
474
  end
@@ -640,14 +482,14 @@ module RMath3D
640
482
  # mtx1 -= mtx2 : subtracts the elements of +mtx2+ from corresponding +mtx1+ elements.
641
483
  #
642
484
  def sub!( other )
643
- if ( other.class != RMtx3 )
644
- raise TypeError, "RMtx3#sub! : Unknown type #{other.class} given as RMtx3."
485
+ if ( other.class != RMtx2 )
486
+ raise TypeError, "RMtx2#sub! : Unknown type #{other.class} given as RMtx2."
645
487
  return nil
646
488
  end
647
489
 
648
- result = RMtx3.new
649
- for row in 0...3 do
650
- for col in 0...3 do
490
+ result = RMtx2.new
491
+ for row in 0...2 do
492
+ for col in 0...2 do
651
493
  self.setElement( row, col, getElement(row,col) - other.getElement(row,col) )
652
494
  end
653
495
  end
@@ -665,21 +507,16 @@ module RMath3D
665
507
  when Fixnum, Float, Bignum
666
508
  self.e00 = other*self.e00
667
509
  self.e01 = other*self.e01
668
- self.e02 = other*self.e02
669
510
  self.e10 = other*self.e10
670
511
  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
512
 
676
513
  return self
677
- when RMtx3
678
- result = RMtx3.new
679
- for row in 0...3 do
680
- for col in 0...3 do
514
+ when RMtx2
515
+ result = RMtx2.new
516
+ for row in 0...2 do
517
+ for col in 0...2 do
681
518
  sum = 0.0
682
- for i in 0...3 do
519
+ for i in 0...2 do
683
520
  sum += getElement( row, i ) * other.getElement( i, col )
684
521
  end
685
522
  result.setElement( row, col, sum )
@@ -688,13 +525,8 @@ module RMath3D
688
525
 
689
526
  self.e00 = result.e00
690
527
  self.e01 = result.e01
691
- self.e02 = result.e02
692
528
  self.e10 = result.e10
693
529
  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
530
 
699
531
  return self
700
532
  end
@@ -702,65 +534,62 @@ module RMath3D
702
534
  end
703
535
 
704
536
  #
705
- # Document-class: RMath3D::RMtx4
706
- # provies 4x4 matrix arithmetic.
537
+ # Document-class: RMath3D::RMtx3
538
+ # provies 3x3 matrix arithmetic.
707
539
  #
708
540
  # <b>Notice</b>
709
541
  # * elements are stored in column-major order.
710
542
  #
711
- class RMtx4
543
+ class RMtx3
712
544
 
713
545
  #
714
546
  # 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))
547
+ # RMtx3.new -> ((1,0,0),(0,1,0),(0,0,1))
548
+ # RMtx3.new(e) -> ((e,e,e), (e,e,e), (e,e,e))
549
+ # RMtx3.new( other ) : Copy Constructor
550
+ # RMtx3.new( e0, e1, ..., e8 ) -> ((e0,e1,e2), (e3,e4,e5), (e6,e7,e8))
719
551
  #
720
- # Creates a new 4x4 matrix.
552
+ # Creates a new 3x3 matrix.
721
553
  #
722
554
  def initialize( *a )
723
555
  # [NOTE] elemetns are stored in column-major order.
724
556
  @e = []
725
557
  case a.length
726
558
  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 ]
559
+ @e = [ 0.0, 0.0, 0.0,
560
+ 0.0, 0.0, 0.0,
561
+ 0.0, 0.0, 0.0 ]
731
562
  when 1
732
563
  case a[0]
733
564
  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
565
+ @e = [ a[0], a[0], a[0],
566
+ a[0], a[0], a[0],
567
+ a[0], a[0], a[0] ]
568
+ when RMtx3
739
569
  # 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 ]
570
+ @e = [ a[0].e00, a[0].e10, a[0].e20,
571
+ a[0].e01, a[0].e11, a[0].e21,
572
+ a[0].e02, a[0].e12, a[0].e22 ]
744
573
  else
745
- raise TypeError, "RMtx4#initialize : Unknown type #{a[0].class}."
574
+ raise TypeError, "RMtx3#initialize : Unknown type #{a[0].class}."
746
575
  return nil
747
576
  end
748
- when 16
577
+ when 9
749
578
  # Element-wise setter
750
- for row in 0...4 do
751
- for col in 0...4 do
752
- index = 4*row + col
579
+ for row in 0...3 do
580
+ for col in 0...3 do
581
+ index = 3*row + col
753
582
  case a[index]
754
583
  when Fixnum, Float
755
584
  setElement( row, col, a[index] )
756
585
  else
757
- raise TypeError, "RMtx4#initialize : Unknown type #{a[0].class}."
586
+ raise TypeError, "RMtx3#initialize : Unknown type #{a[0].class}."
758
587
  return nil
759
588
  end
760
589
  end
761
590
  end
762
591
  else
763
- raise RuntimeError, "RMtx4#initialize : wrong # of arguments (#{a.length})"
592
+ raise RuntimeError, "RMtx3#initialize : wrong # of arguments (#{a.length})"
764
593
  return nil
765
594
  end
766
595
 
@@ -773,10 +602,9 @@ module RMath3D
773
602
  # Returns human-readable string.
774
603
  #
775
604
  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"
605
+ "( #{@e[0]}, #{@e[3]}, #{@e[6]} )\n" +
606
+ "( #{@e[1]}, #{@e[4]}, #{@e[7]} )\n" +
607
+ "( #{@e[2]}, #{@e[5]}, #{@e[8]} )\n"
780
608
  end
781
609
 
782
610
  #
@@ -798,25 +626,25 @@ module RMath3D
798
626
  when Fixnum, Float, Bignum
799
627
  return [ self, arg ]
800
628
  else
801
- raise TypeError, "RMtx4#coerce : #{arg.self} can't be coerced into #{self.class}."
629
+ raise TypeError, "RMtx3#coerce : #{arg.self} can't be coerced into #{self.class}."
802
630
  return nil
803
631
  end
804
632
  end
805
633
 
806
634
  #
807
- # call-seq: setElements( e0, e1, ..., e15 )
635
+ # call-seq: setElements( e0, e1, ..., e8 )
808
636
  #
809
- # Stores given 16 new values.
637
+ # Stores given 9 new values.
810
638
  #
811
639
  def setElements( *a )
812
- if a.length != 16
813
- raise RuntimeError, "RMtx4#setElements : wrong # of arguments (#{a.length})"
640
+ if a.length != 9
641
+ raise RuntimeError, "RMtx3#setElements : wrong # of arguments (#{a.length})"
814
642
  return nil
815
643
  end
816
644
 
817
- for row in 0...4 do
818
- for col in 0...4 do
819
- index = 4*row + col
645
+ for row in 0...3 do
646
+ for col in 0...3 do
647
+ index = 3*row + col
820
648
  setElement( row, col, a[index] )
821
649
  end
822
650
  end
@@ -829,7 +657,7 @@ module RMath3D
829
657
  #
830
658
  def []=(row,col,value)
831
659
  # [NOTE] elemetns are stored in column-major order.
832
- @e[col*4+row] = value
660
+ @e[col*3+row] = value
833
661
  end
834
662
  alias_method :setElement, :'[]='
835
663
 
@@ -840,7 +668,7 @@ module RMath3D
840
668
  #
841
669
  def [](row,col)
842
670
  # [NOTE] elemetns are stored in column-major order.
843
- return @e[col*4+row]
671
+ return @e[col*3+row]
844
672
  end
845
673
  alias_method :getElement, :'[]'
846
674
 
@@ -850,32 +678,18 @@ module RMath3D
850
678
  def e01() getElement(0,1) end
851
679
  # Returns the element at row 0 and column 2.
852
680
  def e02() getElement(0,2) end
853
- # Returns the element at row 0 and column 3.
854
- def e03() getElement(0,3) end
855
681
  # Returns the element at row 1 and column 0.
856
682
  def e10() getElement(1,0) end
857
683
  # Returns the element at row 1 and column 1.
858
684
  def e11() getElement(1,1) end
859
685
  # Returns the element at row 1 and column 2.
860
686
  def e12() getElement(1,2) end
861
- # Returns the element at row 1 and column 3.
862
- def e13() getElement(1,3) end
863
687
  # Returns the element at row 2 and column 0.
864
688
  def e20() getElement(2,0) end
865
689
  # Returns the element at row 2 and column 1.
866
690
  def e21() getElement(2,1) end
867
691
  # Returns the element at row 2 and column 2.
868
692
  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
693
 
880
694
  # Replaces the element at row 0 and column 0 by +value+.
881
695
  def e00=(value) setElement(0,0,value) end
@@ -883,53 +697,40 @@ module RMath3D
883
697
  def e01=(value) setElement(0,1,value) end
884
698
  # Replaces the element at row 0 and column 2 by +value+.
885
699
  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
700
  # Replaces the element at row 1 and column 0 by +value+.
889
701
  def e10=(value) setElement(1,0,value) end
890
702
  # Replaces the element at row 1 and column 1 by +value+.
891
703
  def e11=(value) setElement(1,1,value) end
892
704
  # Replaces the element at row 1 and column 2 by +value+.
893
705
  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
706
  # Replaces the element at row 2 and column 0 by +value+.
897
707
  def e20=(value) setElement(2,0,value) end
898
708
  # Replaces the element at row 2 and column 1 by +value+.
899
709
  def e21=(value) setElement(2,1,value) end
900
710
  # Replaces the element at row 2 and column 2 by +value+.
901
711
  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
712
+
912
713
 
913
714
  #
914
- # call-seq: mtx4.getRow(r) -> RVec4
715
+ # call-seq: mtx3.getRow(r) -> RVec3
915
716
  #
916
717
  # Returns +r+-th row vector.
917
718
  #
918
719
  def getRow( row )
919
- return RVec4.new( self[row,0], self[row,1], self[row,2], self[row,3] )
720
+ return RVec3.new( self[row,0], self[row,1], self[row,2] )
920
721
  end
921
722
 
922
723
  #
923
- # call-seq: mtx4.getColumn(c) -> RVec4
724
+ # call-seq: mtx3.getColumn(c) -> RVec3
924
725
  #
925
726
  # Returns +c+-th column vector.
926
727
  #
927
728
  def getColumn( column )
928
- return RVec4.new( self[0,column], self[1,column], self[2,column], self[3,column] )
729
+ return RVec3.new( self[0,column], self[1,column], self[2,column] )
929
730
  end
930
731
 
931
732
  #
932
- # call-seq: mtx4.setRow(v,r)
733
+ # call-seq: mtx3.setRow(v,r)
933
734
  #
934
735
  # Returns sets +r+-th row by vector +v+.
935
736
  #
@@ -937,11 +738,10 @@ module RMath3D
937
738
  self[row,0] = v.x
938
739
  self[row,1] = v.y
939
740
  self[row,2] = v.z
940
- self[row,3] = v.w
941
741
  end
942
742
 
943
743
  #
944
- # call-seq: mtx4.setColumn(v,c)
744
+ # call-seq: mtx3.setColumn(v,c)
945
745
  #
946
746
  # Returns sets +c+-th column by vector +v+.
947
747
  #
@@ -949,35 +749,15 @@ module RMath3D
949
749
  self[0,column] = v.x
950
750
  self[1,column] = v.y
951
751
  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
752
  end
974
753
 
754
+ #
975
755
  # call-seq: setZero
976
756
  #
977
757
  # Clears all elements by 0.0
978
758
  #
979
759
  def setZero
980
- 16.times do |i|
760
+ 9.times do |i|
981
761
  @e[i] = 0.0
982
762
  end
983
763
  return self
@@ -989,9 +769,9 @@ module RMath3D
989
769
  # Sets as identity matrix.
990
770
  #
991
771
  def setIdentity
992
- for row in 0...4 do
993
- for col in 0...4 do
994
- index = 4*row + col
772
+ for row in 0...3 do
773
+ for col in 0...3 do
774
+ index = 3*row + col
995
775
  if ( row == col )
996
776
  setElement( row, col, 1.0 )
997
777
  else
@@ -1002,23 +782,15 @@ module RMath3D
1002
782
  return self
1003
783
  end
1004
784
 
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
785
  #
1013
786
  # call-seq: getDeterminant -> determinant
1014
787
  #
1015
788
  # Calculates determinant.
1016
789
  #
1017
790
  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 )
791
+ e00 * (e11*e22 - e12*e21) -
792
+ e01 * (e10*e22 - e12*e20) +
793
+ e02 * (e10*e21 - e11*e20)
1022
794
  end
1023
795
 
1024
796
  #
@@ -1027,10 +799,9 @@ module RMath3D
1027
799
  # Returns transposed matrix.
1028
800
  #
1029
801
  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] )
802
+ return RMtx3.new( @e[0], @e[1], @e[2],
803
+ @e[3], @e[4], @e[5],
804
+ @e[6], @e[7], @e[8] )
1034
805
  end
1035
806
 
1036
807
  #
@@ -1039,12 +810,9 @@ module RMath3D
1039
810
  # Transposeas its elements.
1040
811
  #
1041
812
  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]
813
+ @e[1], @e[3] = @e[3], @e[1]
814
+ @e[2], @e[6] = @e[6], @e[2]
815
+ @e[5], @e[7] = @e[7], @e[5]
1048
816
  end
1049
817
 
1050
818
  #
@@ -1053,32 +821,24 @@ module RMath3D
1053
821
  # Returns the inverse.
1054
822
  #
1055
823
  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 )
824
+ result = RMtx3.new
1062
825
 
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 )
826
+ result.e00 = (self.e11*self.e22 - self.e12*self.e21)
827
+ result.e01 = -(self.e01*self.e22 - self.e02*self.e21)
828
+ result.e02 = (self.e01*self.e12 - self.e02*self.e11)
1067
829
 
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 )
830
+ result.e10 = -(self.e10*self.e22 - self.e12*self.e20)
831
+ result.e11 = (self.e00*self.e22 - self.e02*self.e20)
832
+ result.e12 = -(self.e00*self.e12 - self.e02*self.e10)
1072
833
 
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 )
834
+ result.e20 = (self.e10*self.e21 - self.e11*self.e20)
835
+ result.e21 = -(self.e00*self.e21 - self.e01*self.e20)
836
+ result.e22 = (self.e00*self.e11 - self.e01*self.e10)
1077
837
 
1078
- det = e00 * result.e00 + e01 * result.e10 + e02 * result.e20 + e03 * result.e30
838
+ det = e00 * result.e00 + e01 * result.e10 + e02 * result.e20
1079
839
 
1080
840
  if ( det.abs < TOLERANCE )
1081
- raise RuntimeError, "RMtx4#getInverse : det.abs < TOLERANCE"
841
+ raise RuntimeError, "RMtx3#getInverse : det.abs < TOLERANCE"
1082
842
  return nil
1083
843
  end
1084
844
 
@@ -1095,70 +855,38 @@ module RMath3D
1095
855
  # Makes itself as the inverse of the original matrix.
1096
856
  #
1097
857
  def invert!
1098
- elements = Array.new( 16 )
858
+ elements = Array.new( 9 )
1099
859
 
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 )
860
+ elements[3*0+0] = (self.e11*self.e22 - self.e12*self.e21)
861
+ elements[3*0+1] = -(self.e01*self.e22 - self.e02*self.e21)
862
+ elements[3*0+2] = (self.e01*self.e12 - self.e02*self.e11)
1104
863
 
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 )
1109
-
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 )
864
+ elements[3*1+0] = -(self.e10*self.e22 - self.e12*self.e20)
865
+ elements[3*1+1] = (self.e00*self.e22 - self.e02*self.e20)
866
+ elements[3*1+2] = -(self.e00*self.e12 - self.e02*self.e10)
1114
867
 
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 )
868
+ elements[3*2+0] = (self.e10*self.e21 - self.e11*self.e20)
869
+ elements[3*2+1] = -(self.e00*self.e21 - self.e01*self.e20)
870
+ elements[3*2+2] = (self.e00*self.e11 - self.e01*self.e10)
1119
871
 
1120
- det = e00 * elements[4*0+0] + e01 * elements[4*1+0] + e02 * elements[4*2+0] + e03 * elements[4*3+0]
872
+ det = e00 * elements[3*0+0] + e01 * elements[3*1+0] + e02 * elements[3*2+0]
1121
873
 
1122
- if ( det.abs< TOLERANCE )
1123
- raise RuntimeError, "RMtx4invert! : det.abs < TOLERANCE"
874
+ if ( det.abs < TOLERANCE )
875
+ raise RuntimeError, "RMtx3#invert! : det.abs < TOLERANCE"
1124
876
  return nil
1125
877
  end
1126
878
 
1127
879
  d = 1.0 / det
1128
880
 
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
881
+ setElement( 0, 0, d * elements[3*0+0] )
882
+ setElement( 0, 1, d * elements[3*0+1] )
883
+ setElement( 0, 2, d * elements[3*0+2] )
884
+ setElement( 1, 0, d * elements[3*1+0] )
885
+ setElement( 1, 1, d * elements[3*1+1] )
886
+ setElement( 1, 2, d * elements[3*1+2] )
887
+ setElement( 2, 0, d * elements[3*2+0] )
888
+ setElement( 2, 1, d * elements[3*2+1] )
889
+ setElement( 2, 2, d * elements[3*2+2] )
1162
890
 
1163
891
  return self
1164
892
  end
@@ -1224,7 +952,7 @@ module RMath3D
1224
952
  #
1225
953
  def rotationAxis( axis, radian )
1226
954
  if ( axis.class != RVec3 )
1227
- raise TypeError, "RMtx4#rotationAxis : Unknown type #{axis.class} given as axis."
955
+ raise TypeError, "RMtx3#rotationAxis : Unknown type #{axis.class} given as axis."
1228
956
  return nil
1229
957
  end
1230
958
  s = Math.sin( radian )
@@ -1234,8 +962,6 @@ module RMath3D
1234
962
  y = axis.y.to_f
1235
963
  z = axis.z.to_f
1236
964
 
1237
- setIdentity()
1238
-
1239
965
  self.e00 = x*x*omc + c
1240
966
  self.e01 = x*y*omc - z*s
1241
967
  self.e02 = z*x*omc + y*s
@@ -1256,7 +982,7 @@ module RMath3D
1256
982
  #
1257
983
  def rotationQuaternion( q )
1258
984
  if ( q.class != RQuat )
1259
- raise TypeError, "RMtx4#rotationQuaternion : Unknown type #{q.class} given as RQuat."
985
+ raise TypeError, "RMtx3#rotationQuaternion : Unknown type #{q.class} given as RQuat."
1260
986
  return nil
1261
987
  end
1262
988
  x = q.x
@@ -1279,8 +1005,6 @@ module RMath3D
1279
1005
  xz2 = x * z2
1280
1006
  wy2 = w * y2
1281
1007
 
1282
- setIdentity()
1283
-
1284
1008
  self.e00 = 1.0 - yy2 - zz2
1285
1009
  self.e10 = xy2 + wz2
1286
1010
  self.e20 = xz2 - wy2
@@ -1308,150 +1032,6 @@ module RMath3D
1308
1032
  return self
1309
1033
  end
1310
1034
 
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
1035
  #
1456
1036
  # call-seq: +
1457
1037
  #
@@ -1467,7 +1047,7 @@ module RMath3D
1467
1047
  # -mtx : Unary minus operator.
1468
1048
  #
1469
1049
  def -@
1470
- return RMtx4.new( self * -1.0 )
1050
+ return RMtx3.new( self * -1.0 )
1471
1051
  end
1472
1052
 
1473
1053
  #
@@ -1476,14 +1056,14 @@ module RMath3D
1476
1056
  # mtx1 + mtx2 : Binary plus operator.
1477
1057
  #
1478
1058
  def +( arg )
1479
- if ( arg.class != RMtx4 )
1480
- raise TypeError, "RMtx4#+(arg) : Unknown type #{arg.class} given as RMtx4."
1059
+ if ( arg.class != RMtx3 )
1060
+ raise TypeError, "RMtx3#+(arg) : Unknown type #{arg.class} given as RMtx3."
1481
1061
  return nil
1482
1062
  end
1483
1063
 
1484
- result = RMtx4.new
1485
- for row in 0...4 do
1486
- for col in 0...4 do
1064
+ result = RMtx3.new
1065
+ for row in 0...3 do
1066
+ for col in 0...3 do
1487
1067
  result.setElement( row, col, getElement(row,col) + arg.getElement(row,col) )
1488
1068
  end
1489
1069
  end
@@ -1497,14 +1077,14 @@ module RMath3D
1497
1077
  # mtx1 - mtx2 : Binary minus operator.
1498
1078
  #
1499
1079
  def -( arg )
1500
- if ( arg.class != RMtx4 )
1501
- raise TypeError, "RMtx4#-(arg) : Unknown type #{arg.class} given as RMtx4."
1080
+ if ( arg.class != RMtx3 )
1081
+ raise TypeError, "RMtx3#-(arg) : Unknown type #{arg.class} given as RMtx3."
1502
1082
  return nil
1503
1083
  end
1504
1084
 
1505
- result = RMtx4.new
1506
- for row in 0...4 do
1507
- for col in 0...4 do
1085
+ result = RMtx3.new
1086
+ for row in 0...3 do
1087
+ for col in 0...3 do
1508
1088
  result.setElement( row, col, getElement(row,col) - arg.getElement(row,col) )
1509
1089
  end
1510
1090
  end
@@ -1520,17 +1100,16 @@ module RMath3D
1520
1100
  def *( arg )
1521
1101
  case arg
1522
1102
  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 )
1103
+ return RMtx3.new( arg*self.e00, arg*self.e01, arg*self.e02,
1104
+ arg*self.e10, arg*self.e11, arg*self.e12,
1105
+ arg*self.e20, arg*self.e21, arg*self.e22 )
1527
1106
 
1528
- when RMtx4
1529
- result = RMtx4.new
1530
- for row in 0...4 do
1531
- for col in 0...4 do
1107
+ when RMtx3
1108
+ result = RMtx3.new
1109
+ for row in 0...3 do
1110
+ for col in 0...3 do
1532
1111
  sum = 0.0
1533
- for i in 0...4 do
1112
+ for i in 0...3 do
1534
1113
  sum += getElement( row, i ) * arg.getElement( i, col )
1535
1114
  end
1536
1115
  result.setElement( row, col, sum )
@@ -1539,7 +1118,7 @@ module RMath3D
1539
1118
  return result
1540
1119
 
1541
1120
  else
1542
- raise TypeError, "RMtx4#*(arg) : Unknown type #{arg.class} given."
1121
+ raise TypeError, "RMtx3#*(arg) : Unknown type #{arg.class} given."
1543
1122
  return nil
1544
1123
  end
1545
1124
  end
@@ -1550,13 +1129,13 @@ module RMath3D
1550
1129
  # mtx1 == mtx2 : evaluates equality.
1551
1130
  #
1552
1131
  def ==( other )
1553
- if ( other.class != RMtx4 )
1554
- raise TypeError, "RMtx4#==(other) : Unknown type #{other.class} given as RMtx4."
1132
+ if ( other.class != RMtx3 )
1133
+ raise TypeError, "RMtx3#==(other) : Unknown type #{other.class} given as RMtx3."
1555
1134
  return nil
1556
1135
  end
1557
1136
 
1558
- for row in 0...4 do
1559
- for col in 0...4 do
1137
+ for row in 0...3 do
1138
+ for col in 0...3 do
1560
1139
  if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
1561
1140
  return false
1562
1141
  end
@@ -1571,14 +1150,14 @@ module RMath3D
1571
1150
  # mtx1 += mtx2 : appends the elements of +mtx2+ into corresponding +mtx1+ elements.
1572
1151
  #
1573
1152
  def add!( other )
1574
- if ( other.class != RMtx4 )
1575
- raise TypeError, "RMtx4#add! : Unknown type #{other.class} given as RMtx4."
1153
+ if ( other.class != RMtx3 )
1154
+ raise TypeError, "RMtx3#add! : Unknown type #{other.class} given as RMtx3."
1576
1155
  return nil
1577
1156
  end
1578
1157
 
1579
- result = RMtx4.new
1580
- for row in 0...4 do
1581
- for col in 0...4 do
1158
+ result = RMtx3.new
1159
+ for row in 0...3 do
1160
+ for col in 0...3 do
1582
1161
  self.setElement( row, col, getElement(row,col) + other.getElement(row,col) )
1583
1162
  end
1584
1163
  end
@@ -1592,14 +1171,14 @@ module RMath3D
1592
1171
  # mtx1 -= mtx2 : subtracts the elements of +mtx2+ from corresponding +mtx1+ elements.
1593
1172
  #
1594
1173
  def sub!( other )
1595
- if ( other.class != RMtx4 )
1596
- raise TypeError, "RMtx4#sub! : Unknown type #{other.class} given as RMtx4."
1174
+ if ( other.class != RMtx3 )
1175
+ raise TypeError, "RMtx3#sub! : Unknown type #{other.class} given as RMtx3."
1597
1176
  return nil
1598
1177
  end
1599
1178
 
1600
- result = RMtx4.new
1601
- for row in 0...4 do
1602
- for col in 0...4 do
1179
+ result = RMtx3.new
1180
+ for row in 0...3 do
1181
+ for col in 0...3 do
1603
1182
  self.setElement( row, col, getElement(row,col) - other.getElement(row,col) )
1604
1183
  end
1605
1184
  end
@@ -1618,31 +1197,20 @@ module RMath3D
1618
1197
  self.e00 = other*self.e00
1619
1198
  self.e01 = other*self.e01
1620
1199
  self.e02 = other*self.e02
1621
- self.e03 = other*self.e03
1622
-
1623
1200
  self.e10 = other*self.e10
1624
1201
  self.e11 = other*self.e11
1625
1202
  self.e12 = other*self.e12
1626
- self.e13 = other*self.e13
1627
-
1628
1203
  self.e20 = other*self.e20
1629
1204
  self.e21 = other*self.e21
1630
1205
  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
1206
 
1638
1207
  return self
1639
-
1640
- when RMtx4
1641
- result = RMtx4.new
1642
- for row in 0...4 do
1643
- for col in 0...4 do
1208
+ when RMtx3
1209
+ result = RMtx3.new
1210
+ for row in 0...3 do
1211
+ for col in 0...3 do
1644
1212
  sum = 0.0
1645
- for i in 0...4 do
1213
+ for i in 0...3 do
1646
1214
  sum += getElement( row, i ) * other.getElement( i, col )
1647
1215
  end
1648
1216
  result.setElement( row, col, sum )
@@ -1652,22 +1220,12 @@ module RMath3D
1652
1220
  self.e00 = result.e00
1653
1221
  self.e01 = result.e01
1654
1222
  self.e02 = result.e02
1655
- self.e03 = result.e03
1656
-
1657
1223
  self.e10 = result.e10
1658
1224
  self.e11 = result.e11
1659
1225
  self.e12 = result.e12
1660
- self.e13 = result.e13
1661
-
1662
1226
  self.e20 = result.e20
1663
1227
  self.e21 = result.e21
1664
1228
  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
1229
 
1672
1230
  return self
1673
1231
  end
@@ -1675,49 +1233,68 @@ module RMath3D
1675
1233
  end
1676
1234
 
1677
1235
  #
1678
- # Document-class: RMath3D::RQuat
1679
- # provies quaternion arithmetic.
1236
+ # Document-class: RMath3D::RMtx4
1237
+ # provies 4x4 matrix arithmetic.
1680
1238
  #
1681
- class RQuat
1239
+ # <b>Notice</b>
1240
+ # * elements are stored in column-major order.
1241
+ #
1242
+ class RMtx4
1682
1243
 
1683
1244
  #
1684
1245
  # 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)
1246
+ # RMtx4.new -> ((1,0,0,0),(0,1,0,0),(0,0,1,0),(0,0,0,1))
1247
+ # RMtx4.new(e) -> ((e,e,e,e),(e,e,e,e),(e,e,e,e),(e,e,e,e))
1248
+ # RMtx4.new( other ) : Copy Constructor
1249
+ # RMtx4.new( e0, e1, ..., e15 ) -> ((e0,e1,e2,e3),(e4,e5,e6,e7),(e8,e9,e10,e11),(e12,e13,e14,e15))
1689
1250
  #
1690
- # Creates a new quaternion.
1251
+ # Creates a new 4x4 matrix.
1691
1252
  #
1692
1253
  def initialize( *a )
1254
+ # [NOTE] elemetns are stored in column-major order.
1693
1255
  @e = []
1694
1256
  case a.length
1695
1257
  when 0
1696
- @e = [0.0, 0.0, 0.0, 0.0]
1258
+ @e = [ 0.0, 0.0, 0.0, 0.0,
1259
+ 0.0, 0.0, 0.0, 0.0,
1260
+ 0.0, 0.0, 0.0, 0.0,
1261
+ 0.0, 0.0, 0.0, 0.0 ]
1697
1262
  when 1
1698
1263
  case a[0]
1699
1264
  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 ]
1265
+ @e = [ a[0], a[0], a[0], a[0],
1266
+ a[0], a[0], a[0], a[0],
1267
+ a[0], a[0], a[0], a[0],
1268
+ a[0], a[0], a[0], a[0] ]
1269
+ when RMtx4
1270
+ # Copy Constructor
1271
+ @e = [ a[0].e00, a[0].e10, a[0].e20, a[0].e30,
1272
+ a[0].e01, a[0].e11, a[0].e21, a[0].e31,
1273
+ a[0].e02, a[0].e12, a[0].e22, a[0].e32,
1274
+ a[0].e03, a[0].e13, a[0].e23, a[0].e33 ]
1703
1275
  else
1704
- raise TypeError, "RQuat#initialize : Unknown type #{a[0].class}."
1276
+ raise TypeError, "RMtx4#initialize : Unknown type #{a[0].class}."
1705
1277
  return nil
1706
1278
  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
1279
+ when 16
1280
+ # Element-wise setter
1281
+ for row in 0...4 do
1282
+ for col in 0...4 do
1283
+ index = 4*row + col
1284
+ case a[index]
1285
+ when Fixnum, Float
1286
+ setElement( row, col, a[index] )
1287
+ else
1288
+ raise TypeError, "RMtx4#initialize : Unknown type #{a[0].class}."
1289
+ return nil
1290
+ end
1715
1291
  end
1716
1292
  end
1717
1293
  else
1718
- raise RuntimeError, "RQuat#initialize : wrong # of arguments (#{a.length})"
1294
+ raise RuntimeError, "RMtx4#initialize : wrong # of arguments (#{a.length})"
1719
1295
  return nil
1720
1296
  end
1297
+
1721
1298
  return self
1722
1299
  end
1723
1300
 
@@ -1727,7 +1304,10 @@ module RMath3D
1727
1304
  # Returns human-readable string.
1728
1305
  #
1729
1306
  def to_s
1730
- return "( #{@e[0]}, #{@e[1]}, #{@e[2]}, #{@e[3]} )\n"
1307
+ "( #{@e[0]}, #{@e[4]}, #{@e[8]}, #{@e[12]} )\n" +
1308
+ "( #{@e[1]}, #{@e[5]}, #{@e[9]}, #{@e[13]} )\n" +
1309
+ "( #{@e[2]}, #{@e[6]}, #{@e[10]}, #{@e[14]} )\n" +
1310
+ "( #{@e[3]}, #{@e[7]}, #{@e[11]}, #{@e[15]} )\n"
1731
1311
  end
1732
1312
 
1733
1313
  #
@@ -1744,266 +1324,1683 @@ module RMath3D
1744
1324
  #
1745
1325
  # Resolves type mismatch.
1746
1326
  #
1747
- def coerce( arg )
1327
+ def coerce
1748
1328
  case arg
1749
1329
  when Fixnum, Float, Bignum
1750
1330
  return [ self, arg ]
1751
1331
  else
1752
- raise TypeError, "RQuat#coerce : #{arg.self} can't be coerced into #{self.class}."
1332
+ raise TypeError, "RMtx4#coerce : #{arg.self} can't be coerced into #{self.class}."
1753
1333
  return nil
1754
1334
  end
1755
1335
  end
1756
1336
 
1757
1337
  #
1758
- # call-seq: setElements( e0, e1, e2, e3 )
1338
+ # call-seq: setElements( e0, e1, ..., e15 )
1759
1339
  #
1760
- # Stores given 4 new values.
1340
+ # Stores given 16 new values.
1761
1341
  #
1762
- def setElements( x, y, z, w )
1763
- self.x = x
1764
- self.y = y
1765
- self.z = z
1766
- self.w = w
1342
+ def setElements( *a )
1343
+ if a.length != 16
1344
+ raise RuntimeError, "RMtx4#setElements : wrong # of arguments (#{a.length})"
1345
+ return nil
1346
+ end
1347
+
1348
+ for row in 0...4 do
1349
+ for col in 0...4 do
1350
+ index = 4*row + col
1351
+ setElement( row, col, a[index] )
1352
+ end
1353
+ end
1767
1354
  end
1768
1355
 
1769
1356
  #
1770
- # call-seq: quat[i]= value
1357
+ # call-seq: [row,col]= value
1771
1358
  #
1772
- # Stores +value+ at +i+.
1359
+ # Stores +value+ at (+row+,+col+).
1773
1360
  #
1774
- def []=(i,value)
1775
- @e[i] = value
1361
+ def []=(row,col,value)
1362
+ # [NOTE] elemetns are stored in column-major order.
1363
+ @e[col*4+row] = value
1776
1364
  end
1365
+ alias_method :setElement, :'[]='
1777
1366
 
1778
1367
  #
1779
- # call-seq: x= value
1368
+ # call-seq: [row,col] -> value
1780
1369
  #
1781
- # Stores +value+ as +x+.
1370
+ # Returns the element at (+row+,+col+).
1782
1371
  #
1783
- def x=(value) @e[0] = value end
1372
+ def [](row,col)
1373
+ # [NOTE] elemetns are stored in column-major order.
1374
+ return @e[col*4+row]
1375
+ end
1376
+ alias_method :getElement, :'[]'
1377
+
1378
+ # Returns the element at row 0 and column 0.
1379
+ def e00() getElement(0,0) end
1380
+ # Returns the element at row 0 and column 1.
1381
+ def e01() getElement(0,1) end
1382
+ # Returns the element at row 0 and column 2.
1383
+ def e02() getElement(0,2) end
1384
+ # Returns the element at row 0 and column 3.
1385
+ def e03() getElement(0,3) end
1386
+ # Returns the element at row 1 and column 0.
1387
+ def e10() getElement(1,0) end
1388
+ # Returns the element at row 1 and column 1.
1389
+ def e11() getElement(1,1) end
1390
+ # Returns the element at row 1 and column 2.
1391
+ def e12() getElement(1,2) end
1392
+ # Returns the element at row 1 and column 3.
1393
+ def e13() getElement(1,3) end
1394
+ # Returns the element at row 2 and column 0.
1395
+ def e20() getElement(2,0) end
1396
+ # Returns the element at row 2 and column 1.
1397
+ def e21() getElement(2,1) end
1398
+ # Returns the element at row 2 and column 2.
1399
+ def e22() getElement(2,2) end
1400
+ # Returns the element at row 2 and column 3.
1401
+ def e23() getElement(2,3) end
1402
+ # Returns the element at row 3 and column 0.
1403
+ def e30() getElement(3,0) end
1404
+ # Returns the element at row 3 and column 1.
1405
+ def e31() getElement(3,1) end
1406
+ # Returns the element at row 3 and column 2.
1407
+ def e32() getElement(3,2) end
1408
+ # Returns the element at row 3 and column 3.
1409
+ def e33() getElement(3,3) end
1410
+
1411
+ # Replaces the element at row 0 and column 0 by +value+.
1412
+ def e00=(value) setElement(0,0,value) end
1413
+ # Replaces the element at row 0 and column 1 by +value+.
1414
+ def e01=(value) setElement(0,1,value) end
1415
+ # Replaces the element at row 0 and column 2 by +value+.
1416
+ def e02=(value) setElement(0,2,value) end
1417
+ # Replaces the element at row 0 and column 3 by +value+.
1418
+ def e03=(value) setElement(0,3,value) end
1419
+ # Replaces the element at row 1 and column 0 by +value+.
1420
+ def e10=(value) setElement(1,0,value) end
1421
+ # Replaces the element at row 1 and column 1 by +value+.
1422
+ def e11=(value) setElement(1,1,value) end
1423
+ # Replaces the element at row 1 and column 2 by +value+.
1424
+ def e12=(value) setElement(1,2,value) end
1425
+ # Replaces the element at row 1 and column 3 by +value+.
1426
+ def e13=(value) setElement(1,3,value) end
1427
+ # Replaces the element at row 2 and column 0 by +value+.
1428
+ def e20=(value) setElement(2,0,value) end
1429
+ # Replaces the element at row 2 and column 1 by +value+.
1430
+ def e21=(value) setElement(2,1,value) end
1431
+ # Replaces the element at row 2 and column 2 by +value+.
1432
+ def e22=(value) setElement(2,2,value) end
1433
+ # Replaces the element at row 2 and column 3 by +value+.
1434
+ def e23=(value) setElement(2,3,value) end
1435
+ # Replaces the element at row 3 and column 0 by +value+.
1436
+ def e30=(value) setElement(3,0,value) end
1437
+ # Replaces the element at row 3 and column 1 by +value+.
1438
+ def e31=(value) setElement(3,1,value) end
1439
+ # Replaces the element at row 3 and column 2 by +value+.
1440
+ def e32=(value) setElement(3,2,value) end
1441
+ # Replaces the element at row 3 and column 3 by +value+.
1442
+ def e33=(value) setElement(3,3,value) end
1784
1443
 
1785
1444
  #
1786
- # call-seq: y= value
1445
+ # call-seq: mtx4.getRow(r) -> RVec4
1787
1446
  #
1788
- # Stores +value+ as +y+.
1447
+ # Returns +r+-th row vector.
1789
1448
  #
1790
- def y=(value) @e[1] = value end
1449
+ def getRow( row )
1450
+ return RVec4.new( self[row,0], self[row,1], self[row,2], self[row,3] )
1451
+ end
1791
1452
 
1792
1453
  #
1793
- # call-seq: z= value
1454
+ # call-seq: mtx4.getColumn(c) -> RVec4
1794
1455
  #
1795
- # Stores +value+ as +z+.
1456
+ # Returns +c+-th column vector.
1796
1457
  #
1797
- def z=(value) @e[2] = value end
1458
+ def getColumn( column )
1459
+ return RVec4.new( self[0,column], self[1,column], self[2,column], self[3,column] )
1460
+ end
1461
+
1462
+ #
1463
+ # call-seq: mtx4.setRow(v,r)
1464
+ #
1465
+ # Returns sets +r+-th row by vector +v+.
1466
+ #
1467
+ def setRow( v, row )
1468
+ self[row,0] = v.x
1469
+ self[row,1] = v.y
1470
+ self[row,2] = v.z
1471
+ self[row,3] = v.w
1472
+ end
1473
+
1474
+ #
1475
+ # call-seq: mtx4.setColumn(v,c)
1476
+ #
1477
+ # Returns sets +c+-th column by vector +v+.
1478
+ #
1479
+ def setColumn( v, column )
1480
+ self[0,column] = v.x
1481
+ self[1,column] = v.y
1482
+ self[2,column] = v.z
1483
+ self[3,column] = v.w
1484
+ end
1485
+
1486
+ def getUpper3x3
1487
+ return RMtx3.new( self.e00, self.e01, self.e02,
1488
+ self.e10, self.e11, self.e12,
1489
+ self.e20, self.e21, self.e22 )
1490
+ end
1491
+
1492
+ def setUpper3x3( mtx3x3 )
1493
+ self.e00 = mtx3x3.e00
1494
+ self.e01 = mtx3x3.e01
1495
+ self.e02 = mtx3x3.e02
1496
+ self.e10 = mtx3x3.e10
1497
+ self.e11 = mtx3x3.e11
1498
+ self.e12 = mtx3x3.e12
1499
+ self.e20 = mtx3x3.e20
1500
+ self.e21 = mtx3x3.e21
1501
+ self.e22 = mtx3x3.e22
1502
+
1503
+ return self
1504
+ end
1505
+
1506
+ # call-seq: setZero
1507
+ #
1508
+ # Clears all elements by 0.0
1509
+ #
1510
+ def setZero
1511
+ 16.times do |i|
1512
+ @e[i] = 0.0
1513
+ end
1514
+ return self
1515
+ end
1516
+
1517
+ #
1518
+ # call-seq: setIdentity
1519
+ #
1520
+ # Sets as identity matrix.
1521
+ #
1522
+ def setIdentity
1523
+ for row in 0...4 do
1524
+ for col in 0...4 do
1525
+ index = 4*row + col
1526
+ if ( row == col )
1527
+ setElement( row, col, 1.0 )
1528
+ else
1529
+ setElement( row, col, 0.0 )
1530
+ end
1531
+ end
1532
+ end
1533
+ return self
1534
+ end
1535
+
1536
+ def det3( _e00,_e01,_e02, _e10,_e11,_e12, _e20,_e21,_e22 )
1537
+ _e00 * (_e11*_e22 - _e12*_e21) -
1538
+ _e01 * (_e10*_e22 - _e12*_e20) +
1539
+ _e02 * (_e10*_e21 - _e11*_e20)
1540
+ end
1541
+ private :det3
1542
+
1543
+ #
1544
+ # call-seq: getDeterminant -> determinant
1545
+ #
1546
+ # Calculates determinant.
1547
+ #
1548
+ def getDeterminant
1549
+ e00 * det3( e11,e12,e13, e21,e22,e23, e31,e32,e33 ) -
1550
+ e01 * det3( e10,e12,e13, e20,e22,e23, e30,e32,e33 ) +
1551
+ e02 * det3( e10,e11,e13, e20,e21,e23, e30,e31,e33 ) -
1552
+ e03 * det3( e10,e11,e12, e20,e21,e22, e30,e31,e32 )
1553
+ end
1554
+
1555
+ #
1556
+ # call-seq: getTransposed
1557
+ #
1558
+ # Returns transposed matrix.
1559
+ #
1560
+ def getTransposed
1561
+ return RMtx4.new( @e[ 0], @e[ 1], @e[ 2], @e[ 3],
1562
+ @e[ 4], @e[ 5], @e[ 6], @e[ 7],
1563
+ @e[ 8], @e[ 9], @e[10], @e[11],
1564
+ @e[12], @e[13], @e[14], @e[15] )
1565
+ end
1566
+
1567
+ #
1568
+ # call-seq: transpose!
1569
+ #
1570
+ # Transposeas its elements.
1571
+ #
1572
+ def transpose!
1573
+ @e[ 1], @e[ 4] = @e[ 4], @e[ 1]
1574
+ @e[ 2], @e[ 8] = @e[ 8], @e[ 2]
1575
+ @e[ 3], @e[12] = @e[12], @e[ 3]
1576
+ @e[ 6], @e[ 9] = @e[ 9], @e[ 6]
1577
+ @e[ 7], @e[13] = @e[13], @e[ 7]
1578
+ @e[11], @e[14] = @e[14], @e[11]
1579
+ end
1580
+
1581
+ #
1582
+ # call-seq: getInverse -> inverse
1583
+ #
1584
+ # Returns the inverse.
1585
+ #
1586
+ def getInverse
1587
+ result = RMtx4.new
1588
+
1589
+ result.e00 = det3( e11,e12,e13, e21,e22,e23, e31,e32,e33 )
1590
+ result.e01 = -det3( e01,e02,e03, e21,e22,e23, e31,e32,e33 )
1591
+ result.e02 = det3( e01,e02,e03, e11,e12,e13, e31,e32,e33 )
1592
+ result.e03 = -det3( e01,e02,e03, e11,e12,e13, e21,e22,e23 )
1593
+
1594
+ result.e10 = -det3( e10,e12,e13, e20,e22,e23, e30,e32,e33 )
1595
+ result.e11 = det3( e00,e02,e03, e20,e22,e23, e30,e32,e33 )
1596
+ result.e12 = -det3( e00,e02,e03, e10,e12,e13, e30,e32,e33 )
1597
+ result.e13 = det3( e00,e02,e03, e10,e12,e13, e20,e22,e23 )
1598
+
1599
+ result.e20 = det3( e10,e11,e13, e20,e21,e23, e30,e31,e33 )
1600
+ result.e21 = -det3( e00,e01,e03, e20,e21,e23, e30,e31,e33 )
1601
+ result.e22 = det3( e00,e01,e03, e10,e11,e13, e30,e31,e33 )
1602
+ result.e23 = -det3( e00,e01,e03, e10,e11,e13, e20,e21,e23 )
1603
+
1604
+ result.e30 = -det3( e10,e11,e12, e20,e21,e22, e30,e31,e32 )
1605
+ result.e31 = det3( e00,e01,e02, e20,e21,e22, e30,e31,e32 )
1606
+ result.e32 = -det3( e00,e01,e02, e10,e11,e12, e30,e31,e32 )
1607
+ result.e33 = det3( e00,e01,e02, e10,e11,e12, e20,e21,e22 )
1608
+
1609
+ det = e00 * result.e00 + e01 * result.e10 + e02 * result.e20 + e03 * result.e30
1610
+
1611
+ if ( det.abs < TOLERANCE )
1612
+ raise RuntimeError, "RMtx4#getInverse : det.abs < TOLERANCE"
1613
+ return nil
1614
+ end
1615
+
1616
+ d = 1.0 / det
1617
+
1618
+ result.mul!( d )
1619
+
1620
+ return result
1621
+ end
1622
+
1623
+ #
1624
+ # call-seq: invert! -> self
1625
+ #
1626
+ # Makes itself as the inverse of the original matrix.
1627
+ #
1628
+ def invert!
1629
+ elements = Array.new( 16 )
1630
+
1631
+ elements[4*0+0] = det3( self.e11,self.e12,self.e13, self.e21,self.e22,self.e23, self.e31,self.e32,self.e33 )
1632
+ elements[4*0+1] = -det3( self.e01,self.e02,self.e03, self.e21,self.e22,self.e23, self.e31,self.e32,self.e33 )
1633
+ elements[4*0+2] = det3( self.e01,self.e02,self.e03, self.e11,self.e12,self.e13, self.e31,self.e32,self.e33 )
1634
+ elements[4*0+3] = -det3( self.e01,self.e02,self.e03, self.e11,self.e12,self.e13, self.e21,self.e22,self.e23 )
1635
+
1636
+ elements[4*1+0] = -det3( self.e10,self.e12,self.e13, self.e20,self.e22,self.e23, self.e30,self.e32,self.e33 )
1637
+ elements[4*1+1] = det3( self.e00,self.e02,self.e03, self.e20,self.e22,self.e23, self.e30,self.e32,self.e33 )
1638
+ elements[4*1+2] = -det3( self.e00,self.e02,self.e03, self.e10,self.e12,self.e13, self.e30,self.e32,self.e33 )
1639
+ elements[4*1+3] = det3( self.e00,self.e02,self.e03, self.e10,self.e12,self.e13, self.e20,self.e22,self.e23 )
1640
+
1641
+ elements[4*2+0] = det3( self.e10,self.e11,self.e13, self.e20,self.e21,self.e23, self.e30,self.e31,self.e33 )
1642
+ elements[4*2+1] = -det3( self.e00,self.e01,self.e03, self.e20,self.e21,self.e23, self.e30,self.e31,self.e33 )
1643
+ elements[4*2+2] = det3( self.e00,self.e01,self.e03, self.e10,self.e11,self.e13, self.e30,self.e31,self.e33 )
1644
+ elements[4*2+3] = -det3( self.e00,self.e01,self.e03, self.e10,self.e11,self.e13, self.e20,self.e21,self.e23 )
1645
+
1646
+ elements[4*3+0] = -det3( self.e10,self.e11,self.e12, self.e20,self.e21,self.e22, self.e30,self.e31,self.e32 )
1647
+ elements[4*3+1] = det3( self.e00,self.e01,self.e02, self.e20,self.e21,self.e22, self.e30,self.e31,self.e32 )
1648
+ elements[4*3+2] = -det3( self.e00,self.e01,self.e02, self.e10,self.e11,self.e12, self.e30,self.e31,self.e32 )
1649
+ elements[4*3+3] = det3( self.e00,self.e01,self.e02, self.e10,self.e11,self.e12, self.e20,self.e21,self.e22 )
1650
+
1651
+ det = e00 * elements[4*0+0] + e01 * elements[4*1+0] + e02 * elements[4*2+0] + e03 * elements[4*3+0]
1652
+
1653
+ if ( det.abs< TOLERANCE )
1654
+ raise RuntimeError, "RMtx4invert! : det.abs < TOLERANCE"
1655
+ return nil
1656
+ end
1657
+
1658
+ d = 1.0 / det
1659
+
1660
+ setElement( 0, 0, d * elements[4*0+0] )
1661
+ setElement( 0, 1, d * elements[4*0+1] )
1662
+ setElement( 0, 2, d * elements[4*0+2] )
1663
+ setElement( 0, 3, d * elements[4*0+3] )
1664
+
1665
+ setElement( 1, 0, d * elements[4*1+0] )
1666
+ setElement( 1, 1, d * elements[4*1+1] )
1667
+ setElement( 1, 2, d * elements[4*1+2] )
1668
+ setElement( 1, 3, d * elements[4*1+3] )
1669
+
1670
+ setElement( 2, 0, d * elements[4*2+0] )
1671
+ setElement( 2, 1, d * elements[4*2+1] )
1672
+ setElement( 2, 2, d * elements[4*2+2] )
1673
+ setElement( 2, 3, d * elements[4*2+3] )
1674
+
1675
+ setElement( 3, 0, d * elements[4*3+0] )
1676
+ setElement( 3, 1, d * elements[4*3+1] )
1677
+ setElement( 3, 2, d * elements[4*3+2] )
1678
+ setElement( 3, 3, d * elements[4*3+3] )
1679
+
1680
+ return self
1681
+ end
1682
+
1683
+ #
1684
+ # call-seq: translation(tx,ty,tz) -> self
1685
+ #
1686
+ # Makes itself as a translation matrix.
1687
+ #
1688
+ def translation( tx, ty, tz )
1689
+ setIdentity()
1690
+ self.e03 = tx
1691
+ self.e13 = ty
1692
+ self.e23 = tz
1693
+
1694
+ return self
1695
+ end
1696
+
1697
+ #
1698
+ # call-seq: rotationX(radian) -> self
1699
+ #
1700
+ # Makes a matrix that rotates around the x-axis.
1701
+ #
1702
+ def rotationX( radian )
1703
+ s = Math.sin( radian )
1704
+ c = Math.cos( radian )
1705
+
1706
+ setIdentity()
1707
+ self.e11 = c
1708
+ self.e12 = -s
1709
+ self.e21 = s
1710
+ self.e22 = c
1711
+
1712
+ return self
1713
+ end
1714
+
1715
+ #
1716
+ # call-seq: rotationY(radian) -> self
1717
+ #
1718
+ # Makes a matrix that rotates around the y-axis.
1719
+ #
1720
+ def rotationY( radian )
1721
+ s = Math.sin( radian )
1722
+ c = Math.cos( radian )
1723
+
1724
+ setIdentity()
1725
+ self.e00 = c
1726
+ self.e02 = s
1727
+ self.e20 = -s
1728
+ self.e22 = c
1729
+
1730
+ return self
1731
+ end
1732
+
1733
+ #
1734
+ # call-seq: rotationZ(radian) -> self
1735
+ #
1736
+ # Makes a matrix that rotates around the z-axis.
1737
+ #
1738
+ def rotationZ( radian )
1739
+ s = Math.sin( radian )
1740
+ c = Math.cos( radian )
1741
+
1742
+ setIdentity()
1743
+ self.e00 = c
1744
+ self.e01 = -s
1745
+ self.e10 = s
1746
+ self.e11 = c
1747
+
1748
+ return self
1749
+ end
1750
+
1751
+ #
1752
+ # call-seq: rotationAxis(axis,radian) -> self
1753
+ #
1754
+ # Makes a matrix that rotates around the +axis+.
1755
+ #
1756
+ def rotationAxis( axis, radian )
1757
+ if ( axis.class != RVec3 )
1758
+ raise TypeError, "RMtx4#rotationAxis : Unknown type #{axis.class} given as axis."
1759
+ return nil
1760
+ end
1761
+ s = Math.sin( radian )
1762
+ c = Math.cos( radian )
1763
+ omc = 1.0 - c
1764
+ x = axis.x.to_f
1765
+ y = axis.y.to_f
1766
+ z = axis.z.to_f
1767
+
1768
+ setIdentity()
1769
+
1770
+ self.e00 = x*x*omc + c
1771
+ self.e01 = x*y*omc - z*s
1772
+ self.e02 = z*x*omc + y*s
1773
+ self.e10 = x*y*omc + z*s
1774
+ self.e11 = y*y*omc + c
1775
+ self.e12 = y*z*omc - x*s
1776
+ self.e20 = z*x*omc - y*s
1777
+ self.e21 = y*z*omc + x*s
1778
+ self.e22 = z*z*omc + c
1779
+
1780
+ return self
1781
+ end
1782
+
1783
+ #
1784
+ # call-seq: rotationQuaternion(q) -> self
1785
+ #
1786
+ # Makes a rotation matrix from a normalized quaternion +q+.
1787
+ #
1788
+ def rotationQuaternion( q )
1789
+ if ( q.class != RQuat )
1790
+ raise TypeError, "RMtx4#rotationQuaternion : Unknown type #{q.class} given as RQuat."
1791
+ return nil
1792
+ end
1793
+ x = q.x
1794
+ y = q.y
1795
+ z = q.z
1796
+ w = q.w
1797
+
1798
+ x2 = 2.0 * x
1799
+ y2 = 2.0 * y
1800
+ z2 = 2.0 * z
1801
+
1802
+ xx2 = x * x2
1803
+ yy2 = y * y2
1804
+ zz2 = z * z2
1805
+
1806
+ yz2 = y * z2
1807
+ wx2 = w * x2
1808
+ xy2 = x * y2
1809
+ wz2 = w * z2
1810
+ xz2 = x * z2
1811
+ wy2 = w * y2
1812
+
1813
+ setIdentity()
1814
+
1815
+ self.e00 = 1.0 - yy2 - zz2
1816
+ self.e10 = xy2 + wz2
1817
+ self.e20 = xz2 - wy2
1818
+ self.e01 = xy2 - wz2
1819
+ self.e11 = 1.0 - xx2 - zz2
1820
+ self.e21 = yz2 + wx2
1821
+ self.e02 = xz2 + wy2
1822
+ self.e12 = yz2 - wx2
1823
+ self.e22 = 1.0 - xx2 - yy2
1824
+
1825
+ return self
1826
+ end
1827
+
1828
+ #
1829
+ # call-seq: scaling(sx,sy,sz) -> self
1830
+ #
1831
+ # Makes itself as a scaling matrix.
1832
+ #
1833
+ def scaling( sx, sy, sz )
1834
+ setIdentity()
1835
+ setElement( 0, 0, sx )
1836
+ setElement( 1, 1, sy )
1837
+ setElement( 2, 2, sz )
1838
+
1839
+ return self
1840
+ end
1841
+
1842
+ #
1843
+ # call-seq: lookAtRH(eye,at,up) -> self
1844
+ #
1845
+ # Builds a viewing matrix for a right-handed coordinate system from:
1846
+ # * eye position (+eye+: RVec3)
1847
+ # * a point looking at (+at+: RVec3)
1848
+ # * up vector (+up+: RVec3)
1849
+ #
1850
+ def lookAtRH( eye, at, up )
1851
+ setIdentity()
1852
+
1853
+ axis_z = (eye - at).normalize!
1854
+ axis_x = RVec3.cross( up, axis_z ).normalize!
1855
+ axis_y = RVec3.cross( axis_z, axis_x )
1856
+
1857
+ self.e00 = axis_x[0]
1858
+ self.e01 = axis_x[1]
1859
+ self.e02 = axis_x[2]
1860
+ self.e03 = -RVec3.dot( axis_x, eye )
1861
+
1862
+ self.e10 = axis_y[0]
1863
+ self.e11 = axis_y[1]
1864
+ self.e12 = axis_y[2]
1865
+ self.e13 = -RVec3.dot( axis_y, eye )
1866
+
1867
+ self.e20 = axis_z[0]
1868
+ self.e21 = axis_z[1]
1869
+ self.e22 = axis_z[2]
1870
+ self.e23 = -RVec3.dot( axis_z, eye )
1871
+
1872
+ return self
1873
+ end
1874
+
1875
+ #
1876
+ # call-seq: perspectiveRH(width,height,znear,zfar) -> self
1877
+ #
1878
+ # Builds a perspective projection matrix for a right-handed coordinate system from:
1879
+ # * View volume width (+width+)
1880
+ # * View volume height (+height+)
1881
+ # * Near clip plane distance (+znear+)
1882
+ # * Far clip plane distance (+zfar+)
1883
+ #
1884
+ def perspectiveRH( width, height, znear, zfar )
1885
+ perspectiveOffCenterRH(-width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar )
1886
+ return self
1887
+ end
1888
+
1889
+ #
1890
+ # call-seq: perspectiveFovRH(fovy,aspect,znear,zfar) -> self
1891
+ #
1892
+ # Builds a perspective projection matrix for a right-handed coordinate system from:
1893
+ # * Field of view in y direction (+fovy+ radian)
1894
+ # * Aspect ratio (+aspect+)
1895
+ # * Near clip plane distance (+znear+)
1896
+ # * Far clip plane distance (+zfar+)
1897
+ #
1898
+ def perspectiveFovRH( fovy_radian, aspect, znear, zfar )
1899
+ f = Math::tan( fovy_radian / 2.0 )
1900
+ f = 1.0 / f
1901
+
1902
+ setIdentity()
1903
+ setElement( 0, 0, f / aspect )
1904
+ setElement( 1, 1, f )
1905
+ setElement( 2, 2, (zfar+znear)/(znear-zfar) )
1906
+ setElement( 2, 3, 2*zfar*znear/(znear-zfar) )
1907
+ setElement( 3, 2, -1.0 )
1908
+ setElement( 3, 3, 0.0 )
1909
+
1910
+ return self
1911
+ end
1912
+
1913
+ #
1914
+ # call-seq: perspectiveOffCenterRH(left,right,bottom,top,znear,zfar) -> self
1915
+ #
1916
+ # Builds a perspective projection matrix for a right-handed coordinate system from:
1917
+ # * Minimum value of the view volume width (+left+)
1918
+ # * Maximum value of the view volume width (+right+)
1919
+ # * Minimum value of the view volume height (+bottom+)
1920
+ # * Maximum value of the view volume height (+top+)
1921
+ # * Near clip plane distance (+znear+)
1922
+ # * Far clip plane distance (+zfar+)
1923
+ #
1924
+ def perspectiveOffCenterRH( left, right, bottom, top, znear, zfar )
1925
+ a = (right+left) / (right-left)
1926
+ b = (top+bottom) / (top-bottom)
1927
+ c = -(zfar+znear) / (zfar-znear)
1928
+ d = -(2*znear*zfar) / (zfar-znear)
1929
+
1930
+ setIdentity()
1931
+
1932
+ setElement( 0, 0, 2*znear/(right-left) )
1933
+ setElement( 0, 2, a )
1934
+ setElement( 1, 1, 2*znear/(top-bottom) )
1935
+ setElement( 1, 2, b )
1936
+ setElement( 2, 2, c )
1937
+ setElement( 2, 3, d )
1938
+ setElement( 3, 2, -1.0 )
1939
+ setElement( 3, 3, 0.0 )
1940
+
1941
+ return self
1942
+ end
1943
+
1944
+ #
1945
+ # call-seq: orthoRH(width,height,znear,zfar) -> self
1946
+ #
1947
+ # Builds a orthogonal projection matrix for a right-handed coordinate system from:
1948
+ # * View volume width (+width+)
1949
+ # * View volume height (+height+)
1950
+ # * Near clip plane distance (+znear+)
1951
+ # * Far clip plane distance (+zfar+)
1952
+ #
1953
+ def orthoRH( width, height, znear, zfar )
1954
+ orthoOffCenterRH( -width/2.0, width/2.0, -height/2.0, height/2.0, znear, zfar )
1955
+ return self
1956
+ end
1957
+
1958
+ #
1959
+ # call-seq: orthoOffCenterRH(left,right,bottom,top,znear,zfar) -> self
1960
+ #
1961
+ # Builds a orthogonal projection matrix for a right-handed coordinate system from:
1962
+ # * Minimum value of the view volume width (+left+)
1963
+ # * Maximum value of the view volume width (+right+)
1964
+ # * Minimum value of the view volume height (+bottom+)
1965
+ # * Maximum value of the view volume height (+top+)
1966
+ # * Near clip plane distance (+znear+)
1967
+ # * Far clip plane distance (+zfar+)
1968
+ #
1969
+ def orthoOffCenterRH( left, right, bottom, top, znear, zfar )
1970
+ tx = (right+left) / (right-left)
1971
+ ty = (top+bottom) / (top-bottom)
1972
+ tz = (zfar+znear) / (zfar-znear)
1973
+
1974
+ setIdentity()
1975
+
1976
+ setElement( 0, 0, 2.0/(right-left) )
1977
+ setElement( 0, 3, tx )
1978
+ setElement( 1, 1, 2.0/(top-bottom) )
1979
+ setElement( 1, 3, ty )
1980
+ setElement( 2, 2, -2.0/(zfar-znear) )
1981
+ setElement( 2, 3, tz )
1982
+
1983
+ return self
1984
+ end
1985
+
1986
+ #
1987
+ # call-seq: +
1988
+ #
1989
+ # +mtx : Unary plus operator.
1990
+ #
1991
+ def +@
1992
+ return self
1993
+ end
1994
+
1995
+ #
1996
+ # call-seq: -
1997
+ #
1998
+ # -mtx : Unary minus operator.
1999
+ #
2000
+ def -@
2001
+ return RMtx4.new( self * -1.0 )
2002
+ end
2003
+
2004
+ #
2005
+ # call-seq: +
2006
+ #
2007
+ # mtx1 + mtx2 : Binary plus operator.
2008
+ #
2009
+ def +( arg )
2010
+ if ( arg.class != RMtx4 )
2011
+ raise TypeError, "RMtx4#+(arg) : Unknown type #{arg.class} given as RMtx4."
2012
+ return nil
2013
+ end
2014
+
2015
+ result = RMtx4.new
2016
+ for row in 0...4 do
2017
+ for col in 0...4 do
2018
+ result.setElement( row, col, getElement(row,col) + arg.getElement(row,col) )
2019
+ end
2020
+ end
2021
+
2022
+ return result
2023
+ end
2024
+
2025
+ #
2026
+ # call-seq: -
2027
+ #
2028
+ # mtx1 - mtx2 : Binary minus operator.
2029
+ #
2030
+ def -( arg )
2031
+ if ( arg.class != RMtx4 )
2032
+ raise TypeError, "RMtx4#-(arg) : Unknown type #{arg.class} given as RMtx4."
2033
+ return nil
2034
+ end
2035
+
2036
+ result = RMtx4.new
2037
+ for row in 0...4 do
2038
+ for col in 0...4 do
2039
+ result.setElement( row, col, getElement(row,col) - arg.getElement(row,col) )
2040
+ end
2041
+ end
2042
+
2043
+ return result
2044
+ end
2045
+
2046
+ #
2047
+ # call-seq: *
2048
+ #
2049
+ # mtx1 * mtx2 : Binary multiply operator.
2050
+ #
2051
+ def *( arg )
2052
+ case arg
2053
+ when Fixnum, Float, Bignum
2054
+ return RMtx4.new( arg*self.e00, arg*self.e01, arg*self.e02, arg*self.e03,
2055
+ arg*self.e10, arg*self.e11, arg*self.e12, arg*self.e13,
2056
+ arg*self.e20, arg*self.e21, arg*self.e22, arg*self.e23,
2057
+ arg*self.e30, arg*self.e31, arg*self.e32, arg*self.e33 )
2058
+
2059
+ when RMtx4
2060
+ result = RMtx4.new
2061
+ for row in 0...4 do
2062
+ for col in 0...4 do
2063
+ sum = 0.0
2064
+ for i in 0...4 do
2065
+ sum += getElement( row, i ) * arg.getElement( i, col )
2066
+ end
2067
+ result.setElement( row, col, sum )
2068
+ end
2069
+ end
2070
+ return result
2071
+
2072
+ else
2073
+ raise TypeError, "RMtx4#*(arg) : Unknown type #{arg.class} given."
2074
+ return nil
2075
+ end
2076
+ end
2077
+
2078
+ #
2079
+ # call-seq: ==
2080
+ #
2081
+ # mtx1 == mtx2 : evaluates equality.
2082
+ #
2083
+ def ==( other )
2084
+ if ( other.class != RMtx4 )
2085
+ raise TypeError, "RMtx4#==(other) : Unknown type #{other.class} given as RMtx4."
2086
+ return nil
2087
+ end
2088
+
2089
+ for row in 0...4 do
2090
+ for col in 0...4 do
2091
+ if ( (getElement(row,col) - other.getElement(row,col)).abs > TOLERANCE )
2092
+ return false
2093
+ end
2094
+ end
2095
+ end
2096
+ return true
2097
+ end
2098
+
2099
+ #
2100
+ # call-seq: mtx1.add!( mtx2 )
2101
+ #
2102
+ # mtx1 += mtx2 : appends the elements of +mtx2+ into corresponding +mtx1+ elements.
2103
+ #
2104
+ def add!( other )
2105
+ if ( other.class != RMtx4 )
2106
+ raise TypeError, "RMtx4#add! : Unknown type #{other.class} given as RMtx4."
2107
+ return nil
2108
+ end
2109
+
2110
+ result = RMtx4.new
2111
+ for row in 0...4 do
2112
+ for col in 0...4 do
2113
+ self.setElement( row, col, getElement(row,col) + other.getElement(row,col) )
2114
+ end
2115
+ end
2116
+
2117
+ return self
2118
+ end
2119
+
2120
+ #
2121
+ # call-seq: mtx1.sub!( mtx2 )
2122
+ #
2123
+ # mtx1 -= mtx2 : subtracts the elements of +mtx2+ from corresponding +mtx1+ elements.
2124
+ #
2125
+ def sub!( other )
2126
+ if ( other.class != RMtx4 )
2127
+ raise TypeError, "RMtx4#sub! : Unknown type #{other.class} given as RMtx4."
2128
+ return nil
2129
+ end
2130
+
2131
+ result = RMtx4.new
2132
+ for row in 0...4 do
2133
+ for col in 0...4 do
2134
+ self.setElement( row, col, getElement(row,col) - other.getElement(row,col) )
2135
+ end
2136
+ end
2137
+
2138
+ return self
2139
+ end
2140
+
2141
+ #
2142
+ # call-seq: mtx1.mul!( mtx2 )
2143
+ #
2144
+ # mtx1 *= mtx2
2145
+ #
2146
+ def mul!( other )
2147
+ case other
2148
+ when Fixnum, Float, Bignum
2149
+ self.e00 = other*self.e00
2150
+ self.e01 = other*self.e01
2151
+ self.e02 = other*self.e02
2152
+ self.e03 = other*self.e03
2153
+
2154
+ self.e10 = other*self.e10
2155
+ self.e11 = other*self.e11
2156
+ self.e12 = other*self.e12
2157
+ self.e13 = other*self.e13
2158
+
2159
+ self.e20 = other*self.e20
2160
+ self.e21 = other*self.e21
2161
+ self.e22 = other*self.e22
2162
+ self.e23 = other*self.e23
2163
+
2164
+ self.e30 = other*self.e30
2165
+ self.e31 = other*self.e31
2166
+ self.e32 = other*self.e32
2167
+ self.e33 = other*self.e33
2168
+
2169
+ return self
2170
+
2171
+ when RMtx4
2172
+ result = RMtx4.new
2173
+ for row in 0...4 do
2174
+ for col in 0...4 do
2175
+ sum = 0.0
2176
+ for i in 0...4 do
2177
+ sum += getElement( row, i ) * other.getElement( i, col )
2178
+ end
2179
+ result.setElement( row, col, sum )
2180
+ end
2181
+ end
2182
+
2183
+ self.e00 = result.e00
2184
+ self.e01 = result.e01
2185
+ self.e02 = result.e02
2186
+ self.e03 = result.e03
2187
+
2188
+ self.e10 = result.e10
2189
+ self.e11 = result.e11
2190
+ self.e12 = result.e12
2191
+ self.e13 = result.e13
2192
+
2193
+ self.e20 = result.e20
2194
+ self.e21 = result.e21
2195
+ self.e22 = result.e22
2196
+ self.e23 = result.e23
2197
+
2198
+ self.e30 = result.e30
2199
+ self.e31 = result.e31
2200
+ self.e32 = result.e32
2201
+ self.e33 = result.e33
2202
+
2203
+ return self
2204
+ end
2205
+ end
2206
+ end
2207
+
2208
+ #
2209
+ # Document-class: RMath3D::RQuat
2210
+ # provies quaternion arithmetic.
2211
+ #
2212
+ class RQuat
2213
+
2214
+ #
2215
+ # call-seq:
2216
+ # RQuat.new -> (0,0,0,0)
2217
+ # RQuat.new(e) -> (e,e,e,e)
2218
+ # RQuat.new( other ) : Copy Constructor
2219
+ # RQuat.new( e0, e1, e2, e3 ) -> (e0,e1,e2,e3)
2220
+ #
2221
+ # Creates a new quaternion.
2222
+ #
2223
+ def initialize( *a )
2224
+ @e = []
2225
+ case a.length
2226
+ when 0
2227
+ @e = [0.0, 0.0, 0.0, 0.0]
2228
+ when 1
2229
+ case a[0]
2230
+ when Fixnum, Float
2231
+ @e = [ a[0], a[0], a[0], a[0] ]
2232
+ when RQuat
2233
+ @e = [ a[0].x, a[0].y, a[0].z, a[0].w ]
2234
+ else
2235
+ raise TypeError, "RQuat#initialize : Unknown type #{a[0].class}."
2236
+ return nil
2237
+ end
2238
+ when 4
2239
+ a.each_with_index do |elem, index|
2240
+ case elem
2241
+ when Fixnum, Float
2242
+ @e[index] = elem
2243
+ else
2244
+ raise TypeError, "RQuat#initialize : Unknown type #{elem.class}."
2245
+ return nil
2246
+ end
2247
+ end
2248
+ else
2249
+ raise RuntimeError, "RQuat#initialize : wrong # of arguments (#{a.length})"
2250
+ return nil
2251
+ end
2252
+ return self
2253
+ end
2254
+
2255
+ #
2256
+ # call-seq: to_s
2257
+ #
2258
+ # Returns human-readable string.
2259
+ #
2260
+ def to_s
2261
+ return "( #{@e[0]}, #{@e[1]}, #{@e[2]}, #{@e[3]} )\n"
2262
+ end
2263
+
2264
+ #
2265
+ # call-seq: to_a
2266
+ #
2267
+ # Returns its elements as a new Array.
2268
+ #
2269
+ def to_a
2270
+ return @e
2271
+ end
2272
+
2273
+ #
2274
+ # call-seq: coerse(other)
2275
+ #
2276
+ # Resolves type mismatch.
2277
+ #
2278
+ def coerce( arg )
2279
+ case arg
2280
+ when Fixnum, Float, Bignum
2281
+ return [ self, arg ]
2282
+ else
2283
+ raise TypeError, "RQuat#coerce : #{arg.self} can't be coerced into #{self.class}."
2284
+ return nil
2285
+ end
2286
+ end
2287
+
2288
+ #
2289
+ # call-seq: setElements( e0, e1, e2, e3 )
2290
+ #
2291
+ # Stores given 4 new values.
2292
+ #
2293
+ def setElements( x, y, z, w )
2294
+ self.x = x
2295
+ self.y = y
2296
+ self.z = z
2297
+ self.w = w
2298
+ end
2299
+
2300
+ #
2301
+ # call-seq: quat[i]= value
2302
+ #
2303
+ # Stores +value+ at +i+.
2304
+ #
2305
+ def []=(i,value)
2306
+ @e[i] = value
2307
+ end
2308
+
2309
+ #
2310
+ # call-seq: x= value
2311
+ #
2312
+ # Stores +value+ as +x+.
2313
+ #
2314
+ def x=(value) @e[0] = value end
2315
+
2316
+ #
2317
+ # call-seq: y= value
2318
+ #
2319
+ # Stores +value+ as +y+.
2320
+ #
2321
+ def y=(value) @e[1] = value end
2322
+
2323
+ #
2324
+ # call-seq: z= value
2325
+ #
2326
+ # Stores +value+ as +z+.
2327
+ #
2328
+ def z=(value) @e[2] = value end
1798
2329
 
1799
2330
  #
1800
2331
  # call-seq: w= value
1801
2332
  #
1802
- # Stores +value+ as +w+.
2333
+ # Stores +value+ as +w+.
2334
+ #
2335
+ def w=(value) @e[3] = value end
2336
+
2337
+ #
2338
+ # call-seq: xyz= vXYZ
2339
+ #
2340
+ # Copies the values of +vXYZ+(RVec3) into +x+, +y+ and +z+.
2341
+ #
2342
+ def xyz=( arg )
2343
+ if arg.class != RVec3
2344
+ raise TypeError, "RQuat#xyz= : Unknown type #{arg.class}."
2345
+ return nil
2346
+ end
2347
+ @e[0] = arg.x
2348
+ @e[1] = arg.y
2349
+ @e[2] = arg.z
2350
+ end
2351
+
2352
+ #
2353
+ # call-seq: quat[i] -> value
2354
+ #
2355
+ # Returns the element at +i+.
2356
+ #
2357
+ def [](i)
2358
+ @e[i]
2359
+ end
2360
+
2361
+
2362
+ #
2363
+ # call-seq: x -> value
2364
+ #
2365
+ # Returns the value of +x+.
2366
+ #
2367
+ def x() return @e[0] end
2368
+
2369
+ #
2370
+ # call-seq: y -> value
2371
+ #
2372
+ # Returns the value of +y+.
2373
+ #
2374
+ def y() return @e[1] end
2375
+
2376
+ #
2377
+ # call-seq: z -> value
2378
+ #
2379
+ # Returns the value of +z+.
2380
+ #
2381
+ def z() return @e[2] end
2382
+
2383
+ #
2384
+ # call-seq: w -> value
2385
+ #
2386
+ # Returns the value of +w+.
2387
+ #
2388
+ def w() return @e[3] end
2389
+
2390
+ #
2391
+ # call-seq: xyz -> RVec3
2392
+ #
2393
+ # Returns the values of +x+, +y+ and +z+ with new RVec3(+x+,+y+,+z+).
2394
+ #
2395
+ def xyz()
2396
+ return RVec3.new( @e[0], @e[1], @e[2] )
2397
+ end
2398
+
2399
+ #
2400
+ # call-seq: getLength
2401
+ #
2402
+ # Returns the Euclidean length.
2403
+ #
2404
+ def getLength
2405
+ return Math.sqrt( @e[0]*@e[0] + @e[1]*@e[1] + @e[2]*@e[2] + @e[3]*@e[3] )
2406
+ end
2407
+
2408
+ #
2409
+ # call-seq: getLengthSq
2410
+ #
2411
+ # Returns the squared Euclidean length.
2412
+ #
2413
+ def getLengthSq
2414
+ return (@e[0]*@e[0] + @e[1]*@e[1] + @e[2]*@e[2] + @e[3]*@e[3]).to_f
2415
+ end
2416
+
2417
+ #
2418
+ # call-seq: RQuat.dot(q_a,q_b) -> value
2419
+ #
2420
+ # Calculates the dot product of +q_a+ and +q_b+.
2421
+ #
2422
+ def RQuat.dot( q1, q2 )
2423
+ if q1.class != RQuat || q2.class != RQuat
2424
+ raise TypeError, "RQuat#dot : Unknown type q1:#{q2.class}, q2:#{q2.class}."
2425
+ return nil
2426
+ end
2427
+ return q1.x*q2.x + q1.y*q2.y + q1.z*q2.z + q1.w*q2.w
2428
+ end
2429
+
2430
+ #
2431
+ # call-seq: RQuat.slerp( q_a, q_b, t ) -> interpolated quaternion
2432
+ #
2433
+ # Calculates the spherical linear interpolation between +q_a+ and
2434
+ # +q_b+ at time +t+ (0.0~1.0).
2435
+ #
2436
+ def RQuat.slerp( q1, q2, t )
2437
+ if q1.class != RQuat || q2.class != RQuat
2438
+ raise TypeError, "RQuat#slerp : Unknown type q1:#{q2.class}, q2:#{q2.class}."
2439
+ return nil
2440
+ end
2441
+ s1 = 0.0
2442
+ s2 = 0.0
2443
+ it = 1.0 - t
2444
+ cosine = RQuat.dot( q1, q2 )
2445
+
2446
+ qn1 = q1
2447
+ qn2 = q2
2448
+
2449
+ if ( cosine < 0.0 )
2450
+ cosine *= -1.0
2451
+ qn1 *= -1.0
2452
+ end
2453
+
2454
+ if ( (1.0 - cosine) > TOLERANCE )
2455
+ theta = Math.acos( cosine )
2456
+ sin_theta = Math.sin( theta )
2457
+
2458
+ s1 = Math.sin( it * theta ) / sin_theta
2459
+ s2 = Math.sin( t * theta ) / sin_theta
2460
+ else
2461
+ s1 = it
2462
+ s2 = t
2463
+ end
2464
+
2465
+ qn1 *= s1
2466
+ qn2 *= s2
2467
+ qResult = qn1 + qn2
2468
+
2469
+ return qResult
2470
+ end
2471
+
2472
+ #
2473
+ # call-seq: setIdentity
2474
+ #
2475
+ # Sets as identity quaternion.
2476
+ #
2477
+ def setIdentity
2478
+ self.x = 0.0
2479
+ self.y = 0.0
2480
+ self.z = 0.0
2481
+ self.w = 1.0
2482
+ return self
2483
+ end
2484
+
2485
+ #
2486
+ # call-seq: getConjugated
2487
+ #
2488
+ # Returns its conjugate quaternion.
2489
+ #
2490
+ def getConjugated
2491
+ return RQuat.new( -@e[0], -@e[1], -@e[2], @e[3] )
2492
+ end
2493
+
2494
+ #
2495
+ # call-seq: conjugate!
2496
+ #
2497
+ # Conjugates itself.
2498
+ #
2499
+ def conjugate!
2500
+ @e[0] *= -1.0
2501
+ @e[1] *= -1.0
2502
+ @e[2] *= -1.0
2503
+ return self
2504
+ end
2505
+
2506
+ #
2507
+ # call-seq: getInverse -> inverse quaternion
2508
+ #
2509
+ # Returns the inverse.
2510
+ #
2511
+ def getInverse
2512
+ length_sq = getLengthSq()
2513
+ return RQuat.new( -@e[0]/length_sq, -@e[1]/length_sq, -@e[2]/length_sq, @e[3]/length_sq )
2514
+ end
2515
+
2516
+ #
2517
+ # call-seq: invert! -> self
2518
+ #
2519
+ # Inverts itself.
2520
+ #
2521
+ def invert!
2522
+ length_sq = getLengthSq()
2523
+ @e[0] /= -length_sq
2524
+ @e[1] /= -length_sq
2525
+ @e[2] /= -length_sq
2526
+ @e[3] /= length_sq
2527
+ return self
2528
+ end
2529
+
2530
+ #
2531
+ # call-seq: getNormalized -> RQuat
2532
+ #
2533
+ # Returns normalized quaternion.
2534
+ #
2535
+ def getNormalized
2536
+ length = getLength()
2537
+ return RQuat.new( @e[0]/length, @e[1]/length, @e[2]/length, @e[3]/length )
2538
+ end
2539
+
2540
+ #
2541
+ # call-seq: normalize! -> self
2542
+ #
2543
+ # Normalizes itself.
2544
+ #
2545
+ def normalize!
2546
+ length = getLength()
2547
+ @e[0] /= length
2548
+ @e[1] /= length
2549
+ @e[2] /= length
2550
+ @e[3] /= length
2551
+ return self
2552
+ end
2553
+
2554
+ #
2555
+ # call-seq: +
2556
+ #
2557
+ # +quat : Unary plus operator.
2558
+ #
2559
+ def +@
2560
+ return self
2561
+ end
2562
+
2563
+ #
2564
+ # call-seq: -
2565
+ #
2566
+ # -quat : Unary minus operator.
2567
+ #
2568
+ def -@
2569
+ return RQuat.new( -@e[0], -@e[1], -@e[2], -@e[3] )
2570
+ end
2571
+
2572
+ #
2573
+ # call-seq: +
2574
+ #
2575
+ # quat1 + quat2 : Binary plus operator.
2576
+ #
2577
+ def +( arg )
2578
+ if arg.class != RQuat
2579
+ raise TypeError, "RQuat#+ : Unknown type #{arg.class}."
2580
+ return nil
2581
+ end
2582
+ RQuat.new( x+arg.x, y+arg.y, z+arg.z, w+arg.w )
2583
+ end
2584
+
2585
+ #
2586
+ # call-seq: -
2587
+ #
2588
+ # quat1 - quat2 : Binary minus operator.
2589
+ #
2590
+ def -( arg )
2591
+ if arg.class != RQuat
2592
+ raise TypeError, "RQuat#- : Unknown type #{arg.class}."
2593
+ return nil
2594
+ end
2595
+ RQuat.new( x-arg.x, y-arg.y, z-arg.z, w-arg.w )
2596
+ end
2597
+
2598
+ #
2599
+ # call-seq: *
2600
+ #
2601
+ # quat1 * quat2 : Binary multiply operator.
2602
+ #
2603
+ def *( arg )
2604
+ case arg
2605
+ when RQuat
2606
+ q1x = self.x
2607
+ q1y = self.y
2608
+ q1z = self.z
2609
+ q1w = self.w
2610
+ q2x = arg.x
2611
+ q2y = arg.y
2612
+ q2z = arg.z
2613
+ q2w = arg.w
2614
+ x = q1w*q2x + q1x*q2w + q1y*q2z - q1z*q2y
2615
+ y = q1w*q2y - q1x*q2z + q1y*q2w + q1z*q2x
2616
+ z = q1w*q2z + q1x*q2y - q1y*q2x + q1z*q2w
2617
+ w = q1w*q2w - q1x*q2x - q1y*q2y - q1z*q2z
2618
+ return RQuat.new( x, y, z, w )
2619
+ when Fixnum, Float
2620
+ return RQuat.new( @e[0]*arg, @e[1]*arg, @e[2]*arg, @e[3]*arg )
2621
+ else
2622
+ raise TypeError, "RQuat#* : Unknown type #{arg}."
2623
+ return nil
2624
+ end
2625
+ end
2626
+
2627
+ #
2628
+ # call-seq: ==
2629
+ #
2630
+ # quat1 == quat2 : evaluates equality.
2631
+ #
2632
+ def ==( other )
2633
+ if other.class != RQuat
2634
+ raise TypeError, "RQuat#== : Unknown type #{other.class}."
2635
+ return nil
2636
+ end
2637
+
2638
+ if (x-other.x).abs<=Float::EPSILON &&
2639
+ (y-other.y).abs<=Float::EPSILON &&
2640
+ (z-other.z).abs<=Float::EPSILON &&
2641
+ (w-other.w).abs<=Float::EPSILON
2642
+ return true
2643
+ else
2644
+ return false
2645
+ end
2646
+ end
2647
+
2648
+ #
2649
+ # call-seq: quat1.add!( quat2 )
2650
+ #
2651
+ # quat1 += quat2 : appends the elements of +quat2+ into corresponding +quat1+ elements.
2652
+ #
2653
+ def add!( other )
2654
+ if other.class != RQuat
2655
+ raise TypeError, "RQ#add! : Unknown type #{other.class}."
2656
+ return nil
2657
+ end
2658
+
2659
+ self.x += other.x
2660
+ self.y += other.y
2661
+ self.z += other.z
2662
+ self.w += other.w
2663
+
2664
+ return self
2665
+ end
2666
+
2667
+ #
2668
+ # call-seq: quat1.sub!( quat2 )
2669
+ #
2670
+ # quat1 -= quat2 : subtracts the elements of +quat2+ from corresponding +quat1+ elements.
1803
2671
  #
1804
- def w=(value) @e[3] = value end
2672
+ def sub!( other )
2673
+ if other.class != RQuat
2674
+ raise TypeError, "RQuat#sub! : Unknown type #{other.class}."
2675
+ return nil
2676
+ end
2677
+
2678
+ self.x -= other.x
2679
+ self.y -= other.y
2680
+ self.z -= other.z
2681
+ self.w -= other.w
2682
+
2683
+ return self
2684
+ end
1805
2685
 
1806
2686
  #
1807
- # call-seq: xyz= vXYZ
2687
+ # call-seq: quat1.mul!( quat2 )
1808
2688
  #
1809
- # Copies the values of +vXYZ+(RVec3) into +x+, +y+ and +z+.
2689
+ # quat1 *= quat2
1810
2690
  #
1811
- def xyz=( arg )
1812
- if arg.class != RVec3
1813
- raise TypeError, "RQuat#xyz= : Unknown type #{arg.class}."
2691
+ def mul!( other )
2692
+ case other
2693
+ when RQuat
2694
+ q1x = self.x
2695
+ q1y = self.y
2696
+ q1z = self.z
2697
+ q1w = self.w
2698
+ q2x = other.x
2699
+ q2y = other.y
2700
+ q2z = other.z
2701
+ q2w = other.w
2702
+
2703
+ x = q1w*q2x + q1x*q2w + q1y*q2z - q1z*q2y
2704
+ y = q1w*q2y - q1x*q2z + q1y*q2w + q1z*q2x
2705
+ z = q1w*q2z + q1x*q2y - q1y*q2x + q1z*q2w
2706
+ w = q1w*q2w - q1x*q2x - q1y*q2y - q1z*q2z
2707
+
2708
+ self.x = x
2709
+ self.y = y
2710
+ self.z = z
2711
+ self.w = w
2712
+
2713
+ return self
2714
+
2715
+ when Fixnum, Float
2716
+ self.x *= other
2717
+ self.y *= other
2718
+ self.z *= other
2719
+ self.w *= other
2720
+ return self
2721
+
2722
+ else
2723
+ raise TypeError, "RQuat#mul! : Unknown type #{other.class}."
1814
2724
  return nil
1815
2725
  end
1816
- @e[0] = arg.x
1817
- @e[1] = arg.y
1818
- @e[2] = arg.z
1819
2726
  end
1820
2727
 
1821
2728
  #
1822
- # call-seq: quat[i] -> value
2729
+ # call-seq: rotationMarix(mtx4) -> self
1823
2730
  #
1824
- # Returns the element at +i+.
2731
+ # Makes a rotation quaternion from a rotation matrix +mtx4+ (RMtx4).
1825
2732
  #
1826
- def [](i)
1827
- @e[i]
1828
- end
2733
+ def rotationMatrix( mtx )
2734
+ if mtx.class != RMtx3 && mtx.class != RMtx4
2735
+ raise TypeError, "RQuat#rotationMatrix : Unknown type #{mtx.class}."
2736
+ return nil
2737
+ end
2738
+
2739
+ diag00 = mtx.getElement(0,0)
2740
+ diag11 = mtx.getElement(1,1)
2741
+ diag22 = mtx.getElement(2,2)
2742
+
2743
+ if ( diag00 + diag11 + diag22 > 0.0 )
2744
+ t = diag00 + diag11 + diag22 + 1.0
2745
+ s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2746
+ self.w = s * t
2747
+ self.z = (mtx.getElement(1,0) - mtx.getElement(0,1)) * s
2748
+ self.y = (mtx.getElement(0,2) - mtx.getElement(2,0)) * s
2749
+ self.x = (mtx.getElement(2,1) - mtx.getElement(1,2)) * s
2750
+ elsif ( diag00 > diag11 && diag00 > diag22 )
2751
+ t = diag00 - diag11 - diag22 + 1.0
2752
+ s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2753
+ self.x = s * t
2754
+ self.y = (mtx.getElement(1,0) + mtx.getElement(0,1)) * s
2755
+ self.z = (mtx.getElement(0,2) + mtx.getElement(2,0)) * s
2756
+ self.w = (mtx.getElement(2,1) - mtx.getElement(1,2)) * s
2757
+ elsif ( diag11 > diag22 )
2758
+ t = -diag00 + diag11 - diag22 + 1.0
2759
+ s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2760
+ self.y = s * t
2761
+ self.x = (mtx.getElement(1,0) + mtx.getElement(0,1)) * s
2762
+ self.w = (mtx.getElement(0,2) - mtx.getElement(2,0)) * s
2763
+ self.z = (mtx.getElement(2,1) + mtx.getElement(1,2)) * s
2764
+ else
2765
+ t = -diag00 - diag11 + diag22 + 1.0
2766
+ s = 1.0 / ( Math.sqrt( t ) * 2.0 )
2767
+ self.z = s * t
2768
+ self.w = (mtx.getElement(1,0) - mtx.getElement(0,1)) * s
2769
+ self.x = (mtx.getElement(0,2) + mtx.getElement(2,0)) * s
2770
+ self.y = (mtx.getElement(2,1) + mtx.getElement(1,2)) * s
2771
+ end
1829
2772
 
2773
+ return self
2774
+ end
1830
2775
 
1831
2776
  #
1832
- # call-seq: x -> value
2777
+ # call-seq: rotationAxis(axis,radian) -> self
1833
2778
  #
1834
- # Returns the value of +x+.
2779
+ # Makes a quaternion that rotates around the +axis+.
1835
2780
  #
1836
- def x() return @e[0] end
2781
+ def rotationAxis( axis, radian )
2782
+ if axis.class != RVec3
2783
+ raise TypeError, "RQuat#rotationAxis : Unknown type #{axis.class}."
2784
+ return nil
2785
+ end
2786
+
2787
+ s = Math.sin( radian / 2.0 )
2788
+ self.x = s * axis.x
2789
+ self.y = s * axis.y
2790
+ self.z = s * axis.z
2791
+ self.w = Math.cos( radian / 2.0 )
2792
+
2793
+ return self
2794
+ end
1837
2795
 
1838
2796
  #
1839
- # call-seq: y -> value
2797
+ # call-seq: toAxisAngle -> [axis,radian]
1840
2798
  #
1841
- # Returns the value of +y+.
2799
+ # Returns its rotation axis (RVec3) and rotation angle (in radian).
1842
2800
  #
1843
- def y() return @e[1] end
2801
+ def toAxisAngle
2802
+ axis = RVec3.new( self.x, self.y, self.z ).normalize!
2803
+ radian = 2.0 * Math.acos( self.w )
2804
+
2805
+ return [ axis, radian ]
2806
+ end
2807
+ end
2808
+
2809
+ #
2810
+ # Document-class: RMath3D::RVec2
2811
+ # provies 2 element vector arithmetic.
2812
+ #
2813
+ class RVec2
1844
2814
 
1845
2815
  #
1846
- # call-seq: z -> value
2816
+ # call-seq:
2817
+ # RVec2.new -> (0,0)
2818
+ # RVec2.new(e) -> (e,e)
2819
+ # RVec2.new( other ) : Copy Constructor
2820
+ # RVec2.new( e0, e1 ) -> (e0,e1)
1847
2821
  #
1848
- # Returns the value of +z+.
2822
+ # Creates a new 3 element vector.
1849
2823
  #
1850
- def z() return @e[2] end
2824
+ def initialize( *a )
2825
+ @e = []
2826
+ case a.length
2827
+ when 0
2828
+ @e = [0.0, 0.0]
2829
+ when 1
2830
+ case a[0]
2831
+ when Fixnum, Float
2832
+ @e = [ a[0], a[0] ]
2833
+ when RVec2
2834
+ @e = [ a[0].x, a[0].y ]
2835
+ else
2836
+ raise TypeError, "RVec2#initialize : Unknown type #{a[0].class}."
2837
+ return nil
2838
+ end
2839
+ when 2
2840
+ a.each_with_index do |elem, index|
2841
+ case elem
2842
+ when Fixnum, Float
2843
+ @e[index] = elem
2844
+ else
2845
+ raise TypeError, "RVec2#initialize : Unknown type #{elem.class}."
2846
+ return nil
2847
+ end
2848
+ end
2849
+ else
2850
+ raise RuntimeError, "RVec2#initialize : wrong # of arguments (#{a.length})"
2851
+ return nil
2852
+ end
2853
+ return self
2854
+ end
1851
2855
 
1852
2856
  #
1853
- # call-seq: w -> value
2857
+ # call-seq: to_s
1854
2858
  #
1855
- # Returns the value of +w+.
2859
+ # Returns human-readable string.
1856
2860
  #
1857
- def w() return @e[3] end
2861
+ def to_s
2862
+ return "( #{@e[0]}, #{@e[1]} )\n"
2863
+ end
1858
2864
 
1859
2865
  #
1860
- # call-seq: xyz -> RVec3
2866
+ # call-seq: to_a
1861
2867
  #
1862
- # Returns the values of +x+, +y+ and +z+ with new RVec3(+x+,+y+,+z+).
2868
+ # Returns its elements as a new Array.
1863
2869
  #
1864
- def xyz()
1865
- return RVec3.new( @e[0], @e[1], @e[2] )
2870
+ def to_a
2871
+ return @e
1866
2872
  end
1867
2873
 
1868
2874
  #
1869
- # call-seq: getLength
2875
+ # call-seq: coerse(other)
1870
2876
  #
1871
- # Returns the Euclidean length.
2877
+ # Resolves type mismatch.
1872
2878
  #
1873
- def getLength
1874
- return Math.sqrt( @e[0]*@e[0] + @e[1]*@e[1] + @e[2]*@e[2] + @e[3]*@e[3] )
2879
+ def coerce( arg )
2880
+ case arg
2881
+ when Fixnum, Float, Bignum
2882
+ return [ self, arg ]
2883
+ else
2884
+ raise TypeError, "RVec2#coerce : #{arg.self} can't be coerced into #{self.class}."
2885
+ return nil
2886
+ end
1875
2887
  end
1876
2888
 
1877
2889
  #
1878
- # call-seq: getLengthSq
2890
+ # call-seq: setElements( e0, e1 )
1879
2891
  #
1880
- # Returns the squared Euclidean length.
2892
+ # Stores given 2 new values.
1881
2893
  #
1882
- def getLengthSq
1883
- return (@e[0]*@e[0] + @e[1]*@e[1] + @e[2]*@e[2] + @e[3]*@e[3]).to_f
2894
+ def setElements( x, y )
2895
+ self.x = x
2896
+ self.y = y
1884
2897
  end
1885
2898
 
1886
2899
  #
1887
- # call-seq: RQuat.dot(q_a,q_b) -> value
2900
+ # call-seq: vec2[i]= value
1888
2901
  #
1889
- # Calculates the dot product of +q_a+ and +q_b+.
2902
+ # Stores +value+ at +i+.
1890
2903
  #
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
2904
+ def []=(i,value)
2905
+ @e[i] = value
1897
2906
  end
1898
2907
 
1899
2908
  #
1900
- # call-seq: RQuat.slerp( q_a, q_b, t ) -> interpolated quaternion
2909
+ # call-seq: x= value
1901
2910
  #
1902
- # Calculates the spherical linear interpolation between +q_a+ and
1903
- # +q_b+ at time +t+ (0.0~1.0).
2911
+ # Stores +value+ as +x+.
1904
2912
  #
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
1922
-
1923
- if ( (1.0 - cosine) > TOLERANCE )
1924
- theta = Math.acos( cosine )
1925
- sin_theta = Math.sin( theta )
1926
-
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
2913
+ def x=(value) @e[0] = value end
1933
2914
 
1934
- qn1 *= s1
1935
- qn2 *= s2
1936
- qResult = qn1 + qn2
2915
+ #
2916
+ # call-seq: y= value
2917
+ #
2918
+ # Stores +value+ as +y+.
2919
+ #
2920
+ def y=(value) @e[1] = value end
1937
2921
 
1938
- return qResult
2922
+ #
2923
+ # call-seq: vec3[i] -> value
2924
+ #
2925
+ # Returns the element at +i+.
2926
+ #
2927
+ def [](i)
2928
+ @e[i]
1939
2929
  end
1940
2930
 
1941
2931
  #
1942
- # call-seq: setIdentity
2932
+ # call-seq: x -> value
1943
2933
  #
1944
- # Sets as identity quaternion.
2934
+ # Returns the value of +x+.
1945
2935
  #
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
2936
+ def x() return @e[0] end
2937
+
2938
+ #
2939
+ # call-seq: y -> value
2940
+ #
2941
+ # Returns the value of +y+.
2942
+ #
2943
+ def y() return @e[1] end
2944
+
2945
+ #
2946
+ # call-seq: getLength
2947
+ #
2948
+ # Returns the Euclidean length.
2949
+ #
2950
+ def getLength
2951
+ return Math.sqrt( @e[0]*@e[0] + @e[1]*@e[1] )
1952
2952
  end
1953
2953
 
1954
2954
  #
1955
- # call-seq: getConjugated
2955
+ # call-seq: getLengthSq
1956
2956
  #
1957
- # Returns its conjugate quaternion.
2957
+ # Returns the squared Euclidean length.
1958
2958
  #
1959
- def getConjugated
1960
- return RQuat.new( -@e[0], -@e[1], -@e[2], @e[3] )
2959
+ def getLengthSq
2960
+ return (@e[0]*@e[0] + @e[1]*@e[1]).to_f
1961
2961
  end
1962
2962
 
1963
2963
  #
1964
- # call-seq: conjugate!
2964
+ # call-seq: RVec2.dot(v_a,v_b) -> value
1965
2965
  #
1966
- # Conjugates itself.
2966
+ # Calculates the dot product of +v_a+ and +v_b+.
1967
2967
  #
1968
- def conjugate!
1969
- @e[0] *= -1.0
1970
- @e[1] *= -1.0
1971
- @e[2] *= -1.0
1972
- return self
2968
+ def RVec2.dot( v1, v2 )
2969
+ return v1.x*v2.x + v1.y*v2.y
1973
2970
  end
1974
2971
 
1975
2972
  #
1976
- # call-seq: getInverse -> inverse quaternion
2973
+ # call-seq: RVec2.cross(v_a,v_b) -> value
1977
2974
  #
1978
- # Returns the inverse.
2975
+ # Calculates the cross product of +v_a+ and +v_b+.
1979
2976
  #
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 )
2977
+ def RVec2.cross( v1, v2 )
2978
+ return v1.x*v2.y - v1.y*v2.x
1983
2979
  end
1984
2980
 
1985
2981
  #
1986
- # call-seq: invert! -> self
2982
+ # call-seq: transform(mtx2) -> transformed RVec2
1987
2983
  #
1988
- # Inverts itself.
2984
+ # Returns new RVec2 containing the result of the transformation of
2985
+ # RVec2(self.x,self.y) by +mtx2+ (RMtx2).
1989
2986
  #
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
2987
+ def transform( mtx2 )
2988
+ result = RVec2.new
2989
+ result.x = mtx2.e00 * self[0] + mtx2.e01 * self[1]
2990
+ result.y = mtx2.e10 * self[0] + mtx2.e11 * self[1]
2991
+
2992
+ return result
1997
2993
  end
1998
2994
 
1999
2995
  #
2000
- # call-seq: getNormalized -> RQuat
2996
+ # call-seq: getNormalized -> RVec2
2001
2997
  #
2002
- # Returns normalized quaternion.
2998
+ # Returns normalized vector.
2003
2999
  #
2004
3000
  def getNormalized
2005
- length = getLength()
2006
- return RQuat.new( @e[0]/length, @e[1]/length, @e[2]/length, @e[3]/length )
3001
+ l = getLength()
3002
+ l = 1.0/l
3003
+ return RVec2.new( @e[0]*l, @e[1]*l )
2007
3004
  end
2008
3005
 
2009
3006
  #
@@ -2012,18 +3009,17 @@ module RMath3D
2012
3009
  # Normalizes itself.
2013
3010
  #
2014
3011
  def normalize!
2015
- length = getLength()
2016
- @e[0] /= length
2017
- @e[1] /= length
2018
- @e[2] /= length
2019
- @e[3] /= length
3012
+ l = getLength()
3013
+ l = 1.0/l
3014
+ @e[0] *= l
3015
+ @e[1] *= l
2020
3016
  return self
2021
3017
  end
2022
3018
 
2023
3019
  #
2024
3020
  # call-seq: +
2025
3021
  #
2026
- # +quat : Unary plus operator.
3022
+ # +vec : Unary plus operator.
2027
3023
  #
2028
3024
  def +@
2029
3025
  return self
@@ -2032,63 +3028,49 @@ module RMath3D
2032
3028
  #
2033
3029
  # call-seq: -
2034
3030
  #
2035
- # -quat : Unary minus operator.
3031
+ # -vec : Unary minus operator.
2036
3032
  #
2037
3033
  def -@
2038
- return RQuat.new( -@e[0], -@e[1], -@e[2], -@e[3] )
3034
+ return RVec2.new( -@e[0], -@e[1] )
2039
3035
  end
2040
3036
 
2041
3037
  #
2042
3038
  # call-seq: +
2043
3039
  #
2044
- # quat1 + quat2 : Binary plus operator.
3040
+ # vec1 + vec2 : Binary plus operator.
2045
3041
  #
2046
3042
  def +( arg )
2047
- if arg.class != RQuat
2048
- raise TypeError, "RQuat#+ : Unknown type #{arg.class}."
3043
+ if arg.class != RVec2
3044
+ raise TypeError, "RVec2#+ : Unknown type #{arg.class}."
2049
3045
  return nil
2050
3046
  end
2051
- RQuat.new( x+arg.x, y+arg.y, z+arg.z, w+arg.w )
3047
+ RVec2.new( x+arg.x, y+arg.y )
2052
3048
  end
2053
3049
 
2054
3050
  #
2055
3051
  # call-seq: -
2056
3052
  #
2057
- # quat1 - quat2 : Binary minus operator.
3053
+ # vec1 - vec2 : Binary minus operator.
2058
3054
  #
2059
3055
  def -( arg )
2060
- if arg.class != RQuat
2061
- raise TypeError, "RQuat#- : Unknown type #{arg.class}."
3056
+ if arg.class != RVec2
3057
+ raise TypeError, "RVec2#- : Unknown type #{arg.class}."
2062
3058
  return nil
2063
3059
  end
2064
- RQuat.new( x-arg.x, y-arg.y, z-arg.z, w-arg.w )
3060
+ RVec2.new( x-arg.x, y-arg.y )
2065
3061
  end
2066
3062
 
2067
3063
  #
2068
3064
  # call-seq: *
2069
3065
  #
2070
- # quat1 * quat2 : Binary multiply operator.
3066
+ # vec1 * vec2 : Binary multiply operator.
2071
3067
  #
2072
3068
  def *( arg )
2073
3069
  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
3070
  when Fixnum, Float
2089
- return RQuat.new( @e[0]*arg, @e[1]*arg, @e[2]*arg, @e[3]*arg )
3071
+ return RVec2.new( @e[0]*arg, @e[1]*arg )
2090
3072
  else
2091
- raise TypeError, "RQuat#* : Unknown type #{arg}."
3073
+ raise TypeError, "RVec2#* : Unknown type #{arg}."
2092
3074
  return nil
2093
3075
  end
2094
3076
  end
@@ -2096,18 +3078,16 @@ module RMath3D
2096
3078
  #
2097
3079
  # call-seq: ==
2098
3080
  #
2099
- # quat1 == quat2 : evaluates equality.
3081
+ # vec1 == vec2 : evaluates equality.
2100
3082
  #
2101
3083
  def ==( other )
2102
- if other.class != RQuat
2103
- raise TypeError, "RQuat#== : Unknown type #{other.class}."
3084
+ if other.class != RVec2
3085
+ raise TypeError, "RVec2#== : Unknown type #{other.class}."
2104
3086
  return nil
2105
3087
  end
2106
3088
 
2107
3089
  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
3090
+ (y-other.y).abs<=Float::EPSILON
2111
3091
  return true
2112
3092
  else
2113
3093
  return false
@@ -2115,164 +3095,55 @@ module RMath3D
2115
3095
  end
2116
3096
 
2117
3097
  #
2118
- # call-seq: quat1.add!( quat2 )
3098
+ # call-seq: vec1.add!( vec2 )
2119
3099
  #
2120
- # quat1 += quat2 : appends the elements of +quat2+ into corresponding +quat1+ elements.
3100
+ # vec1 += vec2 : appends the elements of +vec2+ into corresponding +vec1+ elements.
2121
3101
  #
2122
3102
  def add!( other )
2123
- if other.class != RQuat
2124
- raise TypeError, "RQ#add! : Unknown type #{other.class}."
3103
+ if other.class != RVec2
3104
+ raise TypeError, "RVec2#add! : Unknown type #{other.class}."
2125
3105
  return nil
2126
3106
  end
2127
3107
 
2128
3108
  self.x += other.x
2129
3109
  self.y += other.y
2130
- self.z += other.z
2131
- self.w += other.w
2132
3110
 
2133
3111
  return self
2134
3112
  end
2135
3113
 
2136
3114
  #
2137
- # call-seq: quat1.sub!( quat2 )
3115
+ # call-seq: vec1.sub!( vec2 )
2138
3116
  #
2139
- # quat1 -= quat2 : subtracts the elements of +quat2+ from corresponding +quat1+ elements.
3117
+ # vec1 -= vec2 : subtracts the elements of +vec2+ from corresponding +vec1+ elements.
2140
3118
  #
2141
3119
  def sub!( other )
2142
- if other.class != RQuat
2143
- raise TypeError, "RQuat#sub! : Unknown type #{other.class}."
3120
+ if other.class != RVec2
3121
+ raise TypeError, "RVec2#sub! : Unknown type #{other.class}."
2144
3122
  return nil
2145
3123
  end
2146
3124
 
2147
3125
  self.x -= other.x
2148
3126
  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
3127
 
2242
3128
  return self
2243
3129
  end
2244
3130
 
2245
3131
  #
2246
- # call-seq: rotationAxis(axis,radian) -> self
3132
+ # call-seq: vec1.mul!( vec2 )
2247
3133
  #
2248
- # Makes a quaternion that rotates around the +axis+.
3134
+ # vec1 *= vec2
2249
3135
  #
2250
- def rotationAxis( axis, radian )
2251
- if axis.class != RVec3
2252
- raise TypeError, "RQuat#rotationAxis : Unknown type #{axis.class}."
3136
+ def mul!( arg )
3137
+ if arg.class != Fixnum && arg.class != Float
3138
+ raise TypeError, "RVec2#mul! : Unknown type #{arg.class}."
2253
3139
  return nil
2254
3140
  end
2255
3141
 
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 )
3142
+ self.x *= arg
3143
+ self.y *= arg
2261
3144
 
2262
3145
  return self
2263
3146
  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
3147
  end
2277
3148
 
2278
3149
  #