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