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