rmath3d 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,174 @@
1
+ # require 'rmath3d/rmath3d_plain'
2
+ require 'rmath3d/rmath3d'
3
+ include RMath3D
4
+
5
+ require 'glfw'
6
+ require 'opengl'
7
+
8
+ include GLFW
9
+ include OpenGL
10
+
11
+ case OpenGL.get_platform
12
+ when :OPENGL_PLATFORM_WINDOWS
13
+ OpenGL.load_dll('opengl32.dll', 'C:/Windows/System32')
14
+ GLFW.load_dll('glfw3.dll', '.')
15
+ when :OPENGL_PLATFORM_MACOSX
16
+ OpenGL.load_dll('libGL.dylib', '/System/Library/Frameworks/OpenGL.framework/Libraries')
17
+ GLFW.load_dll('libglfw.dylib', '.')
18
+ else
19
+ raise RuntimeError, "Unsupported platform."
20
+ end
21
+
22
+
23
+ def drawCube
24
+ size = 1.0
25
+ scale = 0.2
26
+ delta = 0.1
27
+
28
+ v = [
29
+ [ size, size, size * scale + delta ],
30
+ [ size, size, -size * scale + delta ],
31
+ [ size, -size, -size * scale ],
32
+ [ size, -size, size * scale ],
33
+ [-size, size, size * scale + delta ],
34
+ [-size, size, -size * scale + delta ],
35
+ [-size, -size, -size * scale ],
36
+ [-size, -size, size * scale ]
37
+ ]
38
+
39
+ cube = [
40
+ [ [1,0,0], v[3],v[2],v[1],v[0] ], # normal, vertices
41
+ [ [-1,0,0], v[6],v[7],v[4],v[5] ],
42
+ [ [0,0,-1], v[2],v[6],v[5],v[1] ],
43
+ [ [0,0,1], v[7],v[3],v[0],v[4] ],
44
+ [ [0,1,0], v[4],v[0],v[1],v[5] ],
45
+ [ [0,-1,0], v[6],v[2],v[3],v[7] ]
46
+ ]
47
+
48
+ glBegin(GL_QUADS)
49
+ cube.each do |side|
50
+ glNormal3fv(side[0].pack('F*'))
51
+
52
+ glTexCoord2f(1,1)
53
+ glVertex3fv(side[1].pack('F*'))
54
+ glTexCoord2f(0,1)
55
+ glVertex3fv(side[2].pack('F*'))
56
+ glTexCoord2f(0,0)
57
+ glVertex3fv(side[3].pack('F*'))
58
+ glTexCoord2f(1,0)
59
+ glVertex3fv(side[4].pack('F*'))
60
+ end
61
+ glEnd()
62
+ end
63
+
64
+
65
+ class App
66
+
67
+ def draw
68
+ glPushAttrib( GL_ALL_ATTRIB_BITS )
69
+
70
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
71
+
72
+ glMatrixMode( GL_MODELVIEW )
73
+ glLoadMatrixf( @mtxLookAt.to_a.pack('F16') )
74
+
75
+ glLightfv( GL_LIGHT0, GL_POSITION, @light_pos.pack('F*') )
76
+ glLightfv( GL_LIGHT0, GL_DIFFUSE, @light_diffuse.pack('F*') )
77
+ glLightfv( GL_LIGHT0, GL_SPECULAR, @light_specular.pack('F*') )
78
+ glLightfv( GL_LIGHT0, GL_AMBIENT, @light_ambient.pack('F*') )
79
+
80
+ glPushMatrix()
81
+
82
+ @mtxTeapotRotY.rotationY( @teapot_rad_y )
83
+ glMultMatrixf( @mtxTeapotRotY.to_a.pack('F16') )
84
+ @teapot_rad_y += 2.0*Math::PI/60.0
85
+
86
+ glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, @teapot_diffuse.pack('F*') )
87
+ glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, @teapot_specular.pack('F*') )
88
+ glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, @teapot_ambient.pack('F*') )
89
+ glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, @teapot_shininess )
90
+ drawCube() # glutSolidTeapot( 2.0 )
91
+
92
+ glPopMatrix()
93
+
94
+ glPopAttrib()
95
+ end
96
+
97
+ def key_callback( window_handle, key, scancode, action, mods )
98
+ case key
99
+ when GLFW_KEY_ESCAPE, GLFW_KEY_Q
100
+ glfwSetWindowShouldClose(window_handle, 1)
101
+ end
102
+ end
103
+
104
+ def size_callback( window_handle, w, h )
105
+ glViewport( 0, 0, w, h )
106
+ glMatrixMode( GL_PROJECTION )
107
+ @mtxProj.perspectiveFovRH( 30.0*Math::PI/180.0, w.to_f/h.to_f, 0.1, 1000.0 )
108
+ glLoadMatrixf( @mtxProj.to_a.pack('F16') )
109
+
110
+ @window_width = w
111
+ @window_height = h
112
+ end
113
+
114
+ def initialize
115
+ @window_width = 320
116
+ @window_height = 240
117
+
118
+ @eye = RVec3.new(0.0, 15.0, 15.0)
119
+ @at = RVec3.new(0.0, 0.0, 0.0)
120
+ @up = RVec3.new(0.0, 1.0, 0.0)
121
+ @mtxLookAt = RMtx4.new.lookAtRH( @eye, @at, @up )
122
+ @mtxProj = RMtx4.new.perspectiveFovRH( 30.0*Math::PI/180.0, @window_width.to_f/@window_height.to_f, 0.1, 1000.0 )
123
+
124
+ @light_pos = [2.5,0,5,1]
125
+ @light_diffuse = [1,1,1,1]
126
+ @light_specular = [1,1,1,1]
127
+ @light_ambient = [1,1,1,1]
128
+
129
+ @teapot_diffuse = [0.8,1,0,1]
130
+ @teapot_specular = [1,1,1,1]
131
+ @teapot_ambient = [0.2,0.2,0,1]
132
+ @teapot_shininess = 32.0
133
+
134
+ @teapot_rad_y = 0.0
135
+ @mtxTeapotRotY = RMtx4.new.rotationY( @teapot_rad_y )
136
+
137
+ glfwInit()
138
+
139
+ @window_handle = glfwCreateWindow( @window_width, @window_height, self.class.to_s, nil, nil )
140
+ glfwMakeContextCurrent( @window_handle )
141
+ # glfwSetKeyCallback( $window_handle, $key_callback )
142
+ glfwSetKeyCallback( @window_handle, GLFW::create_callback(:GLFWkeyfun, method(:key_callback).to_proc) )
143
+ # glfwSetWindowSizeCallback( $window_handle, $size_callback )
144
+ glfwSetWindowSizeCallback( @window_handle, GLFW::create_callback(:GLFWwindowsizefun, method(:size_callback).to_proc ) )
145
+
146
+ width_ptr = ' '
147
+ height_ptr = ' '
148
+ glfwGetFramebufferSize(@window_handle, width_ptr, height_ptr)
149
+ width = width_ptr.unpack('L')[0]
150
+ height = height_ptr.unpack('L')[0]
151
+ size_callback( @window_handle, width, height )
152
+
153
+ # Common rendering state : reused by PushAttrib/PopAttrib
154
+ glEnable( GL_DEPTH_TEST )
155
+ glEnable( GL_LIGHTING )
156
+ glEnable( GL_LIGHT0 )
157
+ glEnable( GL_NORMALIZE )
158
+ glClearColor( 0.0, 0.0, 0.0, 1 )
159
+ end
160
+
161
+ def start
162
+ while glfwWindowShouldClose( @window_handle ) == 0
163
+ draw()
164
+ glfwSwapBuffers( @window_handle )
165
+ glfwPollEvents()
166
+ end
167
+
168
+ glfwDestroyWindow( @window_handle )
169
+ glfwTerminate()
170
+ end
171
+
172
+ end
173
+
174
+ App.new.start
@@ -0,0 +1,118 @@
1
+ # require 'rmath3d/rmath3d_plain'
2
+ require 'rmath3d/rmath3d'
3
+ include RMath3D
4
+
5
+ require 'opengl'
6
+
7
+ class App
8
+
9
+ def draw
10
+ glPushAttrib( GL_ALL_ATTRIB_BITS )
11
+
12
+ glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT )
13
+
14
+ glMatrixMode( GL_MODELVIEW )
15
+ glLoadMatrix( @mtxLookAt )
16
+
17
+ glLightfv( GL_LIGHT0, GL_POSITION, @light_pos )
18
+ glLightfv( GL_LIGHT0, GL_DIFFUSE, @light_diffuse )
19
+ glLightfv( GL_LIGHT0, GL_SPECULAR, @light_specular )
20
+ glLightfv( GL_LIGHT0, GL_AMBIENT, @light_ambient )
21
+
22
+ glPushMatrix()
23
+
24
+ @mtxTeapotRotY.rotationY( @teapot_rad_y )
25
+ glMultMatrix( @mtxTeapotRotY )
26
+ @teapot_rad_y += 2.0*Math::PI/60.0
27
+
28
+ glMaterialfv( GL_FRONT_AND_BACK, GL_DIFFUSE, @teapot_diffuse )
29
+ glMaterialfv( GL_FRONT_AND_BACK, GL_SPECULAR, @teapot_specular )
30
+ glMaterialfv( GL_FRONT_AND_BACK, GL_AMBIENT, @teapot_ambient )
31
+ glMaterialf( GL_FRONT_AND_BACK, GL_SHININESS, @teapot_shininess )
32
+ glutSolidTeapot( 2.0 )
33
+
34
+ glPopMatrix()
35
+
36
+ glPopAttrib()
37
+
38
+ glutSwapBuffers()
39
+ end
40
+
41
+
42
+ def reshape( width, height )
43
+ glViewport( 0, 0, width, height )
44
+ glMatrixMode( GL_PROJECTION )
45
+ @mtxProj.perspectiveFovRH( 30.0*Math::PI/180.0, width.to_f/height.to_f, 0.1, 1000.0 )
46
+ glLoadMatrix( @mtxProj )
47
+
48
+ @window_width = width
49
+ @window_height = height
50
+
51
+ glutPostRedisplay()
52
+ end
53
+
54
+
55
+ def timer( value )
56
+ glutPostRedisplay()
57
+ glutTimerFunc( 1000/60, method(:timer).to_proc, 0 )
58
+ end
59
+
60
+
61
+ def key( key, x, y )
62
+ case key
63
+ when ?\e, ?q
64
+ exit
65
+ end
66
+ end
67
+
68
+
69
+ def initialize
70
+ @window_width = 320
71
+ @window_height = 240
72
+
73
+ @eye = RVec3.new(0.0, 15.0, 15.0)
74
+ @at = RVec3.new(0.0, 0.0, 0.0)
75
+ @up = RVec3.new(0.0, 1.0, 0.0)
76
+ @mtxLookAt = RMtx4.new.lookAtRH( @eye, @at, @up )
77
+ @mtxProj = RMtx4.new.perspectiveFovRH( 30.0*Math::PI/180.0, @window_width.to_f/@window_height.to_f, 0.1, 1000.0 )
78
+
79
+ @light_pos = [2.5,0,5,1]
80
+ @light_diffuse = [1,1,1,1]
81
+ @light_specular = [1,1,1,1]
82
+ @light_ambient = [1,1,1,1]
83
+
84
+ @teapot_diffuse = [0.8,1,0,1]
85
+ @teapot_specular = [1,1,1,1]
86
+ @teapot_ambient = [0.2,0.2,0,1]
87
+ @teapot_shininess = 32.0
88
+
89
+ @teapot_rad_y = 0.0
90
+ @mtxTeapotRotY = RMtx4.new.rotationY( @teapot_rad_y )
91
+
92
+ glutInit()
93
+
94
+ glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE )
95
+ glutInitWindowPosition( 0, 0 )
96
+ glutInitWindowSize( @window_width, @window_height )
97
+ glutCreateWindow( self.class.to_s )
98
+
99
+ glutDisplayFunc( method(:draw).to_proc )
100
+ glutReshapeFunc( method(:reshape).to_proc )
101
+ glutKeyboardFunc( method(:key).to_proc )
102
+ glutTimerFunc( 0, method(:timer).to_proc, 0 )
103
+
104
+ # Common rendering state : reused by PushAttrib/PopAttrib
105
+ glEnable( GL_DEPTH_TEST )
106
+ glEnable( GL_LIGHTING )
107
+ glEnable( GL_LIGHT0 )
108
+ glEnable( GL_NORMALIZE )
109
+ glClearColor( 0.0, 0.0, 0.0, 1 )
110
+ end
111
+
112
+ def start
113
+ glutMainLoop()
114
+ end
115
+
116
+ end
117
+
118
+ App.new.start
@@ -0,0 +1,11 @@
1
+ # require 'rmath3d/rmath3d_plain'
2
+ require 'rmath3d/rmath3d'
3
+ include RMath3D
4
+
5
+ 99999.times do
6
+ v = RVec3.new( rand(), rand(), rand() )
7
+ m = RMtx3.new.rotationX( Math::PI/4.0 )
8
+ p v
9
+ v2 = v.transformRS( m )
10
+ p v2
11
+ end
data/test/test.rb ADDED
@@ -0,0 +1,15 @@
1
+ require 'rmath3d/rmath3d'
2
+ # require_relative '../ext/rmath3d/rmath3d'
3
+ # require 'rmath3d/rmath3d_plain'
4
+ # require_relative '../lib/rmath3d/rmath3d_plain'
5
+ include RMath3D
6
+
7
+ # Test::Unit
8
+ require 'minitest/autorun'
9
+
10
+ # Test cases
11
+ require_relative 'test_RVec3.rb'
12
+ require_relative 'test_RVec4.rb'
13
+ require_relative 'test_RQuat.rb'
14
+ require_relative 'test_RMtx3.rb'
15
+ require_relative 'test_RMtx4.rb'
@@ -0,0 +1,517 @@
1
+ class TC_RMtx3 < Minitest::Test
2
+
3
+ def setup
4
+ @tolerance = RMath3D::TOLERANCE
5
+ @mZero = RMtx3.new.setZero
6
+ @mIdentity = RMtx3.new.setIdentity
7
+ end
8
+
9
+ def teardown
10
+ end
11
+
12
+ def test_RMtx_initialize
13
+ m0 = RMtx3.new
14
+ for r in 0...3 do
15
+ for c in 0...3 do
16
+ assert_equal( 0.0, m0.getElement(r,c) )
17
+ end
18
+ end
19
+
20
+ m1 = RMtx3.new( 0, 1, 2,
21
+ 3, 4, 5,
22
+ 6, 7, 8 )
23
+ assert_equal( 0, m1.getElement(0,0) )
24
+ assert_equal( 1, m1.getElement(0,1) )
25
+ assert_equal( 2, m1.getElement(0,2) )
26
+ assert_equal( 3, m1.getElement(1,0) )
27
+ assert_equal( 4, m1.getElement(1,1) )
28
+ assert_equal( 5, m1.getElement(1,2) )
29
+ assert_equal( 6, m1.getElement(2,0) )
30
+ assert_equal( 7, m1.getElement(2,1) )
31
+ assert_equal( 8, m1.getElement(2,2) )
32
+
33
+ m2 = RMtx3.new( m1 )
34
+ for r in 0...3 do
35
+ for c in 0...3 do
36
+ assert_equal( 3*r+c, m2.getElement(r,c) )
37
+ end
38
+ end
39
+ end
40
+
41
+ def test_to_s
42
+ assert_respond_to( @mZero, :to_s )
43
+ end
44
+
45
+ def test_coerce
46
+ assert_respond_to( @mZero, :coerce )
47
+ end
48
+
49
+ def test_setElements
50
+ @mZero.setElements( 0, 1, 2, 3, 4, 5, 6, 7, 8 )
51
+ for r in 0...3 do
52
+ for c in 0...3 do
53
+ assert_equal( 3*r+c, @mZero.getElement(r,c) )
54
+ end
55
+ end
56
+ end
57
+
58
+ def test_setElement
59
+ for r in 0...3 do
60
+ for c in 0...3 do
61
+ @mZero.setElement( r, c, 3*r+c )
62
+ end
63
+ end
64
+ for r in 0...3 do
65
+ for c in 0...3 do
66
+ assert_equal( 3*r+c, @mZero.getElement(r,c) )
67
+ end
68
+ end
69
+
70
+ for r in 0...3 do
71
+ for c in 0...3 do
72
+ @mZero[r, c] = 3*c+r
73
+ end
74
+ end
75
+ for r in 0...3 do
76
+ for c in 0...3 do
77
+ assert_equal( 3*c+r, @mZero[r,c] )
78
+ end
79
+ end
80
+ end
81
+
82
+ def test_getElement
83
+ assert_respond_to( @mIdentity, :getElement )
84
+ for r in 0...3 do
85
+ for c in 0...3 do
86
+ e = @mIdentity.getElement( r, c )
87
+ if ( r == c )
88
+ assert_equal( 1.0, e )
89
+ else
90
+ assert_equal( 0.0, e )
91
+ end
92
+ end
93
+ end
94
+
95
+ for r in 0...3 do
96
+ for c in 0...3 do
97
+ e = @mIdentity[ r, c ]
98
+ if ( r == c )
99
+ assert_equal( 1.0, e )
100
+ else
101
+ assert_equal( 0.0, e )
102
+ end
103
+ end
104
+ end
105
+
106
+ mtx = RMtx3.new(1,2,3,
107
+ 4,5,6,
108
+ 7,8,9)
109
+ assert_equal( mtx.e00, 1 )
110
+ assert_equal( mtx.e01, 2 )
111
+ assert_equal( mtx.e02, 3 )
112
+ assert_equal( mtx.e10, 4 )
113
+ assert_equal( mtx.e11, 5 )
114
+ assert_equal( mtx.e12, 6 )
115
+ assert_equal( mtx.e20, 7 )
116
+ assert_equal( mtx.e21, 8 )
117
+ assert_equal( mtx.e22, 9 )
118
+ end
119
+
120
+ def test_getRowColumn
121
+ mtx = RMtx3.new(1,2,3,
122
+ 4,5,6,
123
+ 7,8,9)
124
+
125
+ v = mtx.getRow(0)
126
+ assert_equal( v.x, 1 )
127
+ assert_equal( v.y, 2 )
128
+ assert_equal( v.z, 3 )
129
+
130
+ v = mtx.getRow(1)
131
+ assert_equal( v.x, 4 )
132
+ assert_equal( v.y, 5 )
133
+ assert_equal( v.z, 6 )
134
+
135
+ v = mtx.getRow(2)
136
+ assert_equal( v.x, 7 )
137
+ assert_equal( v.y, 8 )
138
+ assert_equal( v.z, 9 )
139
+
140
+ v = mtx.getColumn(0)
141
+ assert_equal( v.x, 1 )
142
+ assert_equal( v.y, 4 )
143
+ assert_equal( v.z, 7 )
144
+
145
+ v = mtx.getColumn(1)
146
+ assert_equal( v.x, 2 )
147
+ assert_equal( v.y, 5 )
148
+ assert_equal( v.z, 8 )
149
+
150
+ v = mtx.getColumn(2)
151
+ assert_equal( v.x, 3 )
152
+ assert_equal( v.y, 6 )
153
+ assert_equal( v.z, 9 )
154
+ end
155
+
156
+ def test_setRowColumn
157
+ mtx = RMtx3.new
158
+
159
+ vr = [RVec3.new(1,2,3),RVec3.new(4,5,6),RVec3.new(7,8,9)]
160
+ mtx.setRow(vr[0],0)
161
+ mtx.setRow(vr[1],1)
162
+ mtx.setRow(vr[2],2)
163
+ assert_equal( mtx.e00, 1 )
164
+ assert_equal( mtx.e01, 2 )
165
+ assert_equal( mtx.e02, 3 )
166
+ assert_equal( mtx.e10, 4 )
167
+ assert_equal( mtx.e11, 5 )
168
+ assert_equal( mtx.e12, 6 )
169
+ assert_equal( mtx.e20, 7 )
170
+ assert_equal( mtx.e21, 8 )
171
+ assert_equal( mtx.e22, 9 )
172
+
173
+ vc = [RVec3.new(1,2,3),RVec3.new(4,5,6),RVec3.new(7,8,9)]
174
+ mtx.setColumn(vc[0],0)
175
+ mtx.setColumn(vc[1],1)
176
+ mtx.setColumn(vc[2],2)
177
+ assert_equal( mtx.e00, 1 )
178
+ assert_equal( mtx.e01, 4 )
179
+ assert_equal( mtx.e02, 7 )
180
+ assert_equal( mtx.e10, 2 )
181
+ assert_equal( mtx.e11, 5 )
182
+ assert_equal( mtx.e12, 8 )
183
+ assert_equal( mtx.e20, 3 )
184
+ assert_equal( mtx.e21, 6 )
185
+ assert_equal( mtx.e22, 9 )
186
+ end
187
+
188
+ def test_setZero
189
+ m = RMtx3.new( 1, 2, 3, 4, 5, 6, 7, 8, 9 )
190
+ m.setZero
191
+ for r in 0...3 do
192
+ for c in 0...3 do
193
+ assert_equal( 0.0, m.getElement( r, c ) )
194
+ end
195
+ end
196
+ end
197
+
198
+ def test_setIdentity
199
+ m = RMtx3.new( 1, 2, 3, 4, 5, 6, 7, 8, 9 )
200
+ m.setIdentity
201
+ for r in 0...3 do
202
+ for c in 0...3 do
203
+ e = @mIdentity.getElement( r, c )
204
+ if ( r == c )
205
+ assert_equal( 1.0, e )
206
+ else
207
+ assert_equal( 0.0, e )
208
+ end
209
+ end
210
+ end
211
+ end
212
+
213
+ # http://en.wikipedia.org/wiki/Determinant
214
+ def test_getDeterminant
215
+ m0 = RMtx3.new( -2, 2, -3,
216
+ -1, 1, 3,
217
+ 2, 0, -1 )
218
+ assert_equal( 18.0, m0.getDeterminant )
219
+
220
+ m1 = RMtx3.new( 0, 2, -3,
221
+ 0, 1, 3,
222
+ 2, 0, -1 )
223
+ assert_equal( 18.0, m1.getDeterminant )
224
+
225
+ m2 = RMtx3.new( Math::sqrt(2)/2, -Math::sqrt(2)/2, 0.0,
226
+ Math::sqrt(2)/2, Math::sqrt(2)/2, 0.0,
227
+ 0.0, 0.0, 1.0 )
228
+ assert_in_delta( 1.0, m2.getDeterminant, @tolerance )
229
+ end
230
+
231
+ def test_transpose
232
+ m0 = RMtx3.new( -2, 2, -3,
233
+ -1, 1, 3,
234
+ 2, 0, -1 )
235
+ # RMtx3#getTransposed
236
+ m1 = m0.getTransposed
237
+ for r in 0...3 do
238
+ for c in 0...3 do
239
+ assert_equal( m0.getElement(c,r), m1.getElement(r,c) )
240
+ end
241
+ end
242
+
243
+ # RMtx3#transpose!
244
+ m0.transpose!
245
+ for r in 0...3 do
246
+ for c in 0...3 do
247
+ assert_equal( m0.getElement(r,c), m1.getElement(r,c) )
248
+ end
249
+ end
250
+ end
251
+
252
+ # http://people.hofstra.edu/Stefan_waner/RealWorld/tutorialsf1/frames3_3.html
253
+ # http://numericalmethods.eng.usf.edu/mws/gen/04sle/mws_gen_sle_bck_system.pdf
254
+ def test_inverse
255
+ # RMtx3#getInverse
256
+ m0 = RMtx3.new( 1, 0, -2,
257
+ 4, 1, 0,
258
+ 1, 1, 7 )
259
+
260
+ m0inv = RMtx3.new( 7, -2, 2,
261
+ -28, 9, -8,
262
+ 3, -1, 1 )
263
+ m1 = m0.getInverse
264
+ for r in 0...3 do
265
+ for c in 0...3 do
266
+ assert_in_delta( m0inv.getElement(r,c), m1.getElement(r,c), @tolerance )
267
+ end
268
+ end
269
+
270
+ # RMtx3#invert!
271
+ m2 = RMtx3.new( 25, 5, 1,
272
+ 64, 8, 1,
273
+ 144, 12, 1 )
274
+
275
+ m2inv = RMtx3.new( -4, 7, -3,
276
+ 80,-119, 39,
277
+ -384, 420,-120 )
278
+ m2inv *= -1.0 / 84.0
279
+
280
+ m2.invert!
281
+
282
+ for r in 0...3 do
283
+ for c in 0...3 do
284
+ assert_in_delta( m2inv.getElement(r,c), m2.getElement(r,c), @tolerance )
285
+ end
286
+ end
287
+ end
288
+
289
+ def test_rotationX
290
+ m0 = RMtx3.new( 1.0, 0.0, 0.0,
291
+ 0.0, Math::sqrt(2)/2, -Math::sqrt(2)/2,
292
+ 0.0, Math::sqrt(2)/2, Math::sqrt(2)/2 )
293
+ m1 = RMtx3.new.rotationX( Math::PI/4.0 )
294
+
295
+ for r in 0...3 do
296
+ for c in 0...3 do
297
+ assert_in_delta( m0.getElement(r,c), m1.getElement(r,c), @tolerance )
298
+ end
299
+ end
300
+
301
+
302
+ m2 = RMtx3.new( 1.0, 0.0, 0.0,
303
+ 0.0, 0.5, -Math::sqrt(3)/2,
304
+ 0.0, Math::sqrt(3)/2, 0.5 );
305
+ m3 = RMtx3.new.rotationX( Math::PI/3.0 )
306
+
307
+ for r in 0...3 do
308
+ for c in 0...3 do
309
+ assert_in_delta( m2.getElement(r,c), m3.getElement(r,c), @tolerance )
310
+ end
311
+ end
312
+ end
313
+
314
+ def test_rotationY
315
+ m0 = RMtx3.new( Math::sqrt(2)/2, 0.0, Math::sqrt(2)/2,
316
+ 0.0, 1.0, 0.0,
317
+ -Math::sqrt(2)/2, 0.0, Math::sqrt(2)/2 )
318
+ m1 = RMtx3.new.rotationY( Math::PI/4.0 )
319
+
320
+ for r in 0...3 do
321
+ for c in 0...3 do
322
+ assert_in_delta( m0.getElement(r,c), m1.getElement(r,c), @tolerance )
323
+ end
324
+ end
325
+
326
+ m2 = RMtx3.new( 0.5, 0.0, Math::sqrt(3)/2,
327
+ 0.0, 1.0, 0.0,
328
+ -Math::sqrt(3)/2, 0.0, 0.5 )
329
+ m3 = RMtx3.new.rotationY( Math::PI/3.0 )
330
+
331
+ for r in 0...3 do
332
+ for c in 0...3 do
333
+ assert_in_delta( m2.getElement(r,c), m3.getElement(r,c), @tolerance )
334
+ end
335
+ end
336
+ end
337
+
338
+ def test_rotationZ
339
+ m0 = RMtx3.new( Math::sqrt(2)/2, -Math::sqrt(2)/2, 0.0,
340
+ Math::sqrt(2)/2, Math::sqrt(2)/2, 0.0,
341
+ 0.0, 0.0, 1.0 )
342
+ m1 = RMtx3.new.rotationZ( Math::PI/4.0 )
343
+
344
+ for r in 0...3 do
345
+ for c in 0...3 do
346
+ assert_in_delta( m0.getElement(r,c), m1.getElement(r,c), @tolerance )
347
+ end
348
+ end
349
+
350
+ m2 = RMtx3.new( 0.5, -Math::sqrt(3)/2, 0.0,
351
+ Math::sqrt(3)/2, 0.5, 0.0,
352
+ 0.0, 0.0, 1.0 )
353
+ m3 = RMtx3.new.rotationZ( Math::PI/3.0 )
354
+
355
+ for r in 0...3 do
356
+ for c in 0...3 do
357
+ assert_in_delta( m2.getElement(r,c), m3.getElement(r,c), @tolerance )
358
+ end
359
+ end
360
+ end
361
+
362
+ def test_rotationAxis
363
+ m0 = RMtx3.new( 0.5, -Math::sqrt(3)/2, 0.0,
364
+ Math::sqrt(3)/2, 0.5, 0.0,
365
+ 0.0, 0.0, 1.0 )
366
+ m1 = RMtx3.new.rotationAxis( RVec3.new(0,0,1), Math::PI/3.0 )
367
+
368
+ for r in 0...3 do
369
+ for c in 0...3 do
370
+ assert_in_delta( m0.getElement(r,c), m1.getElement(r,c), @tolerance )
371
+ end
372
+ end
373
+ end
374
+
375
+ def test_rotationQuaternion
376
+ q = RQuat.new.rotationAxis( RVec3.new(0,0,1), Math::PI/3.0 )
377
+ m0 = RMtx3.new( 0.5, -Math::sqrt(3)/2, 0.0,
378
+ Math::sqrt(3)/2, 0.5, 0.0,
379
+ 0.0, 0.0, 1.0 )
380
+ m1 = RMtx3.new.rotationQuaternion( q )
381
+
382
+ for r in 0...3 do
383
+ for c in 0...3 do
384
+ assert_in_delta( m0.getElement(r,c), m1.getElement(r,c), @tolerance )
385
+ end
386
+ end
387
+ end
388
+
389
+ def test_scaling
390
+ m0 = RMtx3.new( 10.0, 0.0, 0.0,
391
+ 0.0, 20.0, 0.0,
392
+ 0.0, 0.0, 30.0 )
393
+ m1 = RMtx3.new.scaling( 10.0, 20.0, 30.0 )
394
+ for r in 0...3 do
395
+ for c in 0...3 do
396
+ assert_in_delta( m0.getElement(r,c), m1.getElement(r,c), @tolerance )
397
+ end
398
+ end
399
+ end
400
+
401
+ def test_unary_operators
402
+ # RMtx3#+@
403
+ m0 = RMtx3.new( 0, 1, 2, 3, 4, 5, 6, 7, 8 )
404
+ m1 = RMtx3.new( 0, 1, 2, 3, 4, 5, 6, 7, 8 )
405
+ m2 = +m0
406
+
407
+ assert_same( m0, m2 )
408
+ assert( m1 == m2 )
409
+
410
+ for r in 0...3 do
411
+ for c in 0...3 do
412
+ assert_in_delta( 3*r+c, m2.getElement(r,c), @tolerance )
413
+ end
414
+ end
415
+
416
+ # RMtx3#-@
417
+ m2 = -m0
418
+ for r in 0...3 do
419
+ for c in 0...3 do
420
+ assert_in_delta( m0.getElement(r,c), -m2.getElement(r,c), @tolerance )
421
+ end
422
+ end
423
+ end
424
+
425
+ def test_binary_plus
426
+ m0 = RMtx3.new( 0, 1, 2, 3, 4, 5, 6, 7, 8 )
427
+ m1 = RMtx3.new( 9,10,11,12,13,14,15,16,17 )
428
+ m2 = RMtx3.new( 9,11,13,15,17,19,21,23,25 )
429
+
430
+ # RMtx3#+
431
+ m3 = m0 + m1
432
+ for r in 0...3 do
433
+ for c in 0...3 do
434
+ assert_in_delta( m2.getElement(r,c), m3.getElement(r,c), @tolerance )
435
+ end
436
+ end
437
+
438
+ # RMtx3#add!
439
+ m0.add!( m1 )
440
+ for r in 0...3 do
441
+ for c in 0...3 do
442
+ assert_in_delta( m2.getElement(r,c), m0.getElement(r,c), @tolerance )
443
+ end
444
+ end
445
+ end
446
+
447
+ def test_binary_minus
448
+ m0 = RMtx3.new( 0, 1, 2, 3, 4, 5, 6, 7, 8 )
449
+ m1 = RMtx3.new( 9,10,11,12,13,14,15,16,17 )
450
+ m2 = RMtx3.new(-9,-9,-9,-9,-9,-9,-9,-9,-9 )
451
+
452
+ # RMtx3#-
453
+ m3 = m0 - m1
454
+ for r in 0...3 do
455
+ for c in 0...3 do
456
+ assert_in_delta( m2.getElement(r,c), m3.getElement(r,c), @tolerance )
457
+ end
458
+ end
459
+
460
+ # RMtx3#sub!
461
+ m0.sub!( m1 )
462
+ for r in 0...3 do
463
+ for c in 0...3 do
464
+ assert_in_delta( m2.getElement(r,c), m0.getElement(r,c), @tolerance )
465
+ end
466
+ end
467
+ end
468
+
469
+ def test_binary_mult
470
+ m0 = RMtx3.new( 0, 1, 2, 3, 4, 5, 6, 7, 8 )
471
+ m1 = RMtx3.new( 9,10,11,12,13,14,15,16,17 )
472
+ m0x1 = RMtx3.new( 42, 45, 48, 150, 162, 174, 258, 279, 300 )
473
+ m1x0 = RMtx3.new( 96, 126, 156, 123, 162, 201, 150, 198, 246 )
474
+
475
+ # RMtx3#*
476
+ m2 = m0 * m1
477
+ for r in 0...3 do
478
+ for c in 0...3 do
479
+ assert_in_delta( m0x1.getElement(r,c), m2.getElement(r,c), @tolerance )
480
+ end
481
+ end
482
+
483
+ m2 = m1 * m0
484
+ for r in 0...3 do
485
+ for c in 0...3 do
486
+ assert_in_delta( m1x0.getElement(r,c), m2.getElement(r,c), @tolerance )
487
+ end
488
+ end
489
+
490
+ # RMtx3#mul!
491
+ m2 = RMtx3.new( m0 )
492
+ m2.mul!( m1 )
493
+ for r in 0...3 do
494
+ for c in 0...3 do
495
+ assert_in_delta( m0x1.getElement(r,c), m2.getElement(r,c), @tolerance )
496
+ end
497
+ end
498
+
499
+ m2 = RMtx3.new( m1 )
500
+ m2.mul!( m0 )
501
+ for r in 0...3 do
502
+ for c in 0...3 do
503
+ assert_in_delta( m1x0.getElement(r,c), m2.getElement(r,c), @tolerance )
504
+ end
505
+ end
506
+ end
507
+
508
+ def test_equality_operators
509
+ m0 = RMtx3.new( 0, 1, 2, 3, 4, 5, 6, 7, 8 )
510
+ m1 = RMtx3.new( 0, 1, 2, 3, 4, 5, 6, 7, 8 )
511
+ m2 = RMtx3.new( 9,10,11,12,13,14,15,16,17 )
512
+
513
+ assert( m0 == m1 )
514
+ assert( m0 != m2 )
515
+ end
516
+
517
+ end