rmath3d_plain 1.0.2 → 1.2.3

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