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

google / vector_math.dart / 17014423045

04 Aug 2025 07:19PM UTC coverage: 26.702% (+0.3%) from 26.388%
17014423045

push

github

web-flow
Bump min SDK to 3.7, update dependencies, reformat (#348)

496 of 1182 new or added lines in 55 files covered. (41.96%)

18 existing lines in 8 files now uncovered.

4463 of 16714 relevant lines covered (26.7%)

1.18 hits per line

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

47.91
/lib/src/vector_math/vector2.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.dart';
6

7
/// 2D column vector.
8
class Vector2 implements Vector {
9
  final Float32List _v2storage;
10

11
  /// The components of the vector.
12
  @override
3✔
13
  Float32List get storage => _v2storage;
3✔
14

15
  /// Set the values of [result] to the minimum of [a] and [b] for each line.
16
  static void min(Vector2 a, Vector2 b, Vector2 result) {
2✔
17
    result
18
      ..x = math.min(a.x, b.x)
8✔
19
      ..y = math.min(a.y, b.y);
8✔
20
  }
21

22
  /// Set the values of [result] to the maximum of [a] and [b] for each line.
23
  static void max(Vector2 a, Vector2 b, Vector2 result) {
2✔
24
    result
25
      ..x = math.max(a.x, b.x)
8✔
26
      ..y = math.max(a.y, b.y);
8✔
27
  }
28

29
  /// Interpolate between [min] and [max] with the amount of [a] using a linear
30
  /// interpolation and store the values in [result].
31
  static void mix(Vector2 min, Vector2 max, double a, Vector2 result) {
1✔
32
    result
33
      ..x = min.x + a * (max.x - min.x)
7✔
34
      ..y = min.y + a * (max.y - min.y);
7✔
35
  }
36

37
  /// Construct a new vector with the specified values.
38
  factory Vector2(double x, double y) => Vector2.zero()..setValues(x, y);
21✔
39

40
  /// Initialized with values from [array] starting at [offset].
41
  factory Vector2.array(List<double> array, [int offset = 0]) =>
×
42
      Vector2.zero()..copyFromArray(array, offset);
×
43

44
  /// Zero vector.
45
  Vector2.zero() : _v2storage = Float32List(2);
14✔
46

47
  /// Splat [value] into all lanes of the vector.
48
  factory Vector2.all(double value) => Vector2.zero()..splat(value);
3✔
49

50
  /// Copy of [other].
51
  factory Vector2.copy(Vector2 other) => Vector2.zero()..setFrom(other);
15✔
52

53
  /// Constructs Vector2 with a given [Float32List] as [storage].
54
  Vector2.fromFloat32List(this._v2storage);
1✔
55

56
  /// Constructs Vector2 with a [storage] that views given [buffer] starting at
57
  /// [offset]. [offset] has to be multiple of [Float32List.bytesPerElement].
58
  Vector2.fromBuffer(ByteBuffer buffer, int offset)
1✔
59
    : _v2storage = Float32List.view(buffer, offset, 2);
1✔
60

61
  /// Generate random vector in the range (0, 0) to (1, 1). You can
62
  /// optionally pass your own random number generator.
63
  factory Vector2.random([math.Random? rng]) {
1✔
64
    rng ??= math.Random();
×
65
    return Vector2(rng.nextDouble(), rng.nextDouble());
3✔
66
  }
67

68
  /// Set the values of the vector.
69
  void setValues(double x_, double y_) {
7✔
70
    _v2storage[1] = y_;
14✔
71
    _v2storage[0] = x_;
14✔
72
  }
73

74
  /// Zero the vector.
75
  void setZero() {
1✔
76
    _v2storage[1] = 0.0;
2✔
77
    _v2storage[0] = 0.0;
2✔
78
  }
79

80
  /// Set the values by copying them from [other].
81
  void setFrom(Vector2 other) {
5✔
82
    final otherStorage = other._v2storage;
5✔
83
    _v2storage[1] = otherStorage[1];
15✔
84
    _v2storage[0] = otherStorage[0];
15✔
85
  }
86

87
  /// Splat [arg] into all lanes of the vector.
88
  void splat(double arg) {
1✔
89
    _v2storage[1] = arg;
2✔
90
    _v2storage[0] = arg;
2✔
91
  }
92

93
  /// Returns a printable string
94
  @override
4✔
95
  String toString() => '[${_v2storage[0]},${_v2storage[1]}]';
20✔
96

97
  /// Check if two vectors are the same.
98
  @override
1✔
99
  bool operator ==(Object other) =>
100
      other is Vector2 &&
1✔
101
      _v2storage[1] == other._v2storage[1] &&
5✔
102
      _v2storage[0] == other._v2storage[0];
5✔
103

104
  @override
1✔
105
  int get hashCode => Object.hashAll(_v2storage);
2✔
106

107
  /// Negate.
108
  Vector2 operator -() => clone()..negate();
×
109

110
  /// Subtract two vectors.
111
  Vector2 operator -(Vector2 other) => clone()..sub(other);
3✔
112

113
  /// Add two vectors.
114
  Vector2 operator +(Vector2 other) => clone()..add(other);
×
115

116
  /// Scale.
117
  Vector2 operator /(double scale) => clone()..scale(1.0 / scale);
×
118

119
  /// Scale.
120
  Vector2 operator *(double scale) => clone()..scale(scale);
×
121

122
  /// Access the component of the vector at the index [i].
123
  double operator [](int i) => _v2storage[i];
×
124

125
  /// Set the component of the vector at the index [i].
126
  void operator []=(int i, double v) {
×
127
    _v2storage[i] = v;
×
128
  }
129

130
  /// Set the length of the vector. A negative [value] will change the vectors
131
  /// orientation and a [value] of zero will set the vector to zero.
132
  set length(double value) {
1✔
133
    if (value == 0.0) {
1✔
134
      setZero();
1✔
135
    } else {
136
      var l = length;
1✔
137
      if (l == 0.0) {
1✔
138
        return;
139
      }
140
      l = value / l;
1✔
141
      _v2storage[1] *= l;
3✔
142
      _v2storage[0] *= l;
3✔
143
    }
144
  }
145

146
  /// The length of the vector.
147
  double get length => math.sqrt(length2);
12✔
148

149
  /// The squared length of the vector.
150
  double get length2 =>
4✔
151
      _v2storage[1] * _v2storage[1] + _v2storage[0] * _v2storage[0];
44✔
152

153
  /// Normalize this.
154
  double normalize() {
1✔
155
    final l = length;
1✔
156
    if (l == 0.0) {
1✔
157
      return 0.0;
158
    }
159
    final d = 1.0 / l;
1✔
160
    _v2storage[1] *= d;
3✔
161
    _v2storage[0] *= d;
3✔
162
    return l;
163
  }
164

165
  /// Normalize this. Returns length of vector before normalization.
166
  @Deprecated('Use normalize() instead.')
×
167
  double normalizeLength() => normalize();
×
168

169
  /// Normalized copy of this.
170
  Vector2 normalized() => clone()..normalize();
3✔
171

172
  /// Normalize vector into [out].
173
  Vector2 normalizeInto(Vector2 out) {
×
174
    out
175
      ..setFrom(this)
×
176
      ..normalize();
×
177
    return out;
178
  }
179

180
  /// Distance from this to [arg]
181
  double distanceTo(Vector2 arg) => math.sqrt(distanceToSquared(arg));
3✔
182

183
  /// Squared distance from this to [arg]
184
  double distanceToSquared(Vector2 arg) {
1✔
185
    final dx = x - arg.x;
3✔
186
    final dy = y - arg.y;
3✔
187

188
    return dx * dx + dy * dy;
3✔
189
  }
190

191
  /// Returns the angle between this vector and [other] in radians.
192
  double angleTo(Vector2 other) {
1✔
193
    final otherStorage = other._v2storage;
1✔
194
    if (_v2storage[1] == otherStorage[1] && _v2storage[0] == otherStorage[0]) {
8✔
195
      return 0.0;
196
    }
197

198
    final d = dot(other) / (length * other.length);
5✔
199

200
    return math.acos(d.clamp(-1.0, 1.0));
3✔
201
  }
202

203
  /// Returns the signed angle between this and [other] in radians.
204
  double angleToSigned(Vector2 other) {
1✔
205
    final otherStorage = other._v2storage;
1✔
206
    if (_v2storage[1] == otherStorage[1] && _v2storage[0] == otherStorage[0]) {
8✔
207
      return 0.0;
208
    }
209

210
    final s = cross(other);
1✔
211
    final c = dot(other);
1✔
212

213
    return math.atan2(s, c);
1✔
214
  }
215

216
  /// Inner product.
217
  double dot(Vector2 other) {
1✔
218
    final otherStorage = other._v2storage;
1✔
219
    return _v2storage[1] * otherStorage[1] + _v2storage[0] * otherStorage[0];
9✔
220
  }
221

222
  /// Transforms this into the product of this as a row vector,
223
  /// postmultiplied by matrix, [arg].
224
  /// If [arg] is a rotation matrix, this is a computational shortcut for
225
  /// applying, the inverse of the transformation.
226
  ///
227
  void postmultiply(Matrix2 arg) {
1✔
228
    final argStorage = arg.storage;
1✔
229
    final v1 = _v2storage[1];
2✔
230
    final v0 = _v2storage[0];
2✔
231
    _v2storage[1] = v0 * argStorage[2] + v1 * argStorage[3];
7✔
232
    _v2storage[0] = v0 * argStorage[0] + v1 * argStorage[1];
7✔
233
  }
234

235
  /// Cross product.
236
  double cross(Vector2 other) {
1✔
237
    final otherStorage = other._v2storage;
1✔
238
    return _v2storage[0] * otherStorage[1] - _v2storage[1] * otherStorage[0];
9✔
239
  }
240

241
  /// Rotate this by 90 degrees then scale it.
242
  ///
243
  /// Store result in [out]. Return [out].
244
  Vector2 scaleOrthogonalInto(double scale, Vector2 out) {
1✔
245
    out.setValues(-scale * _v2storage[1], scale * _v2storage[0]);
8✔
246
    return out;
247
  }
248

249
  /// Reflect this.
250
  void reflect(Vector2 normal) {
1✔
251
    final dotProduct = normal.dot(this) * 2;
2✔
252
    _v2storage[1] -= normal._v2storage[1] * dotProduct;
6✔
253
    _v2storage[0] -= normal._v2storage[0] * dotProduct;
6✔
254
  }
255

256
  /// Reflected copy of this.
257
  Vector2 reflected(Vector2 normal) => clone()..reflect(normal);
×
258

259
  /// Relative error between this and [correct]
260
  double relativeError(Vector2 correct) =>
4✔
261
      absoluteError(correct) / correct.length;
12✔
262

263
  /// Absolute error between this and [correct]
264
  double absoluteError(Vector2 correct) {
4✔
265
    final yDiff = _v2storage[1] - correct._v2storage[1];
20✔
266
    final xDiff = _v2storage[0] - correct._v2storage[0];
20✔
267
    return math.sqrt(xDiff * xDiff + yDiff * yDiff);
16✔
268
  }
269

270
  /// True if any component is infinite.
271
  bool get isInfinite => _v2storage[1].isInfinite || _v2storage[0].isInfinite;
×
272

273
  /// True if any component is NaN.
274
  bool get isNaN => _v2storage[1].isNaN || _v2storage[0].isNaN;
×
275

276
  /// Add [arg] to this.
277
  void add(Vector2 arg) {
2✔
278
    final argStorage = arg._v2storage;
2✔
279
    _v2storage[1] += argStorage[1];
8✔
280
    _v2storage[0] += argStorage[0];
8✔
281
  }
282

283
  /// Add [arg] scaled by [factor] to this.
284
  void addScaled(Vector2 arg, double factor) {
1✔
285
    final argStorage = arg._v2storage;
1✔
286
    _v2storage[1] += argStorage[1] * factor;
5✔
287
    _v2storage[0] += argStorage[0] * factor;
5✔
288
  }
289

290
  /// Subtract [arg] from this.
291
  void sub(Vector2 arg) {
3✔
292
    final argStorage = arg._v2storage;
3✔
293
    _v2storage[1] -= argStorage[1];
12✔
294
    _v2storage[0] -= argStorage[0];
12✔
295
  }
296

297
  /// Multiply entries in this with entries in [arg].
298
  void multiply(Vector2 arg) {
×
299
    final argStorage = arg._v2storage;
×
300
    _v2storage[1] *= argStorage[1];
×
301
    _v2storage[0] *= argStorage[0];
×
302
  }
303

304
  /// Divide entries in this with entries in [arg].
305
  void divide(Vector2 arg) {
×
306
    final argStorage = arg._v2storage;
×
307
    _v2storage[1] /= argStorage[1];
×
308
    _v2storage[0] /= argStorage[0];
×
309
  }
310

311
  /// Scale this by [arg].
312
  void scale(double arg) {
1✔
313
    _v2storage[1] *= arg;
3✔
314
    _v2storage[0] *= arg;
3✔
315
  }
316

317
  /// Return a copy of this scaled by [arg].
318
  Vector2 scaled(double arg) => clone()..scale(arg);
×
319

320
  /// Negate.
321
  void negate() {
1✔
322
    _v2storage[1] = -_v2storage[1];
5✔
323
    _v2storage[0] = -_v2storage[0];
5✔
324
  }
325

326
  /// Absolute value.
327
  void absolute() {
×
328
    _v2storage[1] = _v2storage[1].abs();
×
329
    _v2storage[0] = _v2storage[0].abs();
×
330
  }
331

332
  /// Clamp each entry n in this in the range [min[n]]-[max[n]].
333
  void clamp(Vector2 min, Vector2 max) {
1✔
334
    final minStorage = min._v2storage;
1✔
335
    final maxStorage = max._v2storage;
1✔
336
    _v2storage[1] =
2✔
337
        _v2storage[1].clamp(minStorage[1], maxStorage[1]).toDouble();
6✔
338
    _v2storage[0] =
2✔
339
        _v2storage[0].clamp(minStorage[0], maxStorage[0]).toDouble();
6✔
340
  }
341

342
  /// Clamp entries this in the range [min]-[max].
343
  void clampScalar(double min, double max) {
1✔
344
    _v2storage[1] = _v2storage[1].clamp(min, max).toDouble();
6✔
345
    _v2storage[0] = _v2storage[0].clamp(min, max).toDouble();
6✔
346
  }
347

348
  /// Floor entries in this.
349
  void floor() {
1✔
350
    _v2storage[1] = _v2storage[1].floorToDouble();
5✔
351
    _v2storage[0] = _v2storage[0].floorToDouble();
5✔
352
  }
353

354
  /// Ceil entries in this.
355
  void ceil() {
1✔
356
    _v2storage[1] = _v2storage[1].ceilToDouble();
5✔
357
    _v2storage[0] = _v2storage[0].ceilToDouble();
5✔
358
  }
359

360
  /// Round entries in this.
361
  void round() {
1✔
362
    _v2storage[1] = _v2storage[1].roundToDouble();
5✔
363
    _v2storage[0] = _v2storage[0].roundToDouble();
5✔
364
  }
365

366
  /// Round entries in this towards zero.
367
  void roundToZero() {
1✔
368
    _v2storage[1] =
2✔
369
        _v2storage[1] < 0.0
3✔
NEW
370
            ? _v2storage[1].ceilToDouble()
×
371
            : _v2storage[1].floorToDouble();
3✔
372
    _v2storage[0] =
2✔
373
        _v2storage[0] < 0.0
3✔
374
            ? _v2storage[0].ceilToDouble()
3✔
NEW
375
            : _v2storage[0].floorToDouble();
×
376
  }
377

378
  /// Clone of this.
379
  Vector2 clone() => Vector2.copy(this);
6✔
380

381
  /// Copy this into [arg]. Returns [arg].
382
  Vector2 copyInto(Vector2 arg) {
×
383
    final argStorage = arg._v2storage;
×
384
    argStorage[1] = _v2storage[1];
×
385
    argStorage[0] = _v2storage[0];
×
386
    return arg;
387
  }
388

389
  /// Copies this into [array] starting at [offset].
390
  void copyIntoArray(List<double> array, [int offset = 0]) {
×
391
    array[offset + 1] = _v2storage[1];
×
392
    array[offset + 0] = _v2storage[0];
×
393
  }
394

395
  /// Copies elements from [array] into this starting at [offset].
396
  void copyFromArray(List<double> array, [int offset = 0]) {
×
397
    _v2storage[1] = array[offset + 1];
×
398
    _v2storage[0] = array[offset + 0];
×
399
  }
400

401
  set xy(Vector2 arg) {
×
402
    final argStorage = arg._v2storage;
×
403
    _v2storage[1] = argStorage[1];
×
404
    _v2storage[0] = argStorage[0];
×
405
  }
406

407
  set yx(Vector2 arg) {
×
408
    final argStorage = arg._v2storage;
×
409
    _v2storage[1] = argStorage[0];
×
410
    _v2storage[0] = argStorage[1];
×
411
  }
412

413
  set r(double arg) => x = arg;
×
414
  set g(double arg) => y = arg;
×
415
  set s(double arg) => x = arg;
×
416
  set t(double arg) => y = arg;
×
417
  set x(double arg) => _v2storage[0] = arg;
15✔
418
  set y(double arg) => _v2storage[1] = arg;
15✔
419
  set rg(Vector2 arg) => xy = arg;
×
420
  set gr(Vector2 arg) => yx = arg;
×
421
  set st(Vector2 arg) => xy = arg;
×
422
  set ts(Vector2 arg) => yx = arg;
×
423
  Vector2 get xx => Vector2(_v2storage[0], _v2storage[0]);
×
424
  Vector2 get xy => Vector2(_v2storage[0], _v2storage[1]);
×
425
  Vector2 get yx => Vector2(_v2storage[1], _v2storage[0]);
×
426
  Vector2 get yy => Vector2(_v2storage[1], _v2storage[1]);
×
427
  Vector3 get xxx => Vector3(_v2storage[0], _v2storage[0], _v2storage[0]);
×
428
  Vector3 get xxy => Vector3(_v2storage[0], _v2storage[0], _v2storage[1]);
×
429
  Vector3 get xyx => Vector3(_v2storage[0], _v2storage[1], _v2storage[0]);
×
430
  Vector3 get xyy => Vector3(_v2storage[0], _v2storage[1], _v2storage[1]);
×
431
  Vector3 get yxx => Vector3(_v2storage[1], _v2storage[0], _v2storage[0]);
×
432
  Vector3 get yxy => Vector3(_v2storage[1], _v2storage[0], _v2storage[1]);
×
433
  Vector3 get yyx => Vector3(_v2storage[1], _v2storage[1], _v2storage[0]);
×
434
  Vector3 get yyy => Vector3(_v2storage[1], _v2storage[1], _v2storage[1]);
×
435
  Vector4 get xxxx =>
×
436
      Vector4(_v2storage[0], _v2storage[0], _v2storage[0], _v2storage[0]);
×
437
  Vector4 get xxxy =>
×
438
      Vector4(_v2storage[0], _v2storage[0], _v2storage[0], _v2storage[1]);
×
439
  Vector4 get xxyx =>
×
440
      Vector4(_v2storage[0], _v2storage[0], _v2storage[1], _v2storage[0]);
×
441
  Vector4 get xxyy =>
×
442
      Vector4(_v2storage[0], _v2storage[0], _v2storage[1], _v2storage[1]);
×
443
  Vector4 get xyxx =>
×
444
      Vector4(_v2storage[0], _v2storage[1], _v2storage[0], _v2storage[0]);
×
445
  Vector4 get xyxy =>
×
446
      Vector4(_v2storage[0], _v2storage[1], _v2storage[0], _v2storage[1]);
×
447
  Vector4 get xyyx =>
×
448
      Vector4(_v2storage[0], _v2storage[1], _v2storage[1], _v2storage[0]);
×
449
  Vector4 get xyyy =>
×
450
      Vector4(_v2storage[0], _v2storage[1], _v2storage[1], _v2storage[1]);
×
451
  Vector4 get yxxx =>
×
452
      Vector4(_v2storage[1], _v2storage[0], _v2storage[0], _v2storage[0]);
×
453
  Vector4 get yxxy =>
×
454
      Vector4(_v2storage[1], _v2storage[0], _v2storage[0], _v2storage[1]);
×
455
  Vector4 get yxyx =>
×
456
      Vector4(_v2storage[1], _v2storage[0], _v2storage[1], _v2storage[0]);
×
457
  Vector4 get yxyy =>
×
458
      Vector4(_v2storage[1], _v2storage[0], _v2storage[1], _v2storage[1]);
×
459
  Vector4 get yyxx =>
×
460
      Vector4(_v2storage[1], _v2storage[1], _v2storage[0], _v2storage[0]);
×
461
  Vector4 get yyxy =>
×
462
      Vector4(_v2storage[1], _v2storage[1], _v2storage[0], _v2storage[1]);
×
463
  Vector4 get yyyx =>
×
464
      Vector4(_v2storage[1], _v2storage[1], _v2storage[1], _v2storage[0]);
×
465
  Vector4 get yyyy =>
×
466
      Vector4(_v2storage[1], _v2storage[1], _v2storage[1], _v2storage[1]);
×
467
  double get r => x;
×
468
  double get g => y;
×
469
  double get s => x;
×
470
  double get t => y;
×
471
  double get x => _v2storage[0];
21✔
472
  double get y => _v2storage[1];
21✔
473
  Vector2 get rr => xx;
×
474
  Vector2 get rg => xy;
×
475
  Vector2 get gr => yx;
×
476
  Vector2 get gg => yy;
×
477
  Vector3 get rrr => xxx;
×
478
  Vector3 get rrg => xxy;
×
479
  Vector3 get rgr => xyx;
×
480
  Vector3 get rgg => xyy;
×
481
  Vector3 get grr => yxx;
×
482
  Vector3 get grg => yxy;
×
483
  Vector3 get ggr => yyx;
×
484
  Vector3 get ggg => yyy;
×
485
  Vector4 get rrrr => xxxx;
×
486
  Vector4 get rrrg => xxxy;
×
487
  Vector4 get rrgr => xxyx;
×
488
  Vector4 get rrgg => xxyy;
×
489
  Vector4 get rgrr => xyxx;
×
490
  Vector4 get rgrg => xyxy;
×
491
  Vector4 get rggr => xyyx;
×
492
  Vector4 get rggg => xyyy;
×
493
  Vector4 get grrr => yxxx;
×
494
  Vector4 get grrg => yxxy;
×
495
  Vector4 get grgr => yxyx;
×
496
  Vector4 get grgg => yxyy;
×
497
  Vector4 get ggrr => yyxx;
×
498
  Vector4 get ggrg => yyxy;
×
499
  Vector4 get gggr => yyyx;
×
500
  Vector4 get gggg => yyyy;
×
501
  Vector2 get ss => xx;
×
502
  Vector2 get st => xy;
×
503
  Vector2 get ts => yx;
×
504
  Vector2 get tt => yy;
×
505
  Vector3 get sss => xxx;
×
506
  Vector3 get sst => xxy;
×
507
  Vector3 get sts => xyx;
×
508
  Vector3 get stt => xyy;
×
509
  Vector3 get tss => yxx;
×
510
  Vector3 get tst => yxy;
×
511
  Vector3 get tts => yyx;
×
512
  Vector3 get ttt => yyy;
×
513
  Vector4 get ssss => xxxx;
×
514
  Vector4 get ssst => xxxy;
×
515
  Vector4 get ssts => xxyx;
×
516
  Vector4 get sstt => xxyy;
×
517
  Vector4 get stss => xyxx;
×
518
  Vector4 get stst => xyxy;
×
519
  Vector4 get stts => xyyx;
×
520
  Vector4 get sttt => xyyy;
×
521
  Vector4 get tsss => yxxx;
×
522
  Vector4 get tsst => yxxy;
×
523
  Vector4 get tsts => yxyx;
×
524
  Vector4 get tstt => yxyy;
×
525
  Vector4 get ttss => yyxx;
×
526
  Vector4 get ttst => yyxy;
×
527
  Vector4 get ttts => yyyx;
×
528
  Vector4 get tttt => yyyy;
×
529
}
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