vector_math for Dart

repository·master·Indexed 43 days ago

https://github.com/google/vector_math.dart

A high-performance vector math library for 2D and 3D applications in Dart. It provides essential types for graphics and physics, including vectors, matrices, quaternions, and collision detection primitives like Aabb2. The library supports GLSL-style swizzled getters and setters and offers both 32-bit and 64-bit float precision (via vector_math_64.dart). It is used by major projects such as Flutter and Flame.

Tokens
17K
Snippets
61
Records
66
Agent score
55%

What's inside vector_math

  1. Overview of vector_math

    master
    A high-performance vector math library for Dart designed for 2D and 3D applications. It provides essential types for graphics and physics, including vectors, matrices, quaternions, and collision detection primitives. It is heavily optimized and used by major projects like Flutter and Flame.
  2. Use the Quaternion class for rotations

    master

    The Quaternion class provides a four-dimensional vector implementation designed for efficient rotation calculations. Quaternions are preferred over Euler rotations for interpolating between rotations and for avoiding the gimbal lock problem.

    Key capabilities include:

    • Constructing rotations from axis-angles, rotation matrices, or Euler angles (yaw, pitch, roll).
    • Rotating vectors in 3D space.
    • Performing quaternion arithmetic (addition, subtraction, multiplication/composition).
    • Converting to and from Matrix3 rotation matrices.
    // Example: Creating a rotation and rotating a vector
    final rotation = Quaternion.axisAngle(Vector3(0, 1, 0), math.pi / 2); // 90 deg around Y
    final point = Vector3(1, 0, 0);
    final rotatedPoint = rotation.rotated(point);
  3. Invert a matrix

    master

    The library provides methods to invert a Matrix4 entirely using invert(), or to invert only the rotation component using invertRotation().

    import 'dart:math';
    import 'package:vector_math/vector_math.dart';
    
    void main() {
      // Rotation of 90 degrees around the Y axis followed by a
      // translation of (5.0, 2.0, 3.0).
      Matrix4 T = Matrix4.rotationY(PI * 0.5)..translate(5.0, 2.0, 3.0);
      // Invert T.
      T.invert();
      // Invert just the rotation in T.
      T.invertRotation();
    }
  4. Transform a vector using a matrix

    master

    You can apply transformations (like rotation and translation) to a Vector3 using a Matrix4 via the transform3 method.

    import 'dart:math';
    import 'package:vector_math/vector_math.dart';
    
    void main() {
      // Rotation of PI/2 degrees around the Y axis followed by a
      // translation of (5.0, 2.0, 3.0).
      Matrix4 T = Matrix4.rotationY(PI * 0.5)..translate(5.0, 2.0, 3.0);
      // A point.
      Vector3 position = Vector3(1.0, 1.0, 1.0);
      // Transform position by T.
      T.transform3(position);
    }
  5. Rotate a vector using a Quaternion

    master

    To rotate a Vector3 around an arbitrary axis, create a Quaternion using Quaternion.axisAngle(axis, angle) and then call rotate(vector).

    import 'dart:math';
    import 'package:vector_math/vector_math.dart';
    
    void main() {
      // The X axis.
      Vector3 axis = Vector3(1.0, 0.0, 0.0);
      // 90 degrees.
      double angle = PI / 2.0;
      // Quaternion encoding a 90 degree rotation along the X axis.
      Quaternion q = Quaternion.axisAngle(axis, angle);
      // A point.
      Vector3 point = Vector3(1.0, 1.0, 1.0);
      // Rotate point by q.
      q.rotate(point);
    }
  6. Perform Ray-Sphere intersection detection

    master

    To find where a Ray intersects a Sphere, use ray.intersectsWithSphere(sphere). This returns the distance from the ray origin to the intersection point, or null if no intersection occurs. Use ray.at(distance) to retrieve the exact Vector3 position of the intersection.

    import 'package:vector_math/vector_math.dart';
    
    void main() {
      // Define a ray starting at the origin and going into positive x-direction.
      Ray ray = Ray.originDirection(Vector3.zero(), Vector3(1.0, 0.0, 0.0));
      // Defines a sphere with the center (5.0 0.0 0.0) and a radius of 2.
      Sphere sphere = Sphere.centerRadius(Vector3(5.0, 0.0, 0.0), 2.0);
      // Checks if the ray intersect with the sphere and returns the distance of the
      // intersection from the origin of the ray. Would return null if no intersection
      // is found.
      double distanceFromOrigin = ray.intersectsWithSphere(sphere);
      // Evaluate the position of the intersection, in this case (3.0 0.0 0.0).
      Vector3 position = ray.at(distanceFromOrigin);
    }
  7. Work with colors

    master

    Colors are handled as Vector4 types. The Colors utility class provides methods for common operations:

    • Colors.toGrayscale(source, destination)
    • Colors.fromHexString(hexString, destination)
    • Colors.rgbToHsl(source, destination)
    • Colors.hslToRgb(source, destination)
    import 'package:vector_math/vector_math.dart';
    
    void main() {
      // Access a build-in color, colors are stored in 4-dimensional vectors.
      Vector4 red = Colors.red;
      Vector4 gray = Vector4.zero();
      // Convert the red color to a grayscaled color.
      Colors.toGrayscale(red, gray);
      // Parse a blue color from a hex string.
      Vector4 blue = Vector4.zero();
      Colors.fromHexString('#0000FF', blue);
      // Convert the blue color from RGB to HSL.
      Colors.rgbToHsl(blue, blue);
      // Reduce the lightness of the color by 50%.
      blue.z *= 0.5;
      // Convert the HSL color back to RGB.
      Colors.hslToRgb(blue, blue);
    }
  8. Use GLSL-style getters and setters

    master

    The library supports flexible, swizzled-style getters and setters similar to GLSL. This allows you to assign multiple components of one vector to multiple components of another in a single operation using component names like x, y, z, w, r, g, b, etc.

    import 'package:vector_math/vector_math.dart';
    
    void main() {
      Vector3 x = Vector3.zero(); // Zero vector
      Vector4 y = Vector4.all(4.0); // Vector with 4.0 in all lanes
      x.zyx = y.xzz; // Sets z,y,x the values in x,z,z
    }
  9. Perform AABB collision detection

    master

    Use Aabb2 (Axis-Aligned Bounding Box) to check for intersections between two boxes using intersectsWithAabb2. You can also use hullPoint to expand a box to include a specific point.

    import 'package:vector_math/vector_math.dart';
    
    void main() {
      // Define the first box with a minimum and a maximum.
      Aabb2 aabbOne = Aabb2.minMax(Vector2.zero(), Vector2(4.0, 4.0));
      // Define the second box
      Aabb2 aabbTwo = Aabb2.minMax(Vector2(5.0, 5.0), Vector2(6.0, 6.0));
      // Extend the second box to contain a point
      aabbTwo.hullPoint(Vector2(3.0, 3.0));
      // Check if the two boxes intersect, returns true in this case.
      bool intersect = aabbOne.intersectsWithAabb2(aabbTwo);
    }
  10. Use 64-bit float precision

    master

    If your application requires 64-bit float precision instead of the default 32-bit, import package:vector_math/vector_math_64.dart instead of the standard library. The API and types remain identical, but they use 64-bit storage.

    // Use different import statement.
    // Which is a drop-in replacement for 'package:vector_math/vector_math.dart'
    import 'package:vector_math/vector_math_64.dart';
    void main() {
      // Types work the same, but using 64 bit storage.
      Vector3 x = Vector3.zero(); 
      Matrix4 m = Matrix4.identity();
    }
  11. Use Vector3 geometric operations

    master

    Perform common 3D geometric calculations with these methods:

    • dot(other): Computes the dot product (inner product) of two vectors.
    • cross(other): Computes the cross product, returning a new Vector3.
    • crossInto(other, out): Computes the cross product and stores the result in the provided out vector.
    • reflect(normal): Reflects the vector across a given normal in-place.
    • reflected(normal): Returns a new reflected Vector3.
    • applyAxisAngle(axis, angle): Rotates the vector using an axis and an angle.
    • applyQuaternion(quaternion): Rotates the vector using a Quaternion.
    var v1 = Vector3(1, 0, 0);
    var v2 = Vector3(0, 1, 0);
    
    // Cross product (result should be [0, 0, 1])
    var cp = v1.cross(v2);
    
    // Dot product
    double d = v1.dot(v2); // 0.0
  12. Clamp and transform vectors

    master

    Use these methods for bounding and geometric transformations:

    • clamp(min, max): Clamps each component of the vector within the ranges defined by the min and max vectors.
    • clampScalar(min, max): Clamps each component within a scalar range.
    • reflect(normal): Reflects the vector across a given normal vector.
    • reflected(normal): Returns a new reflected copy of the vector.
    • postmultiply(matrix): Transforms this vector as a row vector, postmultiplied by a Matrix2.
    • scaleOrthogonalInto(scale, out): Rotates the vector 90 degrees and scales it, storing the result in out.
    var v = Vector2(10, 10);
    var min = Vector2(0, 0);
    var max = Vector2(5, 5);
    v.clamp(min, max); // v is now [5.0, 5.0]
    
    var normal = Vector2(1, 0);
    var v2 = Vector2(-1, 1);
    v2.reflect(normal); // v2 is now [1.0, 1.0]