• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

google / vector_math.dart / 13087264509

01 Feb 2025 09:20AM UTC coverage: 26.372%. Remained the same
13087264509

Pull #339

github

web-flow
Merge 4cc64e59c into bd4b574b2
Pull Request #339: Bump the github-actions group with 2 updates

4325 of 16400 relevant lines covered (26.37%)

1.2 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

0.0
/lib/src/vector_math_64/matrix3.dart
1
// Copyright (c) 2015, Google Inc. Please see the AUTHORS file for details.
2
// All rights reserved. Use of this source code is governed by a BSD-style
3
// license that can be found in the LICENSE file.
4

5
part of '../../vector_math_64.dart';
6

7
/// 3D Matrix.
8
/// Values are stored in column major order.
9
class Matrix3 {
10
  final Float64List _m3storage;
11

12
  /// The components of the matrix.
13
  Float64List get storage => _m3storage;
×
14

15
  /// Solve [A] * [x] = [b].
16
  static void solve2(Matrix3 A, Vector2 x, Vector2 b) {
×
17
    final a11 = A.entry(0, 0);
×
18
    final a12 = A.entry(0, 1);
×
19
    final a21 = A.entry(1, 0);
×
20
    final a22 = A.entry(1, 1);
×
21
    final bx = b.x - A.storage[6];
×
22
    final by = b.y - A.storage[7];
×
23
    var det = a11 * a22 - a12 * a21;
×
24

25
    if (det != 0.0) {
×
26
      det = 1.0 / det;
×
27
    }
28

29
    x
30
      ..x = det * (a22 * bx - a12 * by)
×
31
      ..y = det * (a11 * by - a21 * bx);
×
32
  }
33

34
  /// Solve [A] * [x] = [b].
35
  static void solve(Matrix3 A, Vector3 x, Vector3 b) {
×
36
    final A0x = A.entry(0, 0);
×
37
    final A0y = A.entry(1, 0);
×
38
    final A0z = A.entry(2, 0);
×
39
    final A1x = A.entry(0, 1);
×
40
    final A1y = A.entry(1, 1);
×
41
    final A1z = A.entry(2, 1);
×
42
    final A2x = A.entry(0, 2);
×
43
    final A2y = A.entry(1, 2);
×
44
    final A2z = A.entry(2, 2);
×
45
    double rx, ry, rz;
46
    double det;
47

48
    // Column1 cross Column 2
49
    rx = A1y * A2z - A1z * A2y;
×
50
    ry = A1z * A2x - A1x * A2z;
×
51
    rz = A1x * A2y - A1y * A2x;
×
52

53
    // A.getColumn(0).dot(x)
54
    det = A0x * rx + A0y * ry + A0z * rz;
×
55
    if (det != 0.0) {
×
56
      det = 1.0 / det;
×
57
    }
58

59
    // b dot [Column1 cross Column 2]
60
    final x_ = det * (b.x * rx + b.y * ry + b.z * rz);
×
61

62
    // Column2 cross b
63
    rx = -(A2y * b.z - A2z * b.y);
×
64
    ry = -(A2z * b.x - A2x * b.z);
×
65
    rz = -(A2x * b.y - A2y * b.x);
×
66
    // Column0 dot -[Column2 cross b (Column3)]
67
    final y_ = det * (A0x * rx + A0y * ry + A0z * rz);
×
68

69
    // b cross Column 1
70
    rx = -(b.y * A1z - b.z * A1y);
×
71
    ry = -(b.z * A1x - b.x * A1z);
×
72
    rz = -(b.x * A1y - b.y * A1x);
×
73
    // Column0 dot -[b cross Column 1]
74
    final z_ = det * (A0x * rx + A0y * ry + A0z * rz);
×
75

76
    x
77
      ..x = x_
×
78
      ..y = y_
×
79
      ..z = z_;
×
80
  }
81

82
  /// Return index in storage for [row], [col] value.
83
  int index(int row, int col) => (col * 3) + row;
×
84

85
  /// Value at [row], [col].
86
  double entry(int row, int col) {
×
87
    assert((row >= 0) && (row < dimension));
×
88
    assert((col >= 0) && (col < dimension));
×
89

90
    return _m3storage[index(row, col)];
×
91
  }
92

93
  /// Set value at [row], [col] to be [v].
94
  void setEntry(int row, int col, double v) {
×
95
    assert((row >= 0) && (row < dimension));
×
96
    assert((col >= 0) && (col < dimension));
×
97

98
    _m3storage[index(row, col)] = v;
×
99
  }
100

101
  /// New matrix with specified values.
102
  factory Matrix3(double arg0, double arg1, double arg2, double arg3,
×
103
          double arg4, double arg5, double arg6, double arg7, double arg8) =>
104
      Matrix3.zero()
×
105
        ..setValues(arg0, arg1, arg2, arg3, arg4, arg5, arg6, arg7, arg8);
×
106

107
  /// New matrix from [values].
108
  factory Matrix3.fromList(List<double> values) => Matrix3.zero()
×
109
    ..setValues(values[0], values[1], values[2], values[3], values[4],
×
110
        values[5], values[6], values[7], values[8]);
×
111

112
  /// Constructs a new [Matrix3] filled with zeros.
113
  Matrix3.zero() : _m3storage = Float64List(9);
×
114

115
  /// Identity matrix.
116
  factory Matrix3.identity() => Matrix3.zero()..setIdentity();
×
117

118
  /// Copes values from [other].
119
  factory Matrix3.copy(Matrix3 other) => Matrix3.zero()..setFrom(other);
×
120

121
  /// Constructs a new mat3 from columns.
122
  factory Matrix3.columns(Vector3 arg0, Vector3 arg1, Vector3 arg2) =>
×
123
      Matrix3.zero()..setColumns(arg0, arg1, arg2);
×
124

125
  /// Outer product of [u] and [v].
126
  factory Matrix3.outer(Vector3 u, Vector3 v) => Matrix3.zero()..setOuter(u, v);
×
127

128
  /// Rotation of [radians] around X axis.
129
  factory Matrix3.rotationX(double radians) =>
×
130
      Matrix3.zero()..setRotationX(radians);
×
131

132
  /// Rotation of [radians] around Y axis.
133
  factory Matrix3.rotationY(double radians) =>
×
134
      Matrix3.zero()..setRotationY(radians);
×
135

136
  /// Rotation of [radians] around Z axis.
137
  factory Matrix3.rotationZ(double radians) =>
×
138
      Matrix3.zero()..setRotationZ(radians);
×
139

140
  /// Sets the matrix with specified values.
141
  void setValues(double arg0, double arg1, double arg2, double arg3,
×
142
      double arg4, double arg5, double arg6, double arg7, double arg8) {
143
    _m3storage[8] = arg8;
×
144
    _m3storage[7] = arg7;
×
145
    _m3storage[6] = arg6;
×
146
    _m3storage[5] = arg5;
×
147
    _m3storage[4] = arg4;
×
148
    _m3storage[3] = arg3;
×
149
    _m3storage[2] = arg2;
×
150
    _m3storage[1] = arg1;
×
151
    _m3storage[0] = arg0;
×
152
  }
153

154
  /// Sets the entire matrix to the column values.
155
  void setColumns(Vector3 arg0, Vector3 arg1, Vector3 arg2) {
×
156
    final arg0Storage = arg0._v3storage;
×
157
    final arg1Storage = arg1._v3storage;
×
158
    final arg2Storage = arg2._v3storage;
×
159
    _m3storage[0] = arg0Storage[0];
×
160
    _m3storage[1] = arg0Storage[1];
×
161
    _m3storage[2] = arg0Storage[2];
×
162
    _m3storage[3] = arg1Storage[0];
×
163
    _m3storage[4] = arg1Storage[1];
×
164
    _m3storage[5] = arg1Storage[2];
×
165
    _m3storage[6] = arg2Storage[0];
×
166
    _m3storage[7] = arg2Storage[1];
×
167
    _m3storage[8] = arg2Storage[2];
×
168
  }
169

170
  /// Sets the entire matrix to the matrix in [arg].
171
  void setFrom(Matrix3 arg) {
×
172
    final argStorage = arg._m3storage;
×
173
    _m3storage[8] = argStorage[8];
×
174
    _m3storage[7] = argStorage[7];
×
175
    _m3storage[6] = argStorage[6];
×
176
    _m3storage[5] = argStorage[5];
×
177
    _m3storage[4] = argStorage[4];
×
178
    _m3storage[3] = argStorage[3];
×
179
    _m3storage[2] = argStorage[2];
×
180
    _m3storage[1] = argStorage[1];
×
181
    _m3storage[0] = argStorage[0];
×
182
  }
183

184
  /// Set this to the outer product of [u] and [v].
185
  void setOuter(Vector3 u, Vector3 v) {
×
186
    final uStorage = u._v3storage;
×
187
    final vStorage = v._v3storage;
×
188
    _m3storage[0] = uStorage[0] * vStorage[0];
×
189
    _m3storage[1] = uStorage[0] * vStorage[1];
×
190
    _m3storage[2] = uStorage[0] * vStorage[2];
×
191
    _m3storage[3] = uStorage[1] * vStorage[0];
×
192
    _m3storage[4] = uStorage[1] * vStorage[1];
×
193
    _m3storage[5] = uStorage[1] * vStorage[2];
×
194
    _m3storage[6] = uStorage[2] * vStorage[0];
×
195
    _m3storage[7] = uStorage[2] * vStorage[1];
×
196
    _m3storage[8] = uStorage[2] * vStorage[2];
×
197
  }
198

199
  /// Set the diagonal of the matrix.
200
  void splatDiagonal(double arg) {
×
201
    _m3storage[0] = arg;
×
202
    _m3storage[4] = arg;
×
203
    _m3storage[8] = arg;
×
204
  }
205

206
  /// Set the diagonal of the matrix.
207
  void setDiagonal(Vector3 arg) {
×
208
    _m3storage[0] = arg.storage[0];
×
209
    _m3storage[4] = arg.storage[1];
×
210
    _m3storage[8] = arg.storage[2];
×
211
  }
212

213
  /// Sets the upper 2x2 of the matrix to be [arg].
214
  void setUpper2x2(Matrix2 arg) {
×
215
    final argStorage = arg._m2storage;
×
216
    _m3storage[0] = argStorage[0];
×
217
    _m3storage[1] = argStorage[1];
×
218
    _m3storage[3] = argStorage[2];
×
219
    _m3storage[4] = argStorage[3];
×
220
  }
221

222
  /// Returns a printable string
223
  @override
×
224
  String toString() => '[0] ${getRow(0)}\n[1] ${getRow(1)}\n[2] ${getRow(2)}\n';
×
225

226
  /// Dimension of the matrix.
227
  int get dimension => 3;
×
228

229
  /// Access the element of the matrix at the index [i].
230
  double operator [](int i) => _m3storage[i];
×
231

232
  /// Set the element of the matrix at the index [i].
233
  void operator []=(int i, double v) {
×
234
    _m3storage[i] = v;
×
235
  }
236

237
  /// Check if two matrices are the same.
238
  @override
×
239
  bool operator ==(Object other) =>
240
      (other is Matrix3) &&
×
241
      (_m3storage[0] == other._m3storage[0]) &&
×
242
      (_m3storage[1] == other._m3storage[1]) &&
×
243
      (_m3storage[2] == other._m3storage[2]) &&
×
244
      (_m3storage[3] == other._m3storage[3]) &&
×
245
      (_m3storage[4] == other._m3storage[4]) &&
×
246
      (_m3storage[5] == other._m3storage[5]) &&
×
247
      (_m3storage[6] == other._m3storage[6]) &&
×
248
      (_m3storage[7] == other._m3storage[7]) &&
×
249
      (_m3storage[8] == other._m3storage[8]);
×
250

251
  @override
×
252
  int get hashCode => Object.hashAll(_m3storage);
×
253

254
  /// Returns row 0
255
  Vector3 get row0 => getRow(0);
×
256

257
  /// Returns row 1
258
  Vector3 get row1 => getRow(1);
×
259

260
  /// Returns row 2
261
  Vector3 get row2 => getRow(2);
×
262

263
  /// Sets row 0 to [arg]
264
  set row0(Vector3 arg) => setRow(0, arg);
×
265

266
  /// Sets row 1 to [arg]
267
  set row1(Vector3 arg) => setRow(1, arg);
×
268

269
  /// Sets row 2 to [arg]
270
  set row2(Vector3 arg) => setRow(2, arg);
×
271

272
  /// Assigns the [row] of to [arg].
273
  void setRow(int row, Vector3 arg) {
×
274
    final argStorage = arg._v3storage;
×
275
    _m3storage[index(row, 0)] = argStorage[0];
×
276
    _m3storage[index(row, 1)] = argStorage[1];
×
277
    _m3storage[index(row, 2)] = argStorage[2];
×
278
  }
279

280
  /// Gets the [row] of the matrix
281
  Vector3 getRow(int row) {
×
282
    final r = Vector3.zero();
×
283
    final rStorage = r._v3storage;
×
284
    rStorage[0] = _m3storage[index(row, 0)];
×
285
    rStorage[1] = _m3storage[index(row, 1)];
×
286
    rStorage[2] = _m3storage[index(row, 2)];
×
287
    return r;
288
  }
289

290
  /// Assigns the [column] of the matrix [arg]
291
  void setColumn(int column, Vector3 arg) {
×
292
    final argStorage = arg._v3storage;
×
293
    final entry = column * 3;
×
294
    _m3storage[entry + 2] = argStorage[2];
×
295
    _m3storage[entry + 1] = argStorage[1];
×
296
    _m3storage[entry + 0] = argStorage[0];
×
297
  }
298

299
  /// Gets the [column] of the matrix
300
  Vector3 getColumn(int column) {
×
301
    final r = Vector3.zero();
×
302
    final rStorage = r._v3storage;
×
303
    final entry = column * 3;
×
304
    rStorage[2] = _m3storage[entry + 2];
×
305
    rStorage[1] = _m3storage[entry + 1];
×
306
    rStorage[0] = _m3storage[entry + 0];
×
307
    return r;
308
  }
309

310
  /// Clone of this.
311
  Matrix3 clone() => Matrix3.copy(this);
×
312

313
  /// Copy this into [arg].
314
  Matrix3 copyInto(Matrix3 arg) {
×
315
    final argStorage = arg._m3storage;
×
316
    argStorage[0] = _m3storage[0];
×
317
    argStorage[1] = _m3storage[1];
×
318
    argStorage[2] = _m3storage[2];
×
319
    argStorage[3] = _m3storage[3];
×
320
    argStorage[4] = _m3storage[4];
×
321
    argStorage[5] = _m3storage[5];
×
322
    argStorage[6] = _m3storage[6];
×
323
    argStorage[7] = _m3storage[7];
×
324
    argStorage[8] = _m3storage[8];
×
325
    return arg;
326
  }
327

328
  /// Returns a new vector or matrix by multiplying this with [arg].
329
  dynamic operator *(dynamic arg) {
×
330
    if (arg is double) {
×
331
      return scaled(arg);
×
332
    }
333
    if (arg is Vector3) {
×
334
      return transformed(arg);
×
335
    }
336
    if (arg is Matrix3) {
×
337
      return multiplied(arg);
×
338
    }
339
    throw ArgumentError(arg);
×
340
  }
341

342
  /// Returns new matrix after component wise this + [arg]
343
  Matrix3 operator +(Matrix3 arg) => clone()..add(arg);
×
344

345
  /// Returns new matrix after component wise this - [arg]
346
  Matrix3 operator -(Matrix3 arg) => clone()..sub(arg);
×
347

348
  /// Returns new matrix -this
349
  Matrix3 operator -() => clone()..negate();
×
350

351
  /// Zeros this.
352
  void setZero() {
×
353
    _m3storage[0] = 0.0;
×
354
    _m3storage[1] = 0.0;
×
355
    _m3storage[2] = 0.0;
×
356
    _m3storage[3] = 0.0;
×
357
    _m3storage[4] = 0.0;
×
358
    _m3storage[5] = 0.0;
×
359
    _m3storage[6] = 0.0;
×
360
    _m3storage[7] = 0.0;
×
361
    _m3storage[8] = 0.0;
×
362
  }
363

364
  /// Makes this into the identity matrix.
365
  void setIdentity() {
×
366
    _m3storage[0] = 1.0;
×
367
    _m3storage[1] = 0.0;
×
368
    _m3storage[2] = 0.0;
×
369
    _m3storage[3] = 0.0;
×
370
    _m3storage[4] = 1.0;
×
371
    _m3storage[5] = 0.0;
×
372
    _m3storage[6] = 0.0;
×
373
    _m3storage[7] = 0.0;
×
374
    _m3storage[8] = 1.0;
×
375
  }
376

377
  /// Returns the tranpose of this.
378
  Matrix3 transposed() => clone()..transpose();
×
379

380
  /// Transpose this.
381
  void transpose() {
×
382
    double temp;
383
    temp = _m3storage[3];
×
384
    _m3storage[3] = _m3storage[1];
×
385
    _m3storage[1] = temp;
×
386
    temp = _m3storage[6];
×
387
    _m3storage[6] = _m3storage[2];
×
388
    _m3storage[2] = temp;
×
389
    temp = _m3storage[7];
×
390
    _m3storage[7] = _m3storage[5];
×
391
    _m3storage[5] = temp;
×
392
  }
393

394
  /// Returns the component wise absolute value of this.
395
  Matrix3 absolute() {
×
396
    final r = Matrix3.zero();
×
397
    final rStorage = r._m3storage;
×
398
    rStorage[0] = _m3storage[0].abs();
×
399
    rStorage[1] = _m3storage[1].abs();
×
400
    rStorage[2] = _m3storage[2].abs();
×
401
    rStorage[3] = _m3storage[3].abs();
×
402
    rStorage[4] = _m3storage[4].abs();
×
403
    rStorage[5] = _m3storage[5].abs();
×
404
    rStorage[6] = _m3storage[6].abs();
×
405
    rStorage[7] = _m3storage[7].abs();
×
406
    rStorage[8] = _m3storage[8].abs();
×
407
    return r;
408
  }
409

410
  /// Returns the determinant of this matrix.
411
  double determinant() {
×
412
    final x = _m3storage[0] *
×
413
        ((_m3storage[4] * _m3storage[8]) - (_m3storage[5] * _m3storage[7]));
×
414
    final y = _m3storage[1] *
×
415
        ((_m3storage[3] * _m3storage[8]) - (_m3storage[5] * _m3storage[6]));
×
416
    final z = _m3storage[2] *
×
417
        ((_m3storage[3] * _m3storage[7]) - (_m3storage[4] * _m3storage[6]));
×
418
    return x - y + z;
×
419
  }
420

421
  /// Returns the dot product of row [i] and [v].
422
  double dotRow(int i, Vector3 v) {
×
423
    final vStorage = v._v3storage;
×
424
    return _m3storage[i] * vStorage[0] +
×
425
        _m3storage[3 + i] * vStorage[1] +
×
426
        _m3storage[6 + i] * vStorage[2];
×
427
  }
428

429
  /// Returns the dot product of column [j] and [v].
430
  double dotColumn(int j, Vector3 v) {
×
431
    final vStorage = v._v3storage;
×
432
    return _m3storage[j * 3] * vStorage[0] +
×
433
        _m3storage[j * 3 + 1] * vStorage[1] +
×
434
        _m3storage[j * 3 + 2] * vStorage[2];
×
435
  }
436

437
  /// Returns the trace of the matrix. The trace of a matrix is the sum of
438
  /// the diagonal entries.
439
  double trace() {
×
440
    var t = 0.0;
441
    t += _m3storage[0];
×
442
    t += _m3storage[4];
×
443
    t += _m3storage[8];
×
444
    return t;
445
  }
446

447
  /// Returns infinity norm of the matrix. Used for numerical analysis.
448
  double infinityNorm() {
×
449
    var norm = 0.0;
450
    {
451
      var row_norm = 0.0;
452
      row_norm += _m3storage[0].abs();
×
453
      row_norm += _m3storage[1].abs();
×
454
      row_norm += _m3storage[2].abs();
×
455
      norm = row_norm > norm ? row_norm : norm;
×
456
    }
457
    {
458
      var row_norm = 0.0;
459
      row_norm += _m3storage[3].abs();
×
460
      row_norm += _m3storage[4].abs();
×
461
      row_norm += _m3storage[5].abs();
×
462
      norm = row_norm > norm ? row_norm : norm;
×
463
    }
464
    {
465
      var row_norm = 0.0;
466
      row_norm += _m3storage[6].abs();
×
467
      row_norm += _m3storage[7].abs();
×
468
      row_norm += _m3storage[8].abs();
×
469
      norm = row_norm > norm ? row_norm : norm;
×
470
    }
471
    return norm;
472
  }
473

474
  /// Returns relative error between this and [correct]
475
  double relativeError(Matrix3 correct) {
×
476
    final diff = correct - this;
×
477
    final correct_norm = correct.infinityNorm();
×
478
    final diff_norm = diff.infinityNorm();
×
479
    return diff_norm / correct_norm;
×
480
  }
481

482
  /// Returns absolute error between this and [correct]
483
  double absoluteError(Matrix3 correct) {
×
484
    final this_norm = infinityNorm();
×
485
    final correct_norm = correct.infinityNorm();
×
486
    final diff_norm = (this_norm - correct_norm).abs();
×
487
    return diff_norm;
488
  }
489

490
  /// Invert the matrix. Returns the determinant.
491
  double invert() => copyInverse(this);
×
492

493
  /// Set this matrix to be the inverse of [arg]
494
  double copyInverse(Matrix3 arg) {
×
495
    final det = arg.determinant();
×
496
    if (det == 0.0) {
×
497
      setFrom(arg);
×
498
      return 0.0;
499
    }
500
    final invDet = 1.0 / det;
×
501
    final argStorage = arg._m3storage;
×
502
    final ix = invDet *
×
503
        (argStorage[4] * argStorage[8] - argStorage[5] * argStorage[7]);
×
504
    final iy = invDet *
×
505
        (argStorage[2] * argStorage[7] - argStorage[1] * argStorage[8]);
×
506
    final iz = invDet *
×
507
        (argStorage[1] * argStorage[5] - argStorage[2] * argStorage[4]);
×
508
    final jx = invDet *
×
509
        (argStorage[5] * argStorage[6] - argStorage[3] * argStorage[8]);
×
510
    final jy = invDet *
×
511
        (argStorage[0] * argStorage[8] - argStorage[2] * argStorage[6]);
×
512
    final jz = invDet *
×
513
        (argStorage[2] * argStorage[3] - argStorage[0] * argStorage[5]);
×
514
    final kx = invDet *
×
515
        (argStorage[3] * argStorage[7] - argStorage[4] * argStorage[6]);
×
516
    final ky = invDet *
×
517
        (argStorage[1] * argStorage[6] - argStorage[0] * argStorage[7]);
×
518
    final kz = invDet *
×
519
        (argStorage[0] * argStorage[4] - argStorage[1] * argStorage[3]);
×
520
    _m3storage[0] = ix;
×
521
    _m3storage[1] = iy;
×
522
    _m3storage[2] = iz;
×
523
    _m3storage[3] = jx;
×
524
    _m3storage[4] = jy;
×
525
    _m3storage[5] = jz;
×
526
    _m3storage[6] = kx;
×
527
    _m3storage[7] = ky;
×
528
    _m3storage[8] = kz;
×
529
    return det;
530
  }
531

532
  /// Set this matrix to be the normal matrix of [arg].
533
  void copyNormalMatrix(Matrix4 arg) {
×
534
    copyInverse(arg.getRotation());
×
535
    transpose();
×
536
  }
537

538
  /// Turns the matrix into a rotation of [radians] around X
539
  void setRotationX(double radians) {
×
540
    final c = math.cos(radians);
×
541
    final s = math.sin(radians);
×
542
    _m3storage[0] = 1.0;
×
543
    _m3storage[1] = 0.0;
×
544
    _m3storage[2] = 0.0;
×
545
    _m3storage[3] = 0.0;
×
546
    _m3storage[4] = c;
×
547
    _m3storage[5] = s;
×
548
    _m3storage[6] = 0.0;
×
549
    _m3storage[7] = -s;
×
550
    _m3storage[8] = c;
×
551
  }
552

553
  /// Turns the matrix into a rotation of [radians] around Y
554
  void setRotationY(double radians) {
×
555
    final c = math.cos(radians);
×
556
    final s = math.sin(radians);
×
557
    _m3storage[0] = c;
×
558
    _m3storage[1] = 0.0;
×
559
    _m3storage[2] = -s;
×
560
    _m3storage[3] = 0.0;
×
561
    _m3storage[4] = 1.0;
×
562
    _m3storage[5] = 0.0;
×
563
    _m3storage[6] = s;
×
564
    _m3storage[7] = 0.0;
×
565
    _m3storage[8] = c;
×
566
  }
567

568
  /// Turns the matrix into a rotation of [radians] around Z
569
  void setRotationZ(double radians) {
×
570
    final c = math.cos(radians);
×
571
    final s = math.sin(radians);
×
572
    _m3storage[0] = c;
×
573
    _m3storage[1] = s;
×
574
    _m3storage[2] = 0.0;
×
575
    _m3storage[3] = -s;
×
576
    _m3storage[4] = c;
×
577
    _m3storage[5] = 0.0;
×
578
    _m3storage[6] = 0.0;
×
579
    _m3storage[7] = 0.0;
×
580
    _m3storage[8] = 1.0;
×
581
  }
582

583
  /// Converts into Adjugate matrix and scales by [scale]
584
  void scaleAdjoint(double scale) {
×
585
    final m00 = _m3storage[0];
×
586
    final m01 = _m3storage[3];
×
587
    final m02 = _m3storage[6];
×
588
    final m10 = _m3storage[1];
×
589
    final m11 = _m3storage[4];
×
590
    final m12 = _m3storage[7];
×
591
    final m20 = _m3storage[2];
×
592
    final m21 = _m3storage[5];
×
593
    final m22 = _m3storage[8];
×
594
    _m3storage[0] = (m11 * m22 - m12 * m21) * scale;
×
595
    _m3storage[1] = (m12 * m20 - m10 * m22) * scale;
×
596
    _m3storage[2] = (m10 * m21 - m11 * m20) * scale;
×
597
    _m3storage[3] = (m02 * m21 - m01 * m22) * scale;
×
598
    _m3storage[4] = (m00 * m22 - m02 * m20) * scale;
×
599
    _m3storage[5] = (m01 * m20 - m00 * m21) * scale;
×
600
    _m3storage[6] = (m01 * m12 - m02 * m11) * scale;
×
601
    _m3storage[7] = (m02 * m10 - m00 * m12) * scale;
×
602
    _m3storage[8] = (m00 * m11 - m01 * m10) * scale;
×
603
  }
604

605
  /// Rotates [arg] by the absolute rotation of this
606
  /// Returns [arg].
607
  /// Primarily used by AABB transformation code.
608
  Vector3 absoluteRotate(Vector3 arg) {
×
609
    final m00 = _m3storage[0].abs();
×
610
    final m01 = _m3storage[3].abs();
×
611
    final m02 = _m3storage[6].abs();
×
612
    final m10 = _m3storage[1].abs();
×
613
    final m11 = _m3storage[4].abs();
×
614
    final m12 = _m3storage[7].abs();
×
615
    final m20 = _m3storage[2].abs();
×
616
    final m21 = _m3storage[5].abs();
×
617
    final m22 = _m3storage[8].abs();
×
618
    final argStorage = arg._v3storage;
×
619
    final x = argStorage[0];
×
620
    final y = argStorage[1];
×
621
    final z = argStorage[2];
×
622
    argStorage[0] = x * m00 + y * m01 + z * m02;
×
623
    argStorage[1] = x * m10 + y * m11 + z * m12;
×
624
    argStorage[2] = x * m20 + y * m21 + z * m22;
×
625
    return arg;
626
  }
627

628
  /// Rotates [arg] by the absolute rotation of this
629
  /// Returns [arg].
630
  /// Primarily used by AABB transformation code.
631
  Vector2 absoluteRotate2(Vector2 arg) {
×
632
    final m00 = _m3storage[0].abs();
×
633
    final m01 = _m3storage[3].abs();
×
634
    final m10 = _m3storage[1].abs();
×
635
    final m11 = _m3storage[4].abs();
×
636
    final argStorage = arg._v2storage;
×
637
    final x = argStorage[0];
×
638
    final y = argStorage[1];
×
639
    argStorage[0] = x * m00 + y * m01;
×
640
    argStorage[1] = x * m10 + y * m11;
×
641
    return arg;
642
  }
643

644
  /// Transforms [arg] with this.
645
  Vector2 transform2(Vector2 arg) {
×
646
    final argStorage = arg._v2storage;
×
647
    final x_ = (_m3storage[0] * argStorage[0]) +
×
648
        (_m3storage[3] * argStorage[1]) +
×
649
        _m3storage[6];
×
650
    final y_ = (_m3storage[1] * argStorage[0]) +
×
651
        (_m3storage[4] * argStorage[1]) +
×
652
        _m3storage[7];
×
653
    argStorage[0] = x_;
×
654
    argStorage[1] = y_;
×
655
    return arg;
656
  }
657

658
  /// Scales this by [scale].
659
  void scale(double scale) {
×
660
    _m3storage[0] = _m3storage[0] * scale;
×
661
    _m3storage[1] = _m3storage[1] * scale;
×
662
    _m3storage[2] = _m3storage[2] * scale;
×
663
    _m3storage[3] = _m3storage[3] * scale;
×
664
    _m3storage[4] = _m3storage[4] * scale;
×
665
    _m3storage[5] = _m3storage[5] * scale;
×
666
    _m3storage[6] = _m3storage[6] * scale;
×
667
    _m3storage[7] = _m3storage[7] * scale;
×
668
    _m3storage[8] = _m3storage[8] * scale;
×
669
  }
670

671
  /// Create a copy of this and scale it by [scale].
672
  Matrix3 scaled(double scale) => clone()..scale(scale);
×
673

674
  /// Add [o] to this.
675
  void add(Matrix3 o) {
×
676
    final oStorage = o._m3storage;
×
677
    _m3storage[0] = _m3storage[0] + oStorage[0];
×
678
    _m3storage[1] = _m3storage[1] + oStorage[1];
×
679
    _m3storage[2] = _m3storage[2] + oStorage[2];
×
680
    _m3storage[3] = _m3storage[3] + oStorage[3];
×
681
    _m3storage[4] = _m3storage[4] + oStorage[4];
×
682
    _m3storage[5] = _m3storage[5] + oStorage[5];
×
683
    _m3storage[6] = _m3storage[6] + oStorage[6];
×
684
    _m3storage[7] = _m3storage[7] + oStorage[7];
×
685
    _m3storage[8] = _m3storage[8] + oStorage[8];
×
686
  }
687

688
  /// Subtract [o] from this.
689
  void sub(Matrix3 o) {
×
690
    final oStorage = o._m3storage;
×
691
    _m3storage[0] = _m3storage[0] - oStorage[0];
×
692
    _m3storage[1] = _m3storage[1] - oStorage[1];
×
693
    _m3storage[2] = _m3storage[2] - oStorage[2];
×
694
    _m3storage[3] = _m3storage[3] - oStorage[3];
×
695
    _m3storage[4] = _m3storage[4] - oStorage[4];
×
696
    _m3storage[5] = _m3storage[5] - oStorage[5];
×
697
    _m3storage[6] = _m3storage[6] - oStorage[6];
×
698
    _m3storage[7] = _m3storage[7] - oStorage[7];
×
699
    _m3storage[8] = _m3storage[8] - oStorage[8];
×
700
  }
701

702
  /// Negate this.
703
  void negate() {
×
704
    _m3storage[0] = -_m3storage[0];
×
705
    _m3storage[1] = -_m3storage[1];
×
706
    _m3storage[2] = -_m3storage[2];
×
707
    _m3storage[3] = -_m3storage[3];
×
708
    _m3storage[4] = -_m3storage[4];
×
709
    _m3storage[5] = -_m3storage[5];
×
710
    _m3storage[6] = -_m3storage[6];
×
711
    _m3storage[7] = -_m3storage[7];
×
712
    _m3storage[8] = -_m3storage[8];
×
713
  }
714

715
  /// Multiply this by [arg].
716
  void multiply(Matrix3 arg) {
×
717
    final m00 = _m3storage[0];
×
718
    final m01 = _m3storage[3];
×
719
    final m02 = _m3storage[6];
×
720
    final m10 = _m3storage[1];
×
721
    final m11 = _m3storage[4];
×
722
    final m12 = _m3storage[7];
×
723
    final m20 = _m3storage[2];
×
724
    final m21 = _m3storage[5];
×
725
    final m22 = _m3storage[8];
×
726
    final argStorage = arg._m3storage;
×
727
    final n00 = argStorage[0];
×
728
    final n01 = argStorage[3];
×
729
    final n02 = argStorage[6];
×
730
    final n10 = argStorage[1];
×
731
    final n11 = argStorage[4];
×
732
    final n12 = argStorage[7];
×
733
    final n20 = argStorage[2];
×
734
    final n21 = argStorage[5];
×
735
    final n22 = argStorage[8];
×
736
    _m3storage[0] = (m00 * n00) + (m01 * n10) + (m02 * n20);
×
737
    _m3storage[3] = (m00 * n01) + (m01 * n11) + (m02 * n21);
×
738
    _m3storage[6] = (m00 * n02) + (m01 * n12) + (m02 * n22);
×
739
    _m3storage[1] = (m10 * n00) + (m11 * n10) + (m12 * n20);
×
740
    _m3storage[4] = (m10 * n01) + (m11 * n11) + (m12 * n21);
×
741
    _m3storage[7] = (m10 * n02) + (m11 * n12) + (m12 * n22);
×
742
    _m3storage[2] = (m20 * n00) + (m21 * n10) + (m22 * n20);
×
743
    _m3storage[5] = (m20 * n01) + (m21 * n11) + (m22 * n21);
×
744
    _m3storage[8] = (m20 * n02) + (m21 * n12) + (m22 * n22);
×
745
  }
746

747
  /// Create a copy of this and multiply it by [arg].
748
  Matrix3 multiplied(Matrix3 arg) => clone()..multiply(arg);
×
749

750
  void transposeMultiply(Matrix3 arg) {
×
751
    final m00 = _m3storage[0];
×
752
    final m01 = _m3storage[1];
×
753
    final m02 = _m3storage[2];
×
754
    final m10 = _m3storage[3];
×
755
    final m11 = _m3storage[4];
×
756
    final m12 = _m3storage[5];
×
757
    final m20 = _m3storage[6];
×
758
    final m21 = _m3storage[7];
×
759
    final m22 = _m3storage[8];
×
760
    final argStorage = arg._m3storage;
×
761
    _m3storage[0] =
×
762
        (m00 * argStorage[0]) + (m01 * argStorage[1]) + (m02 * argStorage[2]);
×
763
    _m3storage[3] =
×
764
        (m00 * argStorage[3]) + (m01 * argStorage[4]) + (m02 * argStorage[5]);
×
765
    _m3storage[6] =
×
766
        (m00 * argStorage[6]) + (m01 * argStorage[7]) + (m02 * argStorage[8]);
×
767
    _m3storage[1] =
×
768
        (m10 * argStorage[0]) + (m11 * argStorage[1]) + (m12 * argStorage[2]);
×
769
    _m3storage[4] =
×
770
        (m10 * argStorage[3]) + (m11 * argStorage[4]) + (m12 * argStorage[5]);
×
771
    _m3storage[7] =
×
772
        (m10 * argStorage[6]) + (m11 * argStorage[7]) + (m12 * argStorage[8]);
×
773
    _m3storage[2] =
×
774
        (m20 * argStorage[0]) + (m21 * argStorage[1]) + (m22 * argStorage[2]);
×
775
    _m3storage[5] =
×
776
        (m20 * argStorage[3]) + (m21 * argStorage[4]) + (m22 * argStorage[5]);
×
777
    _m3storage[8] =
×
778
        (m20 * argStorage[6]) + (m21 * argStorage[7]) + (m22 * argStorage[8]);
×
779
  }
780

781
  void multiplyTranspose(Matrix3 arg) {
×
782
    final m00 = _m3storage[0];
×
783
    final m01 = _m3storage[3];
×
784
    final m02 = _m3storage[6];
×
785
    final m10 = _m3storage[1];
×
786
    final m11 = _m3storage[4];
×
787
    final m12 = _m3storage[7];
×
788
    final m20 = _m3storage[2];
×
789
    final m21 = _m3storage[5];
×
790
    final m22 = _m3storage[8];
×
791
    final argStorage = arg._m3storage;
×
792
    _m3storage[0] =
×
793
        (m00 * argStorage[0]) + (m01 * argStorage[3]) + (m02 * argStorage[6]);
×
794
    _m3storage[3] =
×
795
        (m00 * argStorage[1]) + (m01 * argStorage[4]) + (m02 * argStorage[7]);
×
796
    _m3storage[6] =
×
797
        (m00 * argStorage[2]) + (m01 * argStorage[5]) + (m02 * argStorage[8]);
×
798
    _m3storage[1] =
×
799
        (m10 * argStorage[0]) + (m11 * argStorage[3]) + (m12 * argStorage[6]);
×
800
    _m3storage[4] =
×
801
        (m10 * argStorage[1]) + (m11 * argStorage[4]) + (m12 * argStorage[7]);
×
802
    _m3storage[7] =
×
803
        (m10 * argStorage[2]) + (m11 * argStorage[5]) + (m12 * argStorage[8]);
×
804
    _m3storage[2] =
×
805
        (m20 * argStorage[0]) + (m21 * argStorage[3]) + (m22 * argStorage[6]);
×
806
    _m3storage[5] =
×
807
        (m20 * argStorage[1]) + (m21 * argStorage[4]) + (m22 * argStorage[7]);
×
808
    _m3storage[8] =
×
809
        (m20 * argStorage[2]) + (m21 * argStorage[5]) + (m22 * argStorage[8]);
×
810
  }
811

812
  /// Transform [arg] of type [Vector3] using the transformation defined by
813
  /// this.
814
  Vector3 transform(Vector3 arg) {
×
815
    final argStorage = arg._v3storage;
×
816
    final x_ = (_m3storage[0] * argStorage[0]) +
×
817
        (_m3storage[3] * argStorage[1]) +
×
818
        (_m3storage[6] * argStorage[2]);
×
819
    final y_ = (_m3storage[1] * argStorage[0]) +
×
820
        (_m3storage[4] * argStorage[1]) +
×
821
        (_m3storage[7] * argStorage[2]);
×
822
    final z_ = (_m3storage[2] * argStorage[0]) +
×
823
        (_m3storage[5] * argStorage[1]) +
×
824
        (_m3storage[8] * argStorage[2]);
×
825
    arg
826
      ..x = x_
×
827
      ..y = y_
×
828
      ..z = z_;
×
829
    return arg;
830
  }
831

832
  /// Transform a copy of [arg] of type [Vector3] using the transformation
833
  /// defined by this. If a [out] parameter is supplied, the copy is stored in
834
  /// [out].
835
  Vector3 transformed(Vector3 arg, [Vector3? out]) {
×
836
    if (out == null) {
837
      out = Vector3.copy(arg);
×
838
    } else {
839
      out.setFrom(arg);
×
840
    }
841
    return transform(out);
×
842
  }
843

844
  /// Copies this into [array] starting at [offset].
845
  void copyIntoArray(List<num> array, [int offset = 0]) {
×
846
    final i = offset;
847
    array[i + 8] = _m3storage[8];
×
848
    array[i + 7] = _m3storage[7];
×
849
    array[i + 6] = _m3storage[6];
×
850
    array[i + 5] = _m3storage[5];
×
851
    array[i + 4] = _m3storage[4];
×
852
    array[i + 3] = _m3storage[3];
×
853
    array[i + 2] = _m3storage[2];
×
854
    array[i + 1] = _m3storage[1];
×
855
    array[i + 0] = _m3storage[0];
×
856
  }
857

858
  /// Copies elements from [array] into this starting at [offset].
859
  void copyFromArray(List<double> array, [int offset = 0]) {
×
860
    final i = offset;
861
    _m3storage[8] = array[i + 8];
×
862
    _m3storage[7] = array[i + 7];
×
863
    _m3storage[6] = array[i + 6];
×
864
    _m3storage[5] = array[i + 5];
×
865
    _m3storage[4] = array[i + 4];
×
866
    _m3storage[3] = array[i + 3];
×
867
    _m3storage[2] = array[i + 2];
×
868
    _m3storage[1] = array[i + 1];
×
869
    _m3storage[0] = array[i + 0];
×
870
  }
871

872
  /// Multiply this to each set of xyz values in [array] starting at [offset].
873
  List<double> applyToVector3Array(List<double> array, [int offset = 0]) {
×
874
    for (var i = 0, j = offset; i < array.length; i += 3, j += 3) {
×
875
      final v = Vector3.array(array, j)..applyMatrix3(this);
×
876
      array[j] = v.storage[0];
×
877
      array[j + 1] = v.storage[1];
×
878
      array[j + 2] = v.storage[2];
×
879
    }
880

881
    return array;
882
  }
883

884
  Vector3 get right {
×
885
    final x = _m3storage[0];
×
886
    final y = _m3storage[1];
×
887
    final z = _m3storage[2];
×
888
    return Vector3(x, y, z);
×
889
  }
890

891
  Vector3 get up {
×
892
    final x = _m3storage[3];
×
893
    final y = _m3storage[4];
×
894
    final z = _m3storage[5];
×
895
    return Vector3(x, y, z);
×
896
  }
897

898
  Vector3 get forward {
×
899
    final x = _m3storage[6];
×
900
    final y = _m3storage[7];
×
901
    final z = _m3storage[8];
×
902
    return Vector3(x, y, z);
×
903
  }
904

905
  /// Is this the identity matrix?
906
  bool isIdentity() =>
×
907
      _m3storage[0] == 1.0 // col 1
×
908
      &&
909
      _m3storage[1] == 0.0 &&
×
910
      _m3storage[2] == 0.0 &&
×
911
      _m3storage[3] == 0.0 // col 2
×
912
      &&
913
      _m3storage[4] == 1.0 &&
×
914
      _m3storage[5] == 0.0 &&
×
915
      _m3storage[6] == 0.0 // col 3
×
916
      &&
917
      _m3storage[7] == 0.0 &&
×
918
      _m3storage[8] == 1.0;
×
919

920
  /// Is this the zero matrix?
921
  bool isZero() =>
×
922
      _m3storage[0] == 0.0 // col 1
×
923
      &&
924
      _m3storage[1] == 0.0 &&
×
925
      _m3storage[2] == 0.0 &&
×
926
      _m3storage[3] == 0.0 // col 2
×
927
      &&
928
      _m3storage[4] == 0.0 &&
×
929
      _m3storage[5] == 0.0 &&
×
930
      _m3storage[6] == 0.0 // col 3
×
931
      &&
932
      _m3storage[7] == 0.0 &&
×
933
      _m3storage[8] == 0.0;
×
934
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc