Dart DocumentationstagexlVector

Vector class

class Vector {

 static const num Epsilon = 0.0000001;
 static const num EpsilonSqr = Epsilon * Epsilon;

 final num _x;
 final num _y;

 Vector(num x, num y) : _x = x.toDouble(), _y = y.toDouble();
 Vector.zero() : _x = 0.0, _y = 0.0;
 Vector.polar(num len, num angle) : _x = (len * cos(angle)).toDouble(), _y = (len * sin(angle)).toDouble();

 Vector clone() => new Vector(_x, _y);

 num get x => _x;
 num get y => _y;

 String toString() => "Vector [x=${_x}, y=${_y}]";

 //-----------------------------------------------------------------------------------------------
 // Operators

 Vector operator +(Vector other) => new Vector(_x + other._x, _y + other._y);
 Vector operator -(Vector other) => new Vector(_x - other._x, _y - other._y);
 Vector operator *(Vector other) => new Vector(_x * other._x, _y * other._y);
 Vector operator /(Vector other) => new Vector(_x / other._x, _y / other._y);

 Vector operator -() => new Vector(-_x, -_y);
 bool operator ==(Vector other) => _x == other._x && _y == other._y;

 // ToDo: https://dartbug.com/11617
 int get hashCode => _x.hashCode + _y.hashCode * 7;

 bool equalsXY(num x, num y) => _x == x && _y == y;

 //-----------------------------------------------------------------------------------------------
 // Queries

 bool get isNormalized => ((_x * _x + _y * _y) - 1).abs() < EpsilonSqr;
 bool get isZero => (_x == 0 && _y == 0);
 bool get isValid => (_x.isNaN || _y.isNaN || _x.isInfinite || _y.isInfinite) == false;

 bool isNear(Vector other) => distanceSqr(other) < EpsilonSqr;
 bool isNearXY(num x, num y) => distanceXYSqr(x, y) < EpsilonSqr;
 bool isWithin(Vector other, num epsilon) => distanceSqr(other) < epsilon * epsilon;
 bool isWithinXY(num x, num y, num epsilon) => distanceXYSqr(x, y) < epsilon * epsilon;

 num get degrees => atan2(_y, _x) * 180 / PI;
 num get rads => atan2(_y, _x);

 //-----------------------------------------------------------------------------------------------
 // Scale

 Vector scale(num scale) {
   return new Vector(_x * scale, _y * scale);
 }

 Vector scaleLength(num value) {
   var scale = value / length;
   return new Vector(_x * scale, _y * scale);
 }

 Vector normalize() {
   num nf = 1 / length;
   return new Vector(_x * nf, _y * nf);
 }

 //-----------------------------------------------------------------------------------------------
 // Distance

 num get length => sqrt(_x * _x + _y * _y);
 num get lengthSqr => _x * _x + _y * _y;

 num distance(Vector vec) {
   num xd = _x - vec._x;
   num yd = _y - vec._y;
   return sqrt(xd * xd + yd * yd);
 }

 num distanceXY(num x, num y) {
   num xd = _x - x;
   num yd = _y - y;
   return sqrt(xd * xd + yd * yd);
 }

 num distanceSqr(Vector vec) {
   num xd = _x - vec._x;
   num yd = _y - vec._y;
   return xd * xd + yd * yd;
 }

 num distanceXYSqr(num x, num y) {
   num xd = _x - x;
   num yd = _y - y;
   return xd * xd + yd * yd;
 }

 //-----------------------------------------------------------------------------------------------
 // Dot product

 num dot(Vector vec) => _x * vec._x + _y * vec._y;
 num dotXY(num x, num y) => _x * x + _y * y;

 //-----------------------------------------------------------------------------------------------
 // Cross determinant

 num crossDet(Vector vec) => _x * vec._y - _y * vec._x;
 num crossDetXY(num x, num y) => _x * y - _y * x;

 //-----------------------------------------------------------------------------------------------
 // Rotate

 Vector rotate(num rads) {
   num s = sin(rads);
   num c = cos(rads);
   return new Vector(_x * c - _y * s, _x * s + _y * c);
 }

 Vector normalRight() {
   return new Vector(-_y, _x);
 }

 Vector normalLeft() {
   return new Vector(_y, -_x);
 }

 Vector negate() {
   return new Vector(-_x, -_y);
 }

 //-----------------------------------------------------------------------------------------------
 // Spinor rotation

 Vector rotateSpinor(Vector vec) {
   return new Vector(_x * vec._x - _y * vec._y, _x * vec._y + _y * vec._x);
 }

 Vector spinorBetween(Vector vec) {
   num d = this.lengthSqr;
   num r = (vec._x * _x + vec._y * _y) / d;
   num i = (vec._y * _x - vec._x * _y) / d;
   return new Vector(r, i);
 }

 //-----------------------------------------------------------------------------------------------
 // Lerp / slerp

 Vector lerp(Vector to, num t) {
   return new Vector(_x + t * (to._x - _x), _y + t * (to._y - _y));
 }

 Vector slerp(Vector vec, num t) {
   num cosTheta = this.dot(vec);
   num theta = acos(cosTheta);
   num sinTheta = sin(theta);

   if (sinTheta <= Epsilon)
     return vec.clone();

   num w1 = sin((1 - t) * theta) / sinTheta;
   num w2 = sin(t * theta) / sinTheta;
   return this.scale(w1) + vec.scale(w2);
 }

 //-----------------------------------------------------------------------------------------------
 // Reflect

 Vector reflect(Vector normal) {
   num d = 2 * (_x * normal._x + _y * normal._y);
   return new Vector(_x - d * normal._x, _y - d * normal._y);
 }

}

Static Properties

const num Epsilon #

static const num Epsilon = 0.0000001

const num EpsilonSqr #

static const num EpsilonSqr = Epsilon * Epsilon

Constructors

new Vector(num x, num y) #

Creates a new Object instance.

Object instances have no meaningful state, and are only useful through their identity. An Object instance is equal to itself only.

docs inherited from Object
Vector(num x, num y) : _x = x.toDouble(), _y = y.toDouble();

new Vector.polar(num len, num angle) #

Vector.polar(num len, num angle) : _x = (len * cos(angle)).toDouble(), _y = (len * sin(angle)).toDouble();

new Vector.zero() #

Vector.zero() : _x = 0.0, _y = 0.0;

Properties

final num degrees #

num get degrees => atan2(_y, _x) * 180 / PI;

final int hashCode #

Get a hash code for this object.

All objects have hash codes. Hash codes are guaranteed to be the same for objects that are equal when compared using the equality operator ==. Other than that there are no guarantees about the hash codes. They will not be consistent between runs and there are no distribution guarantees.

If a subclass overrides hashCode it should override the equality operator as well to maintain consistency.

docs inherited from Object
int get hashCode => _x.hashCode + _y.hashCode * 7;

final bool isNormalized #

bool get isNormalized => ((_x * _x + _y * _y) - 1).abs() < EpsilonSqr;

final bool isValid #

bool get isValid => (_x.isNaN || _y.isNaN || _x.isInfinite || _y.isInfinite) == false;

final bool isZero #

bool get isZero => (_x == 0 && _y == 0);

final num length #

num get length => sqrt(_x * _x + _y * _y);

final num lengthSqr #

num get lengthSqr => _x * _x + _y * _y;

final num rads #

num get rads => atan2(_y, _x);

final num x #

num get x => _x;

final num y #

num get y => _y;

Operators

Vector operator +(Vector other) #

Vector operator +(Vector other) => new Vector(_x + other._x, _y + other._y);

Vector operator -() #

Vector operator -() => new Vector(-_x, -_y);

Vector operator -(Vector other) #

Vector operator -(Vector other) => new Vector(_x - other._x, _y - other._y);

Vector operator *(Vector other) #

Vector operator *(Vector other) => new Vector(_x * other._x, _y * other._y);

Vector operator /(Vector other) #

Vector operator /(Vector other) => new Vector(_x / other._x, _y / other._y);

bool operator ==(Vector other) #

The equality operator.

The default behavior for all Objects is to return true if and only if this and other are the same object.

Override this method to specify a different equality relation on a class. The overriding method must still be an equivalence relation. That is, it must be:

  • Total: It must return a boolean for all arguments. It should never throw or return null.

  • Reflexive: For all objects o, o == o must be true.

  • Symmetric: For all objects o1 and o2, o1 == o2 and o2 == o1 must either both be true, or both be false.

  • Transitive: For all objects o1, o2, and o3, if o1 == o2 and o2 == o3 are true, then o1 == o3 must be true.

The method should also be consistent over time, so equality of two objects should not change over time, or at least only change if one of the objects was modified.

If a subclass overrides the equality operator it should override the hashCode method as well to maintain consistency.

docs inherited from Object
bool operator ==(Vector other) => _x == other._x && _y == other._y;

Methods

Vector clone() #

Vector clone() => new Vector(_x, _y);

num crossDet(Vector vec) #

num crossDet(Vector vec) => _x * vec._y - _y * vec._x;

num crossDetXY(num x, num y) #

num crossDetXY(num x, num y) => _x * y - _y * x;

num distance(Vector vec) #

num distance(Vector vec) {
 num xd = _x - vec._x;
 num yd = _y - vec._y;
 return sqrt(xd * xd + yd * yd);
}

num distanceSqr(Vector vec) #

num distanceSqr(Vector vec) {
 num xd = _x - vec._x;
 num yd = _y - vec._y;
 return xd * xd + yd * yd;
}

num distanceXY(num x, num y) #

num distanceXY(num x, num y) {
 num xd = _x - x;
 num yd = _y - y;
 return sqrt(xd * xd + yd * yd);
}

num distanceXYSqr(num x, num y) #

num distanceXYSqr(num x, num y) {
 num xd = _x - x;
 num yd = _y - y;
 return xd * xd + yd * yd;
}

num dot(Vector vec) #

num dot(Vector vec) => _x * vec._x + _y * vec._y;

num dotXY(num x, num y) #

num dotXY(num x, num y) => _x * x + _y * y;

bool equalsXY(num x, num y) #

bool equalsXY(num x, num y) => _x == x && _y == y;

bool isNear(Vector other) #

bool isNear(Vector other) => distanceSqr(other) < EpsilonSqr;

bool isNearXY(num x, num y) #

bool isNearXY(num x, num y) => distanceXYSqr(x, y) < EpsilonSqr;

bool isWithin(Vector other, num epsilon) #

bool isWithin(Vector other, num epsilon) => distanceSqr(other) < epsilon * epsilon;

bool isWithinXY(num x, num y, num epsilon) #

bool isWithinXY(num x, num y, num epsilon) => distanceXYSqr(x, y) < epsilon * epsilon;

Vector lerp(Vector to, num t) #

Vector lerp(Vector to, num t) {
 return new Vector(_x + t * (to._x - _x), _y + t * (to._y - _y));
}

Vector negate() #

Vector negate() {
 return new Vector(-_x, -_y);
}

Vector normalize() #

Vector normalize() {
 num nf = 1 / length;
 return new Vector(_x * nf, _y * nf);
}

Vector normalLeft() #

Vector normalLeft() {
 return new Vector(_y, -_x);
}

Vector normalRight() #

Vector normalRight() {
 return new Vector(-_y, _x);
}

Vector reflect(Vector normal) #

Vector reflect(Vector normal) {
 num d = 2 * (_x * normal._x + _y * normal._y);
 return new Vector(_x - d * normal._x, _y - d * normal._y);
}

Vector rotate(num rads) #

Vector rotate(num rads) {
 num s = sin(rads);
 num c = cos(rads);
 return new Vector(_x * c - _y * s, _x * s + _y * c);
}

Vector rotateSpinor(Vector vec) #

Vector rotateSpinor(Vector vec) {
 return new Vector(_x * vec._x - _y * vec._y, _x * vec._y + _y * vec._x);
}

Vector scale(num scale) #

Vector scale(num scale) {
 return new Vector(_x * scale, _y * scale);
}

Vector scaleLength(num value) #

Vector scaleLength(num value) {
 var scale = value / length;
 return new Vector(_x * scale, _y * scale);
}

Vector slerp(Vector vec, num t) #

Vector slerp(Vector vec, num t) {
 num cosTheta = this.dot(vec);
 num theta = acos(cosTheta);
 num sinTheta = sin(theta);

 if (sinTheta <= Epsilon)
   return vec.clone();

 num w1 = sin((1 - t) * theta) / sinTheta;
 num w2 = sin(t * theta) / sinTheta;
 return this.scale(w1) + vec.scale(w2);
}

Vector spinorBetween(Vector vec) #

Vector spinorBetween(Vector vec) {
 num d = this.lengthSqr;
 num r = (vec._x * _x + vec._y * _y) / d;
 num i = (vec._y * _x - vec._x * _y) / d;
 return new Vector(r, i);
}

String toString() #

Returns a string representation of this object.

docs inherited from Object
String toString() => "Vector [x=${_x}, y=${_y}]";