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

google / vector_math.dart / 12224890780

08 Dec 2024 08:11PM UTC coverage: 26.372%. Remained the same
12224890780

Pull #337

github

web-flow
Merge 1b1108c78 into 433fb6c82
Pull Request #337: Partial fix for benchmarks.

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/matrix2.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
/// 2D Matrix.
8
/// Values are stored in column major order.
9
class Matrix2 {
10
  final Float64List _m2storage;
11

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

15
  /// Solve [A] * [x] = [b].
16
  static void solve(Matrix2 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;
×
22
    final by = b.y;
×
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
  /// Return index in storage for [row], [col] value.
35
  int index(int row, int col) => (col * 2) + row;
×
36

37
  /// Value at [row], [col].
38
  double entry(int row, int col) {
×
39
    assert((row >= 0) && (row < dimension));
×
40
    assert((col >= 0) && (col < dimension));
×
41

42
    return _m2storage[index(row, col)];
×
43
  }
44

45
  /// Set value at [row], [col] to be [v].
46
  void setEntry(int row, int col, double v) {
×
47
    assert((row >= 0) && (row < dimension));
×
48
    assert((col >= 0) && (col < dimension));
×
49

50
    _m2storage[index(row, col)] = v;
×
51
  }
52

53
  /// New matrix with specified values.
54
  factory Matrix2(double arg0, double arg1, double arg2, double arg3) =>
×
55
      Matrix2.zero()..setValues(arg0, arg1, arg2, arg3);
×
56

57
  /// New matrix from [values].
58
  factory Matrix2.fromList(List<double> values) =>
×
59
      Matrix2.zero()..setValues(values[0], values[1], values[2], values[3]);
×
60

61
  /// Zero matrix.
62
  Matrix2.zero() : _m2storage = Float64List(4);
×
63

64
  /// Identity matrix.
65
  factory Matrix2.identity() => Matrix2.zero()..setIdentity();
×
66

67
  /// Copies values from [other].
68
  factory Matrix2.copy(Matrix2 other) => Matrix2.zero()..setFrom(other);
×
69

70
  /// Matrix with values from column arguments.
71
  factory Matrix2.columns(Vector2 arg0, Vector2 arg1) =>
×
72
      Matrix2.zero()..setColumns(arg0, arg1);
×
73

74
  /// Outer product of [u] and [v].
75
  factory Matrix2.outer(Vector2 u, Vector2 v) => Matrix2.zero()..setOuter(u, v);
×
76

77
  /// Rotation of [radians].
78
  factory Matrix2.rotation(double radians) =>
×
79
      Matrix2.zero()..setRotation(radians);
×
80

81
  /// Sets the matrix with specified values.
82
  void setValues(double arg0, double arg1, double arg2, double arg3) {
×
83
    _m2storage[3] = arg3;
×
84
    _m2storage[2] = arg2;
×
85
    _m2storage[1] = arg1;
×
86
    _m2storage[0] = arg0;
×
87
  }
88

89
  /// Sets the entire matrix to the column values.
90
  void setColumns(Vector2 arg0, Vector2 arg1) {
×
91
    final arg0Storage = arg0._v2storage;
×
92
    final arg1Storage = arg1._v2storage;
×
93
    _m2storage[0] = arg0Storage[0];
×
94
    _m2storage[1] = arg0Storage[1];
×
95
    _m2storage[2] = arg1Storage[0];
×
96
    _m2storage[3] = arg1Storage[1];
×
97
  }
98

99
  /// Sets the entire matrix to the matrix in [arg].
100
  void setFrom(Matrix2 arg) {
×
101
    final argStorage = arg._m2storage;
×
102
    _m2storage[3] = argStorage[3];
×
103
    _m2storage[2] = argStorage[2];
×
104
    _m2storage[1] = argStorage[1];
×
105
    _m2storage[0] = argStorage[0];
×
106
  }
107

108
  /// Set this to the outer product of [u] and [v].
109
  void setOuter(Vector2 u, Vector2 v) {
×
110
    final uStorage = u._v2storage;
×
111
    final vStorage = v._v2storage;
×
112
    _m2storage[0] = uStorage[0] * vStorage[0];
×
113
    _m2storage[1] = uStorage[0] * vStorage[1];
×
114
    _m2storage[2] = uStorage[1] * vStorage[0];
×
115
    _m2storage[3] = uStorage[1] * vStorage[1];
×
116
  }
117

118
  /// Sets the diagonal to [arg].
119
  void splatDiagonal(double arg) {
×
120
    _m2storage[0] = arg;
×
121
    _m2storage[3] = arg;
×
122
  }
123

124
  /// Sets the diagonal of the matrix to be [arg].
125
  void setDiagonal(Vector2 arg) {
×
126
    final argStorage = arg._v2storage;
×
127
    _m2storage[0] = argStorage[0];
×
128
    _m2storage[3] = argStorage[1];
×
129
  }
130

131
  /// Returns a printable string
132
  @override
×
133
  String toString() => '[0] ${getRow(0)}\n[1] ${getRow(1)}\n';
×
134

135
  /// Dimension of the matrix.
136
  int get dimension => 2;
×
137

138
  /// Access the element of the matrix at the index [i].
139
  double operator [](int i) => _m2storage[i];
×
140

141
  /// Set the element of the matrix at the index [i].
142
  void operator []=(int i, double v) {
×
143
    _m2storage[i] = v;
×
144
  }
145

146
  /// Check if two matrices are the same.
147
  @override
×
148
  bool operator ==(Object other) =>
149
      (other is Matrix2) &&
×
150
      (_m2storage[0] == other._m2storage[0]) &&
×
151
      (_m2storage[1] == other._m2storage[1]) &&
×
152
      (_m2storage[2] == other._m2storage[2]) &&
×
153
      (_m2storage[3] == other._m2storage[3]);
×
154

155
  @override
×
156
  int get hashCode => Object.hashAll(_m2storage);
×
157

158
  /// Returns row 0
159
  Vector2 get row0 => getRow(0);
×
160

161
  /// Returns row 1
162
  Vector2 get row1 => getRow(1);
×
163

164
  /// Sets row 0 to [arg]
165
  set row0(Vector2 arg) => setRow(0, arg);
×
166

167
  /// Sets row 1 to [arg]
168
  set row1(Vector2 arg) => setRow(1, arg);
×
169

170
  /// Sets [row] of the matrix to values in [arg]
171
  void setRow(int row, Vector2 arg) {
×
172
    final argStorage = arg._v2storage;
×
173
    _m2storage[index(row, 0)] = argStorage[0];
×
174
    _m2storage[index(row, 1)] = argStorage[1];
×
175
  }
176

177
  /// Gets the [row] of the matrix
178
  Vector2 getRow(int row) {
×
179
    final r = Vector2.zero();
×
180
    final rStorage = r._v2storage;
×
181
    rStorage[0] = _m2storage[index(row, 0)];
×
182
    rStorage[1] = _m2storage[index(row, 1)];
×
183
    return r;
184
  }
185

186
  /// Assigns the [column] of the matrix [arg]
187
  void setColumn(int column, Vector2 arg) {
×
188
    final argStorage = arg._v2storage;
×
189
    final entry = column * 2;
×
190
    _m2storage[entry + 1] = argStorage[1];
×
191
    _m2storage[entry + 0] = argStorage[0];
×
192
  }
193

194
  /// Gets the [column] of the matrix
195
  Vector2 getColumn(int column) {
×
196
    final r = Vector2.zero();
×
197
    final entry = column * 2;
×
198
    final rStorage = r._v2storage;
×
199
    rStorage[1] = _m2storage[entry + 1];
×
200
    rStorage[0] = _m2storage[entry + 0];
×
201
    return r;
202
  }
203

204
  /// Create a copy of this.
205
  Matrix2 clone() => Matrix2.copy(this);
×
206

207
  /// Copy this into [arg].
208
  Matrix2 copyInto(Matrix2 arg) {
×
209
    final argStorage = arg._m2storage;
×
210
    argStorage[0] = _m2storage[0];
×
211
    argStorage[1] = _m2storage[1];
×
212
    argStorage[2] = _m2storage[2];
×
213
    argStorage[3] = _m2storage[3];
×
214
    return arg;
215
  }
216

217
  /// Returns a new vector or matrix by multiplying this with [arg].
218
  dynamic operator *(dynamic arg) {
×
219
    if (arg is double) {
×
220
      return scaled(arg);
×
221
    }
222
    if (arg is Vector2) {
×
223
      return transformed(arg);
×
224
    }
225
    if (arg is Matrix2) {
×
226
      return multiplied(arg);
×
227
    }
228
    throw ArgumentError(arg);
×
229
  }
230

231
  /// Returns new matrix after component wise this + [arg]
232
  Matrix2 operator +(Matrix2 arg) => clone()..add(arg);
×
233

234
  /// Returns new matrix after component wise this - [arg]
235
  Matrix2 operator -(Matrix2 arg) => clone()..sub(arg);
×
236

237
  /// Returns new matrix -this
238
  Matrix2 operator -() => clone()..negate();
×
239

240
  /// Zeros this.
241
  void setZero() {
×
242
    _m2storage[0] = 0.0;
×
243
    _m2storage[1] = 0.0;
×
244
    _m2storage[2] = 0.0;
×
245
    _m2storage[3] = 0.0;
×
246
  }
247

248
  /// Makes this into the identity matrix.
249
  void setIdentity() {
×
250
    _m2storage[0] = 1.0;
×
251
    _m2storage[1] = 0.0;
×
252
    _m2storage[2] = 0.0;
×
253
    _m2storage[3] = 1.0;
×
254
  }
255

256
  /// Returns the tranpose of this.
257
  Matrix2 transposed() => clone()..transpose();
×
258

259
  void transpose() {
×
260
    final temp = _m2storage[2];
×
261
    _m2storage[2] = _m2storage[1];
×
262
    _m2storage[1] = temp;
×
263
  }
264

265
  /// Returns the component wise absolute value of this.
266
  Matrix2 absolute() {
×
267
    final r = Matrix2.zero();
×
268
    final rStorage = r._m2storage;
×
269
    rStorage[0] = _m2storage[0].abs();
×
270
    rStorage[1] = _m2storage[1].abs();
×
271
    rStorage[2] = _m2storage[2].abs();
×
272
    rStorage[3] = _m2storage[3].abs();
×
273
    return r;
274
  }
275

276
  /// Returns the determinant of this matrix.
277
  double determinant() =>
×
278
      (_m2storage[0] * _m2storage[3]) - (_m2storage[1] * _m2storage[2]);
×
279

280
  /// Returns the dot product of row [i] and [v].
281
  double dotRow(int i, Vector2 v) {
×
282
    final vStorage = v._v2storage;
×
283
    return _m2storage[i] * vStorage[0] + _m2storage[2 + i] * vStorage[1];
×
284
  }
285

286
  /// Returns the dot product of column [j] and [v].
287
  double dotColumn(int j, Vector2 v) {
×
288
    final vStorage = v._v2storage;
×
289
    return _m2storage[j * 2] * vStorage[0] +
×
290
        _m2storage[(j * 2) + 1] * vStorage[1];
×
291
  }
292

293
  /// Trace of the matrix.
294
  double trace() {
×
295
    var t = 0.0;
296
    t += _m2storage[0];
×
297
    t += _m2storage[3];
×
298
    return t;
299
  }
300

301
  /// Returns infinity norm of the matrix. Used for numerical analysis.
302
  double infinityNorm() {
×
303
    var norm = 0.0;
304
    {
305
      var rowNorm = 0.0;
306
      rowNorm += _m2storage[0].abs();
×
307
      rowNorm += _m2storage[1].abs();
×
308
      norm = rowNorm > norm ? rowNorm : norm;
×
309
    }
310
    {
311
      var rowNorm = 0.0;
312
      rowNorm += _m2storage[2].abs();
×
313
      rowNorm += _m2storage[3].abs();
×
314
      norm = rowNorm > norm ? rowNorm : norm;
×
315
    }
316
    return norm;
317
  }
318

319
  /// Returns relative error between this and [correct]
320
  double relativeError(Matrix2 correct) {
×
321
    final diff = correct - this;
×
322
    final correctNorm = correct.infinityNorm();
×
323
    final diff_norm = diff.infinityNorm();
×
324
    return diff_norm / correctNorm;
×
325
  }
326

327
  /// Returns absolute error between this and [correct]
328
  double absoluteError(Matrix2 correct) {
×
329
    final this_norm = infinityNorm();
×
330
    final correct_norm = correct.infinityNorm();
×
331
    final diff_norm = (this_norm - correct_norm).abs();
×
332
    return diff_norm;
333
  }
334

335
  /// Invert the matrix. Returns the determinant.
336
  double invert() {
×
337
    final det = determinant();
×
338
    if (det == 0.0) {
×
339
      return 0.0;
340
    }
341
    final invDet = 1.0 / det;
×
342
    final temp = _m2storage[0];
×
343
    _m2storage[0] = _m2storage[3] * invDet;
×
344
    _m2storage[1] = -_m2storage[1] * invDet;
×
345
    _m2storage[2] = -_m2storage[2] * invDet;
×
346
    _m2storage[3] = temp * invDet;
×
347
    return det;
348
  }
349

350
  /// Set this matrix to be the inverse of [arg]
351
  double copyInverse(Matrix2 arg) {
×
352
    final det = arg.determinant();
×
353
    if (det == 0.0) {
×
354
      setFrom(arg);
×
355
      return 0.0;
356
    }
357
    final invDet = 1.0 / det;
×
358
    final argStorage = arg._m2storage;
×
359
    _m2storage[0] = argStorage[3] * invDet;
×
360
    _m2storage[1] = -argStorage[1] * invDet;
×
361
    _m2storage[2] = -argStorage[2] * invDet;
×
362
    _m2storage[3] = argStorage[0] * invDet;
×
363
    return det;
364
  }
365

366
  /// Turns the matrix into a rotation of [radians]
367
  void setRotation(double radians) {
×
368
    final c = math.cos(radians);
×
369
    final s = math.sin(radians);
×
370
    _m2storage[0] = c;
×
371
    _m2storage[1] = s;
×
372
    _m2storage[2] = -s;
×
373
    _m2storage[3] = c;
×
374
  }
375

376
  /// Converts into Adjugate matrix and scales by [scale]
377
  void scaleAdjoint(double scale) {
×
378
    final temp = _m2storage[0];
×
379
    _m2storage[0] = _m2storage[3] * scale;
×
380
    _m2storage[2] = -_m2storage[2] * scale;
×
381
    _m2storage[1] = -_m2storage[1] * scale;
×
382
    _m2storage[3] = temp * scale;
×
383
  }
384

385
  /// Scale this by [scale].
386
  void scale(double scale) {
×
387
    _m2storage[0] = _m2storage[0] * scale;
×
388
    _m2storage[1] = _m2storage[1] * scale;
×
389
    _m2storage[2] = _m2storage[2] * scale;
×
390
    _m2storage[3] = _m2storage[3] * scale;
×
391
  }
392

393
  /// Create a copy of this scaled by [scale].
394
  Matrix2 scaled(double scale) => clone()..scale(scale);
×
395

396
  /// Add [o] to this.
397
  void add(Matrix2 o) {
×
398
    final oStorage = o._m2storage;
×
399
    _m2storage[0] = _m2storage[0] + oStorage[0];
×
400
    _m2storage[1] = _m2storage[1] + oStorage[1];
×
401
    _m2storage[2] = _m2storage[2] + oStorage[2];
×
402
    _m2storage[3] = _m2storage[3] + oStorage[3];
×
403
  }
404

405
  /// Subtract [o] from this.
406
  void sub(Matrix2 o) {
×
407
    final oStorage = o._m2storage;
×
408
    _m2storage[0] = _m2storage[0] - oStorage[0];
×
409
    _m2storage[1] = _m2storage[1] - oStorage[1];
×
410
    _m2storage[2] = _m2storage[2] - oStorage[2];
×
411
    _m2storage[3] = _m2storage[3] - oStorage[3];
×
412
  }
413

414
  /// Negate this.
415
  void negate() {
×
416
    _m2storage[0] = -_m2storage[0];
×
417
    _m2storage[1] = -_m2storage[1];
×
418
    _m2storage[2] = -_m2storage[2];
×
419
    _m2storage[3] = -_m2storage[3];
×
420
  }
421

422
  /// Multiply this with [arg] and store it in this.
423
  void multiply(Matrix2 arg) {
×
424
    final m00 = _m2storage[0];
×
425
    final m01 = _m2storage[2];
×
426
    final m10 = _m2storage[1];
×
427
    final m11 = _m2storage[3];
×
428
    final argStorage = arg._m2storage;
×
429
    final n00 = argStorage[0];
×
430
    final n01 = argStorage[2];
×
431
    final n10 = argStorage[1];
×
432
    final n11 = argStorage[3];
×
433
    _m2storage[0] = (m00 * n00) + (m01 * n10);
×
434
    _m2storage[2] = (m00 * n01) + (m01 * n11);
×
435
    _m2storage[1] = (m10 * n00) + (m11 * n10);
×
436
    _m2storage[3] = (m10 * n01) + (m11 * n11);
×
437
  }
438

439
  /// Multiply this with [arg] and return the product.
440
  Matrix2 multiplied(Matrix2 arg) => clone()..multiply(arg);
×
441

442
  /// Multiply a transposed this with [arg].
443
  void transposeMultiply(Matrix2 arg) {
×
444
    final m00 = _m2storage[0];
×
445
    final m01 = _m2storage[1];
×
446
    final m10 = _m2storage[2];
×
447
    final m11 = _m2storage[3];
×
448
    final argStorage = arg._m2storage;
×
449
    _m2storage[0] = (m00 * argStorage[0]) + (m01 * argStorage[1]);
×
450
    _m2storage[2] = (m00 * argStorage[2]) + (m01 * argStorage[3]);
×
451
    _m2storage[1] = (m10 * argStorage[0]) + (m11 * argStorage[1]);
×
452
    _m2storage[3] = (m10 * argStorage[2]) + (m11 * argStorage[3]);
×
453
  }
454

455
  /// Multiply this with a transposed [arg].
456
  void multiplyTranspose(Matrix2 arg) {
×
457
    final m00 = _m2storage[0];
×
458
    final m01 = _m2storage[2];
×
459
    final m10 = _m2storage[1];
×
460
    final m11 = _m2storage[3];
×
461
    final argStorage = arg._m2storage;
×
462
    _m2storage[0] = (m00 * argStorage[0]) + (m01 * argStorage[2]);
×
463
    _m2storage[2] = (m00 * argStorage[1]) + (m01 * argStorage[3]);
×
464
    _m2storage[1] = (m10 * argStorage[0]) + (m11 * argStorage[2]);
×
465
    _m2storage[3] = (m10 * argStorage[1]) + (m11 * argStorage[3]);
×
466
  }
467

468
  /// Transform [arg] of type [Vector2] using the transformation defined by
469
  /// this.
470
  Vector2 transform(Vector2 arg) {
×
471
    final argStorage = arg._v2storage;
×
472
    final x = (_m2storage[0] * argStorage[0]) + (_m2storage[2] * argStorage[1]);
×
473
    final y = (_m2storage[1] * argStorage[0]) + (_m2storage[3] * argStorage[1]);
×
474
    argStorage[0] = x;
×
475
    argStorage[1] = y;
×
476
    return arg;
477
  }
478

479
  /// Transform a copy of [arg] of type [Vector2] using the transformation
480
  /// defined by this. If a [out] parameter is supplied, the copy is stored in
481
  /// [out].
482
  Vector2 transformed(Vector2 arg, [Vector2? out]) {
×
483
    if (out == null) {
484
      out = Vector2.copy(arg);
×
485
    } else {
486
      out.setFrom(arg);
×
487
    }
488
    return transform(out);
×
489
  }
490

491
  /// Copies this into [array] starting at [offset].
492
  void copyIntoArray(List<num> array, [int offset = 0]) {
×
493
    final i = offset;
494
    array[i + 3] = _m2storage[3];
×
495
    array[i + 2] = _m2storage[2];
×
496
    array[i + 1] = _m2storage[1];
×
497
    array[i + 0] = _m2storage[0];
×
498
  }
499

500
  /// Copies elements from [array] into this starting at [offset].
501
  void copyFromArray(List<double> array, [int offset = 0]) {
×
502
    final i = offset;
503
    _m2storage[3] = array[i + 3];
×
504
    _m2storage[2] = array[i + 2];
×
505
    _m2storage[1] = array[i + 1];
×
506
    _m2storage[0] = array[i + 0];
×
507
  }
508
}
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