Subversion Repositories AndroidProjects

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
1452 chris 1
#region --- License ---
2
/*
3
Copyright (c) 2006 - 2008 The Open Toolkit library.
4
 
5
Permission is hereby granted, free of charge, to any person obtaining a copy of
6
this software and associated documentation files (the "Software"), to deal in
7
the Software without restriction, including without limitation the rights to
8
use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies
9
of the Software, and to permit persons to whom the Software is furnished to do
10
so, subject to the following conditions:
11
 
12
The above copyright notice and this permission notice shall be included in all
13
copies or substantial portions of the Software.
14
 
15
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
SOFTWARE.
22
 */
23
#endregion
24
 
25
using System;
26
using System.Runtime.InteropServices;
27
 
28
namespace OpenTK
29
{
30
    // Todo: Remove this warning when the code goes public.
31
    #pragma warning disable 3019
32
#if false
33
    [Serializable]
34
    [StructLayout(LayoutKind.Sequential)]
35
    public struct Matrix3d : IEquatable<Matrix3d>
36
    {
37
        #region Fields & Access
38
 
39
        /// <summary>Row 0, Column 0</summary>
40
        public double R0C0;
41
 
42
        /// <summary>Row 0, Column 1</summary>
43
        public double R0C1;
44
 
45
        /// <summary>Row 0, Column 2</summary>
46
        public double R0C2;
47
 
48
        /// <summary>Row 1, Column 0</summary>
49
        public double R1C0;
50
 
51
        /// <summary>Row 1, Column 1</summary>
52
        public double R1C1;
53
 
54
        /// <summary>Row 1, Column 2</summary>
55
        public double R1C2;
56
 
57
        /// <summary>Row 2, Column 0</summary>
58
        public double R2C0;
59
 
60
        /// <summary>Row 2, Column 1</summary>
61
        public double R2C1;
62
 
63
        /// <summary>Row 2, Column 2</summary>
64
        public double R2C2;
65
 
66
        /// <summary>Gets the component at the given row and column in the matrix.</summary>
67
        /// <param name="row">The row of the matrix.</param>
68
        /// <param name="column">The column of the matrix.</param>
69
        /// <returns>The component at the given row and column in the matrix.</returns>
70
        public double this[int row, int column]
71
        {
72
            get
73
            {
74
                switch( row )
75
                {
76
                    case 0:
77
                        switch (column)
78
                        {
79
                            case 0: return R0C0;
80
                            case 1: return R0C1;
81
                            case 2: return R0C2;
82
                        }
83
                        break;
84
 
85
                    case 1:
86
                        switch (column)
87
                        {
88
                            case 0: return R1C0;
89
                            case 1: return R1C1;
90
                            case 2: return R1C2;
91
                        }
92
                        break;
93
 
94
                    case 2:
95
                        switch (column)
96
                        {
97
                            case 0: return R2C0;
98
                            case 1: return R2C1;
99
                            case 2: return R2C2;
100
                        }
101
                        break;
102
                }
103
 
104
                throw new IndexOutOfRangeException();
105
            }
106
            set
107
            {
108
                switch( row )
109
                {
110
                    case 0:
111
                        switch (column)
112
                        {
113
                            case 0: R0C0 = value; return;
114
                            case 1: R0C1 = value; return;
115
                            case 2: R0C2 = value; return;
116
                        }
117
                        break;
118
 
119
                    case 1:
120
                        switch (column)
121
                        {
122
                            case 0: R1C0 = value; return;
123
                            case 1: R1C1 = value; return;
124
                            case 2: R1C2 = value; return;
125
                        }
126
                        break;
127
 
128
                    case 2:
129
                        switch (column)
130
                        {
131
                            case 0: R2C0 = value; return;
132
                            case 1: R2C1 = value; return;
133
                            case 2: R2C2 = value; return;
134
                        }
135
                        break;
136
                }
137
 
138
                throw new IndexOutOfRangeException();
139
            }
140
        }
141
 
142
        /// <summary>Gets the component at the index into the matrix.</summary>
143
        /// <param name="index">The index into the components of the matrix.</param>
144
        /// <returns>The component at the given index into the matrix.</returns>
145
        public double this[int index]
146
        {
147
            get
148
            {
149
                switch (index)
150
                {
151
                    case 0: return R0C0;
152
                    case 1: return R0C1;
153
                    case 2: return R0C2;
154
                    case 3: return R1C0;
155
                    case 4: return R1C1;
156
                    case 5: return R1C2;
157
                    case 6: return R2C0;
158
                    case 7: return R2C1;
159
                    case 8: return R2C2;
160
                    default: throw new IndexOutOfRangeException();
161
                }
162
            }
163
            set
164
            {
165
                switch (index)
166
                {
167
                    case 0: R0C0 = value; return;
168
                    case 1: R0C1 = value; return;
169
                    case 2: R0C2 = value; return;
170
                    case 3: R1C0 = value; return;
171
                    case 4: R1C1 = value; return;
172
                    case 5: R1C2 = value; return;
173
                    case 6: R2C0 = value; return;
174
                    case 7: R2C1 = value; return;
175
                    case 8: R2C2 = value; return;
176
                    default: throw new IndexOutOfRangeException();
177
                }
178
            }
179
        }
180
 
181
        /// <summary>Converts the matrix into an IntPtr.</summary>
182
        /// <param name="matrix">The matrix to convert.</param>
183
        /// <returns>An IntPtr for the matrix.</returns>
184
        public static explicit operator IntPtr(Matrix3d matrix)
185
        {
186
            unsafe
187
            {
188
                return (IntPtr)(&matrix.R0C0);
189
            }
190
        }
191
 
192
        /// <summary>Converts the matrix into left double*.</summary>
193
        /// <param name="matrix">The matrix to convert.</param>
194
        /// <returns>A double* for the matrix.</returns>
195
        [CLSCompliant(false)]
196
        unsafe public static explicit operator double*(Matrix3d matrix)
197
        {
198
            return &matrix.R0C0;
199
        }
200
 
201
        /// <summary>Converts the matrix into an array of doubles.</summary>
202
        /// <param name="matrix">The matrix to convert.</param>
203
        /// <returns>An array of doubles for the matrix.</returns>
204
        public static explicit operator double[](Matrix3d matrix)
205
        {
206
            return new double[9]
207
            {
208
                matrix.R0C0,
209
                matrix.R0C1,
210
                matrix.R0C2,
211
                matrix.R1C0,
212
                matrix.R1C1,
213
                matrix.R1C2,
214
                matrix.R2C0,
215
                matrix.R2C1,
216
                matrix.R2C2
217
            };
218
        }
219
 
220
        #endregion
221
 
222
        #region Constructors
223
 
224
        /// <summary>Constructs left matrix with the same components as the given matrix.</summary>
225
        /// <param name="vector">The matrix whose components to copy.</param>
226
        public Matrix3d(ref Matrix3d matrix)
227
        {
228
            this.R0C0 = matrix.R0C0;
229
            this.R0C1 = matrix.R0C1;
230
            this.R0C2 = matrix.R0C2;
231
            this.R1C0 = matrix.R1C0;
232
            this.R1C1 = matrix.R1C1;
233
            this.R1C2 = matrix.R1C2;
234
            this.R2C0 = matrix.R2C0;
235
            this.R2C1 = matrix.R2C1;
236
            this.R2C2 = matrix.R2C2;
237
        }
238
 
239
        /// <summary>Constructs left matrix with the given values.</summary>
240
        /// <param name="r0c0">The value for row 0 column 0.</param>
241
        /// <param name="r0c1">The value for row 0 column 1.</param>
242
        /// <param name="r0c2">The value for row 0 column 2.</param>
243
        /// <param name="r1c0">The value for row 1 column 0.</param>
244
        /// <param name="r1c1">The value for row 1 column 1.</param>
245
        /// <param name="r1c2">The value for row 1 column 2.</param>
246
        /// <param name="r2c0">The value for row 2 column 0.</param>
247
        /// <param name="r2c1">The value for row 2 column 1.</param>
248
        /// <param name="r2c2">The value for row 2 column 2.</param>
249
        public Matrix3d
250
        (
251
            double r0c0,
252
            double r0c1,
253
            double r0c2,
254
            double r1c0,
255
            double r1c1,
256
            double r1c2,
257
            double r2c0,
258
            double r2c1,
259
            double r2c2
260
        )
261
        {
262
            this.R0C0 = r0c0;
263
            this.R0C1 = r0c1;
264
            this.R0C2 = r0c2;
265
            this.R1C0 = r1c0;
266
            this.R1C1 = r1c1;
267
            this.R1C2 = r1c2;
268
            this.R2C0 = r2c0;
269
            this.R2C1 = r2c1;
270
            this.R2C2 = r2c2;
271
        }
272
 
273
        /// <summary>Constructs left matrix from the given array of double-precision floating-point numbers.</summary>
274
        /// <param name="doubleArray">The array of doubles for the components of the matrix.</param>
275
        public Matrix3d(double[] doubleArray)
276
        {
277
            if (doubleArray == null || doubleArray.GetLength(0) < 9) throw new MissingFieldException();
278
 
279
            this.R0C0 = doubleArray[0];
280
            this.R0C1 = doubleArray[1];
281
            this.R0C2 = doubleArray[2];
282
            this.R1C0 = doubleArray[3];
283
            this.R1C1 = doubleArray[4];
284
            this.R1C2 = doubleArray[5];
285
            this.R2C0 = doubleArray[6];
286
            this.R2C1 = doubleArray[7];
287
            this.R2C2 = doubleArray[8];
288
        }
289
 
290
        /// <summary>Constructs left matrix from the given quaternion.</summary>
291
        /// <param name="quaternion">The quaternion to use to construct the martix.</param>
292
        public Matrix3d(Quaterniond quaternion)
293
        {
294
            quaternion.Normalize();
295
 
296
            double xx = quaternion.X * quaternion.X;
297
            double yy = quaternion.Y * quaternion.Y;
298
            double zz = quaternion.Z * quaternion.Z;
299
            double xy = quaternion.X * quaternion.Y;
300
            double xz = quaternion.X * quaternion.Z;
301
            double yz = quaternion.Y * quaternion.Z;
302
            double wx = quaternion.W * quaternion.X;
303
            double wy = quaternion.W * quaternion.Y;
304
            double wz = quaternion.W * quaternion.Z;
305
 
306
            R0C0 = 1 - 2 * (yy + zz);
307
            R0C1 = 2 * (xy - wz);
308
            R0C2 = 2 * (xz + wy);
309
 
310
            R1C0 = 2 * (xy + wz);
311
            R1C1 = 1 - 2 * (xx + zz);
312
            R1C2 = 2 * (yz - wx);
313
 
314
            R2C0 = 2 * (xz - wy);
315
            R2C1 = 2 * (yz + wx);
316
            R2C2 = 1 - 2 * (xx + yy);
317
        }
318
 
319
        #endregion
320
 
321
        #region Equality
322
 
323
        /// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
324
        /// <param name="matrix">The OpenTK.Matrix3d structure to compare with.</param>
325
        /// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
326
        [CLSCompliant(false)]
327
        public bool Equals(Matrix3d matrix)
328
        {
329
            return
330
                R0C0 == matrix.R0C0 &&
331
                R0C1 == matrix.R0C1 &&
332
                R0C2 == matrix.R0C2 &&
333
                R1C0 == matrix.R1C0 &&
334
                R1C1 == matrix.R1C1 &&
335
                R1C2 == matrix.R1C2 &&
336
                R2C0 == matrix.R2C0 &&
337
                R2C1 == matrix.R2C1 &&
338
                R2C2 == matrix.R2C2;
339
        }
340
 
341
        /// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
342
        /// <param name="matrix">The OpenTK.Matrix3d structure to compare to.</param>
343
        /// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
344
        public bool Equals(ref Matrix3d matrix)
345
        {
346
            return
347
                R0C0 == matrix.R0C0 &&
348
                R0C1 == matrix.R0C1 &&
349
                R0C2 == matrix.R0C2 &&
350
                R1C0 == matrix.R1C0 &&
351
                R1C1 == matrix.R1C1 &&
352
                R1C2 == matrix.R1C2 &&
353
                R2C0 == matrix.R2C0 &&
354
                R2C1 == matrix.R2C1 &&
355
                R2C2 == matrix.R2C2;
356
        }
357
 
358
        /// <summary>Indicates whether the current matrix is equal to another matrix.</summary>
359
        /// <param name="left">The left-hand operand.</param>
360
        /// <param name="right">The right-hand operand.</param>
361
        /// <returns>true if the current matrix is equal to the matrix parameter; otherwise, false.</returns>
362
        public static bool Equals(ref Matrix3d left, ref Matrix3d right)
363
        {
364
            return
365
                left.R0C0 == right.R0C0 &&
366
                left.R0C1 == right.R0C1 &&
367
                left.R0C2 == right.R0C2 &&
368
                left.R1C0 == right.R1C0 &&
369
                left.R1C1 == right.R1C1 &&
370
                left.R1C2 == right.R1C2 &&
371
                left.R2C0 == right.R2C0 &&
372
                left.R2C1 == right.R2C1 &&
373
                left.R2C2 == right.R2C2;
374
        }
375
 
376
        /// <summary>Indicates whether the current matrix is approximately equal to another matrix.</summary>
377
        /// <param name="matrix">The OpenTK.Matrix3d structure to compare with.</param>
378
        /// <param name="tolerance">The limit below which the matrices are considered equal.</param>
379
        /// <returns>true if the current matrix is approximately equal to the matrix parameter; otherwise, false.</returns>
380
        public bool EqualsApprox(ref Matrix3d matrix, double tolerance)
381
        {
382
            return
383
                System.Math.Abs(R0C0 - matrix.R0C0) <= tolerance &&
384
                System.Math.Abs(R0C1 - matrix.R0C1) <= tolerance &&
385
                System.Math.Abs(R0C2 - matrix.R0C2) <= tolerance &&
386
                System.Math.Abs(R1C0 - matrix.R1C0) <= tolerance &&
387
                System.Math.Abs(R1C1 - matrix.R1C1) <= tolerance &&
388
                System.Math.Abs(R1C2 - matrix.R1C2) <= tolerance &&
389
                System.Math.Abs(R2C0 - matrix.R2C0) <= tolerance &&
390
                System.Math.Abs(R2C1 - matrix.R2C1) <= tolerance &&
391
                System.Math.Abs(R2C2 - matrix.R2C2) <= tolerance;
392
        }
393
 
394
        /// <summary>Indicates whether the current matrix is approximately equal to another matrix.</summary>
395
        /// <param name="left">The left-hand operand.</param>
396
        /// <param name="right">The right-hand operand.</param>
397
        /// <param name="tolerance">The limit below which the matrices are considered equal.</param>
398
        /// <returns>true if the current matrix is approximately equal to the matrix parameter; otherwise, false.</returns>
399
        public static bool EqualsApprox(ref Matrix3d left, ref Matrix3d right, double tolerance)
400
        {
401
            return
402
                System.Math.Abs(left.R0C0 - right.R0C0) <= tolerance &&
403
                System.Math.Abs(left.R0C1 - right.R0C1) <= tolerance &&
404
                System.Math.Abs(left.R0C2 - right.R0C2) <= tolerance &&
405
                System.Math.Abs(left.R1C0 - right.R1C0) <= tolerance &&
406
                System.Math.Abs(left.R1C1 - right.R1C1) <= tolerance &&
407
                System.Math.Abs(left.R1C2 - right.R1C2) <= tolerance &&
408
                System.Math.Abs(left.R2C0 - right.R2C0) <= tolerance &&
409
                System.Math.Abs(left.R2C1 - right.R2C1) <= tolerance &&
410
                System.Math.Abs(left.R2C2 - right.R2C2) <= tolerance;
411
        }
412
 
413
        #endregion
414
 
415
        #region Arithmetic Operators
416
 
417
 
418
        /// <summary>Add left matrix to this matrix.</summary>
419
        /// <param name="matrix">The matrix to add.</param>
420
        public void Add(ref Matrix3d matrix)
421
        {
422
            R0C0 = R0C0 + matrix.R0C0;
423
            R0C1 = R0C1 + matrix.R0C1;
424
            R0C2 = R0C2 + matrix.R0C2;
425
            R1C0 = R1C0 + matrix.R1C0;
426
            R1C1 = R1C1 + matrix.R1C1;
427
            R1C2 = R1C2 + matrix.R1C2;
428
            R2C0 = R2C0 + matrix.R2C0;
429
            R2C1 = R2C1 + matrix.R2C1;
430
            R2C2 = R2C2 + matrix.R2C2;
431
        }
432
 
433
        /// <summary>Add left matrix to this matrix.</summary>
434
        /// <param name="matrix">The matrix to add.</param>
435
        /// <param name="result">The resulting matrix of the addition.</param>
436
        public void Add(ref Matrix3d matrix, out Matrix3d result)
437
        {
438
            result.R0C0 = R0C0 + matrix.R0C0;
439
            result.R0C1 = R0C1 + matrix.R0C1;
440
            result.R0C2 = R0C2 + matrix.R0C2;
441
            result.R1C0 = R1C0 + matrix.R1C0;
442
            result.R1C1 = R1C1 + matrix.R1C1;
443
            result.R1C2 = R1C2 + matrix.R1C2;
444
            result.R2C0 = R2C0 + matrix.R2C0;
445
            result.R2C1 = R2C1 + matrix.R2C1;
446
            result.R2C2 = R2C2 + matrix.R2C2;
447
        }
448
 
449
        /// <summary>Add left matrix to left matrix.</summary>
450
        /// <param name="matrix">The matrix on the matrix side of the equation.</param>
451
        /// <param name="right">The matrix on the right side of the equation</param>
452
        /// <param name="result">The resulting matrix of the addition.</param>
453
        public static void Add(ref Matrix3d left, ref Matrix3d right, out Matrix3d result)
454
        {
455
            result.R0C0 = left.R0C0 + right.R0C0;
456
            result.R0C1 = left.R0C1 + right.R0C1;
457
            result.R0C2 = left.R0C2 + right.R0C2;
458
            result.R1C0 = left.R1C0 + right.R1C0;
459
            result.R1C1 = left.R1C1 + right.R1C1;
460
            result.R1C2 = left.R1C2 + right.R1C2;
461
            result.R2C0 = left.R2C0 + right.R2C0;
462
            result.R2C1 = left.R2C1 + right.R2C1;
463
            result.R2C2 = left.R2C2 + right.R2C2;
464
        }
465
 
466
 
467
        /// <summary>Subtract left matrix from this matrix.</summary>
468
        /// <param name="matrix">The matrix to subtract.</param>
469
        public void Subtract(ref Matrix3d matrix)
470
        {
471
            R0C0 = R0C0 + matrix.R0C0;
472
            R0C1 = R0C1 + matrix.R0C1;
473
            R0C2 = R0C2 + matrix.R0C2;
474
            R1C0 = R1C0 + matrix.R1C0;
475
            R1C1 = R1C1 + matrix.R1C1;
476
            R1C2 = R1C2 + matrix.R1C2;
477
            R2C0 = R2C0 + matrix.R2C0;
478
            R2C1 = R2C1 + matrix.R2C1;
479
            R2C2 = R2C2 + matrix.R2C2;
480
        }
481
 
482
        /// <summary>Subtract left matrix from this matrix.</summary>
483
        /// <param name="matrix">The matrix to subtract.</param>
484
        /// <param name="result">The resulting matrix of the subtraction.</param>
485
        public void Subtract(ref Matrix3d matrix, out Matrix3d result)
486
        {
487
            result.R0C0 = R0C0 + matrix.R0C0;
488
            result.R0C1 = R0C1 + matrix.R0C1;
489
            result.R0C2 = R0C2 + matrix.R0C2;
490
            result.R1C0 = R1C0 + matrix.R1C0;
491
            result.R1C1 = R1C1 + matrix.R1C1;
492
            result.R1C2 = R1C2 + matrix.R1C2;
493
            result.R2C0 = R2C0 + matrix.R2C0;
494
            result.R2C1 = R2C1 + matrix.R2C1;
495
            result.R2C2 = R2C2 + matrix.R2C2;
496
        }
497
 
498
        /// <summary>Subtract left matrix from left matrix.</summary>
499
        /// <param name="matrix">The matrix on the matrix side of the equation.</param>
500
        /// <param name="right">The matrix on the right side of the equation</param>
501
        /// <param name="result">The resulting matrix of the subtraction.</param>
502
        public static void Subtract(ref Matrix3d left, ref Matrix3d right, out Matrix3d result)
503
        {
504
            result.R0C0 = left.R0C0 + right.R0C0;
505
            result.R0C1 = left.R0C1 + right.R0C1;
506
            result.R0C2 = left.R0C2 + right.R0C2;
507
            result.R1C0 = left.R1C0 + right.R1C0;
508
            result.R1C1 = left.R1C1 + right.R1C1;
509
            result.R1C2 = left.R1C2 + right.R1C2;
510
            result.R2C0 = left.R2C0 + right.R2C0;
511
            result.R2C1 = left.R2C1 + right.R2C1;
512
            result.R2C2 = left.R2C2 + right.R2C2;
513
        }
514
 
515
 
516
        /// <summary>Multiply left martix times this matrix.</summary>
517
        /// <param name="matrix">The matrix to multiply.</param>
518
        public void Multiply(ref Matrix3d matrix)
519
        {
520
            double r0c0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0;
521
            double r0c1 = matrix.R0C0 * R0C1 + matrix.R0C1 * R1C1 + matrix.R0C2 * R2C1;
522
            double r0c2 = matrix.R0C0 * R0C2 + matrix.R0C1 * R1C2 + matrix.R0C2 * R2C2;
523
 
524
            double r1c0 = matrix.R1C0 * R0C0 + matrix.R1C1 * R1C0 + matrix.R1C2 * R2C0;
525
            double r1c1 = matrix.R1C0 * R0C1 + matrix.R1C1 * R1C1 + matrix.R1C2 * R2C1;
526
            double r1c2 = matrix.R1C0 * R0C2 + matrix.R1C1 * R1C2 + matrix.R1C2 * R2C2;
527
 
528
            R2C0 = matrix.R2C0 * R0C0 + matrix.R2C1 * R1C0 + matrix.R2C2 * R2C0;
529
            R2C1 = matrix.R2C0 * R0C1 + matrix.R2C1 * R1C1 + matrix.R2C2 * R2C1;
530
            R2C2 = matrix.R2C0 * R0C2 + matrix.R2C1 * R1C2 + matrix.R2C2 * R2C2;
531
 
532
 
533
            R0C0 = r0c0;
534
            R0C1 = r0c1;
535
            R0C2 = r0c2;
536
 
537
            R1C0 = r1c0;
538
            R1C1 = r1c1;
539
            R1C2 = r1c2;
540
        }
541
 
542
        /// <summary>Multiply matrix times this matrix.</summary>
543
        /// <param name="matrix">The matrix to multiply.</param>
544
        /// <param name="result">The resulting matrix of the multiplication.</param>
545
        public void Multiply(ref Matrix3d matrix, out Matrix3d result)
546
        {
547
            result.R0C0 = matrix.R0C0 * R0C0 + matrix.R0C1 * R1C0 + matrix.R0C2 * R2C0;
548
            result.R0C1 = matrix.R0C0 * R0C1 + matrix.R0C1 * R1C1 + matrix.R0C2 * R2C1;
549
            result.R0C2 = matrix.R0C0 * R0C2 + matrix.R0C1 * R1C2 + matrix.R0C2 * R2C2;
550
            result.R1C0 = matrix.R1C0 * R0C0 + matrix.R1C1 * R1C0 + matrix.R1C2 * R2C0;
551
            result.R1C1 = matrix.R1C0 * R0C1 + matrix.R1C1 * R1C1 + matrix.R1C2 * R2C1;
552
            result.R1C2 = matrix.R1C0 * R0C2 + matrix.R1C1 * R1C2 + matrix.R1C2 * R2C2;
553
            result.R2C0 = matrix.R2C0 * R0C0 + matrix.R2C1 * R1C0 + matrix.R2C2 * R2C0;
554
            result.R2C1 = matrix.R2C0 * R0C1 + matrix.R2C1 * R1C1 + matrix.R2C2 * R2C1;
555
            result.R2C2 = matrix.R2C0 * R0C2 + matrix.R2C1 * R1C2 + matrix.R2C2 * R2C2;
556
        }
557
 
558
        /// <summary>Multiply left matrix times left matrix.</summary>
559
        /// <param name="matrix">The matrix on the matrix side of the equation.</param>
560
        /// <param name="right">The matrix on the right side of the equation</param>
561
        /// <param name="result">The resulting matrix of the multiplication.</param>
562
        public static void Multiply(ref Matrix3d left, ref Matrix3d right, out Matrix3d result)
563
        {
564
            result.R0C0 = right.R0C0 * left.R0C0 + right.R0C1 * left.R1C0 + right.R0C2 * left.R2C0;
565
            result.R0C1 = right.R0C0 * left.R0C1 + right.R0C1 * left.R1C1 + right.R0C2 * left.R2C1;
566
            result.R0C2 = right.R0C0 * left.R0C2 + right.R0C1 * left.R1C2 + right.R0C2 * left.R2C2;
567
            result.R1C0 = right.R1C0 * left.R0C0 + right.R1C1 * left.R1C0 + right.R1C2 * left.R2C0;
568
            result.R1C1 = right.R1C0 * left.R0C1 + right.R1C1 * left.R1C1 + right.R1C2 * left.R2C1;
569
            result.R1C2 = right.R1C0 * left.R0C2 + right.R1C1 * left.R1C2 + right.R1C2 * left.R2C2;
570
            result.R2C0 = right.R2C0 * left.R0C0 + right.R2C1 * left.R1C0 + right.R2C2 * left.R2C0;
571
            result.R2C1 = right.R2C0 * left.R0C1 + right.R2C1 * left.R1C1 + right.R2C2 * left.R2C1;
572
            result.R2C2 = right.R2C0 * left.R0C2 + right.R2C1 * left.R1C2 + right.R2C2 * left.R2C2;
573
        }
574
 
575
 
576
        /// <summary>Multiply matrix times this matrix.</summary>
577
        /// <param name="matrix">The matrix to multiply.</param>
578
        public void Multiply(double scalar)
579
        {
580
            R0C0 = scalar * R0C0;
581
            R0C1 = scalar * R0C1;
582
            R0C2 = scalar * R0C2;
583
            R1C0 = scalar * R1C0;
584
            R1C1 = scalar * R1C1;
585
            R1C2 = scalar * R1C2;
586
            R2C0 = scalar * R2C0;
587
            R2C1 = scalar * R2C1;
588
            R2C2 = scalar * R2C2;
589
        }
590
 
591
        /// <summary>Multiply matrix times this matrix.</summary>
592
        /// <param name="matrix">The matrix to multiply.</param>
593
        /// <param name="result">The resulting matrix of the multiplication.</param>
594
        public void Multiply(double scalar, out Matrix3d result)
595
        {
596
            result.R0C0 = scalar * R0C0;
597
            result.R0C1 = scalar * R0C1;
598
            result.R0C2 = scalar * R0C2;
599
            result.R1C0 = scalar * R1C0;
600
            result.R1C1 = scalar * R1C1;
601
            result.R1C2 = scalar * R1C2;
602
            result.R2C0 = scalar * R2C0;
603
            result.R2C1 = scalar * R2C1;
604
            result.R2C2 = scalar * R2C2;
605
        }
606
 
607
        /// <summary>Multiply left matrix times left matrix.</summary>
608
        /// <param name="matrix">The matrix on the matrix side of the equation.</param>
609
        /// <param name="right">The matrix on the right side of the equation</param>
610
        /// <param name="result">The resulting matrix of the multiplication.</param>
611
        public static void Multiply(ref Matrix3d matrix, double scalar, out Matrix3d result)
612
        {
613
            result.R0C0 = scalar * matrix.R0C0;
614
            result.R0C1 = scalar * matrix.R0C1;
615
            result.R0C2 = scalar * matrix.R0C2;
616
            result.R1C0 = scalar * matrix.R1C0;
617
            result.R1C1 = scalar * matrix.R1C1;
618
            result.R1C2 = scalar * matrix.R1C2;
619
            result.R2C0 = scalar * matrix.R2C0;
620
            result.R2C1 = scalar * matrix.R2C1;
621
            result.R2C2 = scalar * matrix.R2C2;
622
        }
623
 
624
 
625
        #endregion
626
 
627
        #region Functions
628
 
629
        public double Determinant
630
        {
631
            get
632
            {
633
                return R0C0 * R1C1 * R2C2 - R0C0 * R1C2 * R2C1 - R0C1 * R1C0 * R2C2 + R0C2 * R1C0 * R2C1 + R0C1 * R1C2 * R2C0 - R0C2 * R1C1 * R2C0;
634
            }
635
        }
636
 
637
        public void Transpose()
638
        {
639
            Functions.Swap(ref R0C1, ref R1C0);
640
            Functions.Swap(ref R0C2, ref R2C0);
641
            Functions.Swap(ref R1C2, ref R2C1);
642
        }
643
        public void Transpose(out Matrix3d result)
644
        {
645
            result.R0C0 = R0C0;
646
            result.R0C1 = R1C0;
647
            result.R0C2 = R2C0;
648
            result.R1C0 = R0C1;
649
            result.R1C1 = R1C1;
650
            result.R1C2 = R2C1;
651
            result.R2C0 = R0C2;
652
            result.R2C1 = R1C2;
653
            result.R2C2 = R2C2;
654
        }
655
        public static void Transpose(ref Matrix3d matrix, out Matrix3d result)
656
        {
657
            result.R0C0 = matrix.R0C0;
658
            result.R0C1 = matrix.R1C0;
659
            result.R0C2 = matrix.R2C0;
660
            result.R1C0 = matrix.R0C1;
661
            result.R1C1 = matrix.R1C1;
662
            result.R1C2 = matrix.R2C1;
663
            result.R2C0 = matrix.R0C2;
664
            result.R2C1 = matrix.R1C2;
665
            result.R2C2 = matrix.R2C2;
666
        }
667
 
668
        #endregion
669
 
670
        #region Transformation Functions
671
 
672
        public void Transform(ref Vector3d vector)
673
        {
674
            double x = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z;
675
            double y = R1C0 * vector.X + R1C1 * vector.Y + R1C2 * vector.Z;
676
            vector.Z = R2C0 * vector.X + R2C1 * vector.Y + R2C2 * vector.Z;
677
            vector.X = x;
678
            vector.Y = y;
679
        }
680
        public static void Transform(ref Matrix3d matrix, ref Vector3d vector)
681
        {
682
            double x = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z;
683
            double y = matrix.R1C0 * vector.X + matrix.R1C1 * vector.Y + matrix.R1C2 * vector.Z;
684
            vector.Z = matrix.R2C0 * vector.X + matrix.R2C1 * vector.Y + matrix.R2C2 * vector.Z;
685
            vector.X = x;
686
            vector.Y = y;
687
        }
688
        public void Transform(ref Vector3d vector, out Vector3d result)
689
        {
690
            result.X = R0C0 * vector.X + R0C1 * vector.Y + R0C2 * vector.Z;
691
            result.Y = R1C0 * vector.X + R1C1 * vector.Y + R1C2 * vector.Z;
692
            result.Z = R2C0 * vector.X + R2C1 * vector.Y + R2C2 * vector.Z;
693
        }
694
        public static void Transform(ref Matrix3d matrix, ref Vector3d vector, out Vector3d result)
695
        {
696
            result.X = matrix.R0C0 * vector.X + matrix.R0C1 * vector.Y + matrix.R0C2 * vector.Z;
697
            result.Y = matrix.R1C0 * vector.X + matrix.R1C1 * vector.Y + matrix.R1C2 * vector.Z;
698
            result.Z = matrix.R2C0 * vector.X + matrix.R2C1 * vector.Y + matrix.R2C2 * vector.Z;
699
        }
700
 
701
        public void Rotate(double angle)
702
        {
703
            double angleRadians = Functions.DTOR * angle;
704
            double sin = (double)System.Math.Sin(angleRadians);
705
            double cos = (double)System.Math.Cos(angleRadians);
706
 
707
            double r0c0 = cos * R0C0 + sin * R1C0;
708
            double r0c1 = cos * R0C1 + sin * R1C1;
709
            double r0c2 = cos * R0C2 + sin * R1C2;
710
 
711
            R1C0 = cos * R1C0 - sin * R0C0;
712
            R1C1 = cos * R1C1 - sin * R0C1;
713
            R1C2 = cos * R1C2 - sin * R0C2;
714
 
715
            R0C0 = r0c0;
716
            R0C1 = r0c1;
717
            R0C2 = r0c2;
718
        }
719
        public void Rotate(double angle, out Matrix3d result)
720
        {
721
            double angleRadians = Functions.DTOR * angle;
722
            double sin = (double)System.Math.Sin(angleRadians);
723
            double cos = (double)System.Math.Cos(angleRadians);
724
 
725
            result.R0C0 = cos * R0C0 + sin * R1C0;
726
            result.R0C1 = cos * R0C1 + sin * R1C1;
727
            result.R0C2 = cos * R0C2 + sin * R1C2;
728
            result.R1C0 = cos * R1C0 - sin * R0C0;
729
            result.R1C1 = cos * R1C1 - sin * R0C1;
730
            result.R1C2 = cos * R1C2 - sin * R0C2;
731
            result.R2C0 = R2C0;
732
            result.R2C1 = R2C1;
733
            result.R2C2 = R2C2;
734
        }
735
        public static void Rotate(ref Matrix3d matrix, double angle, out Matrix3d result)
736
        {
737
            double angleRadians = Functions.DTOR * angle;
738
            double sin = (double)System.Math.Sin(angleRadians);
739
            double cos = (double)System.Math.Cos(angleRadians);
740
 
741
            result.R0C0 = cos * matrix.R0C0 + sin * matrix.R1C0;
742
            result.R0C1 = cos * matrix.R0C1 + sin * matrix.R1C1;
743
            result.R0C2 = cos * matrix.R0C2 + sin * matrix.R1C2;
744
            result.R1C0 = cos * matrix.R1C0 - sin * matrix.R0C0;
745
            result.R1C1 = cos * matrix.R1C1 - sin * matrix.R0C1;
746
            result.R1C2 = cos * matrix.R1C2 - sin * matrix.R0C2;
747
            result.R2C0 = matrix.R2C0;
748
            result.R2C1 = matrix.R2C1;
749
            result.R2C2 = matrix.R2C2;
750
        }
751
        public static void RotateMatrix(double angle, out Matrix3d result)
752
        {
753
            double angleRadians = Functions.DTOR * angle;
754
            double sin = (double)System.Math.Sin(angleRadians);
755
            double cos = (double)System.Math.Cos(angleRadians);
756
 
757
            result.R0C0 = cos;
758
            result.R0C1 = sin;
759
            result.R0C2 = 0;
760
            result.R1C0 = -sin;
761
            result.R1C1 = cos;
762
            result.R1C2 = 0;
763
            result.R2C0 = 0;
764
            result.R2C1 = 0;
765
            result.R2C2 = 1;
766
        }
767
 
768
        public Quaterniond ToQuaternion()
769
        {
770
            //return new Quaterniond(ref this);
771
        }
772
 
773
        #endregion
774
 
775
        #region Constants
776
 
777
        /// <summary>The identity matrix.</summary>
778
        public static readonly Matrix3d Identity = new Matrix3d
779
        (
780
            1, 0, 0,
781
            0, 1, 0,
782
            0, 0, 1
783
        );
784
 
785
        /// <summary>A matrix of all zeros.</summary>
786
        public static readonly Matrix3d Zero = new Matrix3d
787
        (
788
            0, 0, 0,
789
            0, 0, 0,
790
            0, 0, 0
791
        );
792
 
793
        #endregion
794
 
795
        #region HashCode
796
 
797
        /// <summary>Returns the hash code for this instance.</summary>
798
        /// <returns>A 32-bit signed integer that is the hash code for this instance.</returns>
799
        public override int GetHashCode()
800
        {
801
            return
802
                R0C0.GetHashCode() ^ R0C1.GetHashCode() ^ R0C2.GetHashCode() ^
803
                R1C0.GetHashCode() ^ R1C1.GetHashCode() ^ R1C2.GetHashCode() ^
804
                R2C0.GetHashCode() ^ R2C1.GetHashCode() ^ R2C2.GetHashCode();
805
        }
806
 
807
        #endregion
808
 
809
        #region String
810
 
811
        /// <summary>Returns the fully qualified type name of this instance.</summary>
812
        /// <returns>A System.String containing left fully qualified type name.</returns>
813
        public override string ToString()
814
        {
815
            return String.Format(
816
                "|{00}, {01}, {02}|\n" +
817
                "|{03}, {04}, {05}|\n" +
818
                "|{06}, {07}, {18}|\n" +
819
                R0C0, R0C1, R0C2,
820
                R1C0, R1C1, R1C2,
821
                R2C0, R2C1, R2C2);
822
        }
823
 
824
        #endregion
825
    }
826
#endif
827
    #pragma warning restore 3019
828
}