Git Product home page Git Product logo

vector_math.dart's Introduction

Dart pub package package publisher Coverage Status

Introduction

A Vector math library for 2D and 3D applications.

Features

  • 2D, 3D, and 4D vector and matrix types.
  • Quaternion type for animating rotations.
  • Collision detection: AABB, rays, spheres, ...
  • Utilities like color and common rendering related operations
  • Flexible getters and setters, for example, position.xwz = color.grb;.
  • Fully documented.
  • Well tested.
  • Heavily optimized.

Libraries using vector_math

Examples

1. Using the GLSL getter and setter syntax.

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
}

2. Transforming a vector.

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);
}

3. Invert a matrix

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. Rotate a vector using a quaternion

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);
}

5. Check if two axis aligned bounding boxes intersect

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);
}

6. Check where a ray and a sphere intersect

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

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 64bit float precision (instead of 32bit)

// 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();
}

Development

To run the unit tests:

~/src/vector_math/> dart test

To automatically generate the latest version of vector_math_64:

~/src/vector_math/> dart tool/generate_vector_math_64.dart

vector_math.dart's People

Contributors

adam-singer avatar amagill avatar andersforsell avatar bramp avatar brason avatar dependabot[bot] avatar devoncarew avatar dmah42 avatar donny-dont avatar eoineoineoin avatar fkleon avatar fox32 avatar jakemac53 avatar johnmccutchan avatar kevmoo avatar laszlokorte avatar lexaknyazev avatar lohandus avatar moritzblume avatar natebosch avatar pjako avatar pseudopeach avatar rakudrama avatar spydon avatar steveno avatar tlserver avatar toji avatar tvolkert avatar udhos avatar zach-brockway avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

vector_math.dart's Issues

nit on ChangeLog.txt

Why not make ChangeLog.txt a Markdown file so pub.dartlang.org can render it nicely?

Support n-dimensional vectors

Can a new Vector class be added that represents a vector of arbitrary length?

It seems the current implementation of classes Vector2, Vector3, and Vector4 can be generalized to form a new class VectorN, which would also implement Vector.

Clearly, 2, 3, and 4 dimensional vectors are sufficient for many applications. However there are applications where this restriction becomes prohibitive. The options for overcoming this restriction include creating another pub package, or a custom implementation in the application itself; neither of which promotes re-use, nor settling on a common package for solving a very common problem.

As an example, pub package math_expressions has the set goal of "[...]supporting real, vector and interval evaluations of mathematical expressions." As the package depends on vector_math it is currently limited to evaluating expressions involving up to 4-dimensional vectors. An issue has been filed to look into options for eliminating this limitation. One of the options is for math_expressions to add a class that implements Vector and represents vectors of arbitrary length, but it seems such a class would better belong invector_math to promote standardizing on a singe package for representing vectors of all types.

Aabb2 does not enforce max.x >= min.x or max.y >= min.y

It's possible to reverse the max and min inputs when creating a Aabb2, which leads to problems. E.g.

Aabb2 x = new Aabb2.minMax(new Vector2(2.0, 2.0), new Vector2(-2.0, -2.0));  // Min, max reversed
Aabb2 y = new Aabb2.minMax(new Vector2(-1.0, -1.0), new Vector2(1.0, 1.0));
print(x.containsAabb2(y)); // False

similarly, the halfextents vector x and y coordinates may be < 0;

Aabb2 z = new Aabb2.centerAndHalfExtents(new Vector2.zero(), new Vector2(-1.0, -1.0));
print(z.min); // [1.0,1.0]
print(z.max); // [-1.0,-1.0]

I note that there is an intention to maintain min and max through rotation (but see #153).

Aabb2 w = new Aabb2.centerAndHalfExtents(new Vector2.zero(), new Vector2(2.0, 1.0));
print(w.min); // [-2.0,-1.0]
print(w.max); // [2.0,1.0]
w.rotate(new Matrix3.rotationZ((PI/2)));
print(w.min); // [-1.0,-2.0]
print(w.max); // [1.0,2.0]

Solution?

Aabb2.centerAndHalfExtents() could simply take the absolute value of the half extents vector.

I would suggest removing

Aabb2.minMax(Vector2 min, Vector2 min)

and replacing it with something like

Aabb2.around(Vector2 a, Vector2 b)

which should construct a minimal Aabb2 to include a and b. Also possibly

Aabb2.around(Iterable<Vector2> a)

Or at least putting a huge warning in the documentation for Aabb2.minMax(Vector2 min, Vector2 min).

Add dotRow and dotColumn to Matrix2/3/4 classes

class Matrix2 {
double dotRow(int i, Vector2 v) {
// dot product between row i and v.
}

double dotColumn(int j, Vector2 v) {
// dot product between column j and v.
}
}

Repeat for Matrix3 and Matrix4.

Example code in readme.md

First, thanks for this library, it seems pretty powerful and I'm looking forward to diving into it.

As I'm only just trying out this library, I noticed that part of the first example doesn't compile:

Vector4 y = new Vector4.splat(4.0); 

Unless I'm mistaken, it seems that I need to either do:

Vector4 y = new Vector4.zero()..splat(4.0);

or (what I think would be better) a named constructor for Vector4.splat() needs to be added.

Other than pi needing to be capitalized and pulled in from dart:math, the rest of the snippets are working for me.

Thanks again!

cheers,
Rich

Add matrix solve methods

class Matrix2 {
// Solve A x = b.
static void solve(Matrix2 A, Vector2 x, Vector2 b);
}

class Matrix3 {
static void solve(Matrix3 A, Vector3 x, Vector3 b);
static void solve2(Matrix3 A, Vector2 x, Vector2 b);
}

class Matrix4 {
static void solve(Matrix4 A, Vector4 x, Vector4 b);
static void solve3(Matrix4 A, Vector3 x, Vector3 b);
static void solve2(Matrix4 A, Vector2 x, Vector2 b);
}

Why not matrix types?

Why not matrix types, such:
mat2x3
mat2x4
mat3x2
mat3x4
mat4x2
mat4x3
???

They has been added for WebGL2, but removed from Dart.

Make AABB classes based on center + half instead of min + max

In my experience, most common AABB operations, including transformations and collision detection and response, use center + half more often than min + max, or position + size.

Because the current implementation is based on min + max vectors, many times it's required to allocate new vectors and use copyCenterAndHalfExtents.

Basing the class on center + half vectors would allow for some very small optimization, but most importantly it would make the API nicer.

I would like to read opinions on the matter.

Please add recipe for sending mat4 to GPU as WebGL uniform

I am currently using this, though I am unsure whether I can keep relying on the column-major mode?

Program p = gl.createProgram();
// (...)
UniformLocation u_MV = gl.getUniformLocation(p, "u_MV");
// (...)
mat4 modelViewMatrix = new mat4.identity();
// (...)
List<num> MV_tmp = new List<num>(16); 
modelViewMatrix.copyIntoArray(MV_tmp);
gl.uniformMatrix4fv(u_MV, false, MV_tmp);

Add min and max methods

class Vector2 {
static min(Vector2 a, Vector2 b, Vector2 result);
static max(Vector2 a, Vector2 b, Vector2 result);
}

class Vector3 {
...
}

class Vector4 {
...
}

dart2js halts with: library not found dart:typed_data (Dart SDK version 0.5.0.1_r21823)

This is from Dart SDK version 0.5.0.1_r21823.
I guess vector_math works only against bleeding_edge ... ?

--- 26/04/2013 04:25:36 Running dart2js... ---
C:\dart\dart-sdk\bin\dart2js.bat --suppress-warnings --out=C:\tmp\devel\negentropia\wwwroot\dart\negentropia_home.dart.js C:\tmp\devel\negentropia\wwwroot\dart\negentropia_home.dart
Using snapshot "C:\dart\dart-sdk\bin\snapshots\utils_wrapper.dart.snapshot" 
/C:/tmp/devel/negentropia/wwwroot/dart/packages/vector_math/vector_math.dart:23:8: Error: library not found dart:typed_data
import 'dart:typed_data';

       ^^^^^^^^^^^^^^^^^
Error: Compilation failed.

`pub upgrade` fails with an exception

Failed to precompile vector_math:matrix_bench:
Unhandled exception:
Uncaught Error: Failure getting http://localhost:53308/packages/benchmark_harness/benchmark_harness.dart: 404 Not Found
Stack Trace:
#0 _asyncLoadError (dart:_builtin:339)
#1 _httpGet.. (dart:_builtin:128)
#2 _RootZone.runGuarded (dart:async/zone.dart:1009)
#3 _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:390)
#4 _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:399)
#5 _BufferingStreamSubscription._close (dart:async/stream_impl.dart:290)
#6 _ForwardingStream._handleDone (dart:async/stream_pipe.dart:94)
#7 _handleDone (dart:async/stream_pipe.dart:162)
#8 _RootZone.runGuarded (dart:async/zone.dart:1009)
#9 _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:390)
#10 _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:399)
#11 _DelayedDone.perform (dart:async/stream_impl.dart:614)
#12 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:711)
#13 _PendingEvents.schedule. (dart:async/stream_impl.dart:671)
#14 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#15 _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#16 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:84)
#17 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:131)
#0 _rootHandleUncaughtError. (dart:async/zone.dart:820)
#1 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#2 _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#3 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:84)
#4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:131)

Failed to precompile intl:generate_from_arb:
Unhandled exception:
Uncaught Error: Failure getting http://localhost:59436/packages/petitparser/petitparser.dart: 404 Not Found
Stack Trace:
#0 _asyncLoadError (dart:_builtin:339)
#1 _httpGet.. (dart:_builtin:128)
#2 _RootZone.runGuarded (dart:async/zone.dart:1009)
#3 _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:390)
#4 _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:399)
#5 _BufferingStreamSubscription._close (dart:async/stream_impl.dart:290)
#6 _ForwardingStream._handleDone (dart:async/stream_pipe.dart:94)
#7 _handleDone (dart:async/stream_pipe.dart:162)
#8 _RootZone.runGuarded (dart:async/zone.dart:1009)
#9 _BufferingStreamSubscription._sendDone.sendDone (dart:async/stream_impl.dart:390)
#10 _BufferingStreamSubscription._sendDone (dart:async/stream_impl.dart:399)
#11 _DelayedDone.perform (dart:async/stream_impl.dart:614)
#12 _StreamImplEvents.handleNext (dart:async/stream_impl.dart:711)
#13 _PendingEvents.schedule. (dart:async/stream_impl.dart:671)
#14 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#15 _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#16 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:84)
#17 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:131)
#0 _rootHandleUncaughtError. (dart:async/zone.dart:820)
#1 _asyncRunCallbackLoop (dart:async/schedule_microtask.dart:41)
#2 _asyncRunCallback (dart:async/schedule_microtask.dart:48)
#3 _runPendingImmediateCallback (dart:isolate-patch/isolate_patch.dart:84)
#4 _RawReceivePortImpl._handleMessage (dart:isolate-patch/isolate_patch.dart:131)

Precompiled polymer:new_element.
Precompiled polymer:new_entry.
Precompiled di:generator.
Precompiled vector_math:mesh_generator.
Precompiled intl:extract_to_arb.

Dart VM version: 1.6.0-edge.39587 (Wed Aug 27 02:59:03 2014) on "linux_x64"

cw rotation positive?

Am new to this 3d stuff. But are you considering clockwise rotations to be positive and anti-clockwise rotations to be negative?

Float32x4 for Vector4 (3) instead of List

as I 'pub'ed the new version of vector_math I notice that mat4 is already backed by Float32List.
Is it only due to time or is there some reason why
Vector4 (3, 2?) should not use "Float32x4" (which should speed vector operations up, especially when + two vectors)

greez

Porting across my math library contributions from ThreeJS to vector_math?

Great library you have here. I wrote about half of the math types in the ThreeJS library along with the majority of the math unit tests:

https://github.com/mrdoob/three.js/tree/master/src/math
https://github.com/mrdoob/three.js/tree/master/test/unit/math

I'm interested in porting those improvements to this dart library. Would you be open to me contributing these classes:

Box2
Box3
Plane
Sphere
Line3
Ray
Triangle
Color

Let me know.

opengl utility to set rotation matrix ?

I'm using the following method to initalize the model's rotation matrix for every instance:

  Matrix4 _rotation = new Matrix4.identity();

  void setRotation(Vector3 front, up) {
    Vector3 right = front.cross(up).normalize();

    _rotation.setValues(front[0], up[0], right[0], 0.0, front[1], up[1],
        right[1], 0.0, front[2], up[2], right[2], 0.0, 0.0, 0.0, 0.0, 1.0);
  }

Would it make sense to add a similar utility method to opengl.dart ? Like this:

void setRotationMatrix(Matrix4 rotationMatrix, Vector3 front, up) { /* ... */ }

Everton

Add a Vector1List?

Lately I've been packing WebGL vertex buffers with interleaved attributes something like so:

var vtAttributes = new Float32List(nVertices * stride);
var vtPos    = new Vector3List.view(vtAttributes, 0, stride);
var vtTex    = new Vector2List.view(vtAttributes, 3, stride);
var vtNormal = new Vector3List.view(vtAttributes, 5, stride);

for (var i = 0; i < nVertices; i++) {
  vtPos[i]    = new Vector3( ... );
  vtTex[i]    = new Vector2( ... );
  vtNormal[i] = new Vector3( ... );
}

This works nicely.. except when one of those attributes is a single float. I suppose what I really want is a 'stride' parameter on Float32List.view(), but I wonder if it would make sense to implement a Vector1List that would line up with the rest of the vector_math API. I know it seems like a silly idea, and I know it's easy to work around, but it would be useful.

Read only data structures

Sometimes to write clearner API interfaces, it would be nice if I could return a Vector (or something else) from a object, but it shouldn't be possbile to modify the internal state. My normal approch for this would be:

final _position = new Vector3();

Vector3 get position => _position.clone();

But the problem it, that it creates a copy of the object and that copy might have a very short lifetime In the target area of this library, allocations can become a problem. For me that mean that I avoid creating copies of the vectors, but also drop the protection of the internal state.

One solution could be a interface like ReadOnlyVector. ReadOnlyVector contains everything that only access the vector, but doesn't modifiy it. The Vector class implements it and all parameters of methods that are only read, should be updated to the read only version. For example for Vector3 (but I think it could be applied to most of the types):

class Vector3 implement ReadOnlyVector3 {
 double get x;

  // .... clone, etc.
}

class Vector3 implement ReadOnlyVector3 {

  double get x => storage[0];
  set x(double arg) => storage[0] = arg;

  Vector3 add(ReadOnlyVector3 arg) {
     storage[0] = storage[0] + arg.storage[0]; 
     // This is a problem... as storage shouldn't be in the interface, but if 
     // ReadOnlyVector3 only has the Vector3 implementation this might be useable?
     // Is the direct access required to allow optimisations, or would it also be possbile
     // to use the index operator?

     //...

     return this;
   }

  // ....

}

Any thoughts on it?
It it worth the changes?
I wonder if this comes with performance impacts?
Does it come with breaking changes?
Am I the only one who would like to have a read only version of a vector?

This is also a reason, why haven't done issue #35 yet (at least the Colors enum part).

PS: How about updating the Pub version of vector_math? I saw many people in the last weeks that are using the old version released on Pub and I don't think that they know that there is a more recent (and more feature rich) version on GitHub (or a least they just import it without reading that part of the readme)

Change storage to allow creating it from a ByteBuffer

I have a usecase where it would be helpful to create Vector3/Matrix4 ect. from a ByteBuffer.
So something like this would be nice:

class Vector3 {
  final Float32List storage;

  Vector3() : storage = new Float32List(3);

  Vector3.fromFloat32List(Float32List this.storage);

  Vector3.fromBuffer(ByteBuffer buffer, int offset) : storage = new Float32List.view(buffer, offset, 3);
}

Matrix constructor that takes a list

I have code where I ended up doing:

Matrix4 transform = Function.apply(new Matrix4#, matrixArray);

...where matrixArray is a list of 16 doubles.

It would be cleaner if there was a constructor I could call that took care of this for me.

Where can I find this function?

I came across this in three.dart, but cannot find a good equivalent function in vector_math (Matrix4.transform3 is the same but without the d scaling).

Any suggestion?

Vector3 multiplyVector3(Matrix4 te, Vector3 v ) {
var vx = v.x, vy = v.y, vz = v.z;
var d = 1.0 / ( te[3] * vx + te[7] * vy + te[11] * vz + te[15] );

v[0] = ( te[0] * vx + te[4] * vy + te[8] * vz + te[12] ) * d;
v[1] = ( te[1] * vx + te[5] * vy + te[9] * vz + te[13] ) * d;
v[2] = ( te[2] * vx + te[6] * vy + te[10] * vz + te[14] ) * d;
return v;
}

Build problems

I think something is wrong with the drone.io build of vector_math. The latest build was some days ago, but some commits where made after that. What happend to the other build that should be there, e.g. my commit that was supposed to fix the build was never build?

Release timeline

The current version of vector_math available on pub is quite outdated compared to master. Is there a timeline for future releases, and would it be possible to prepare a new release with the fixes merged since 1.4.3?

The newest version of my library math_expressions depends on some of the changes made since 1.4.3 was released, and the pub dependency to a git repository leads to certain problems such as fkleon/math-expressions#4 - which is why that approach is not recommended in the first place. Unfortunately I don't see a way around this without a new release of vector_math to pub.

Matrix4.inverted constructor misuses ArgumentError

No constructor 'ArgumentError' with matching arguments declared in class 'ArgumentError'.
NoSuchMethodError: incorrect number of arguments passed to method named 'ArgumentError'
Receiver: Type: class 'ArgumentError'
Tried calling: ArgumentError(Instance of 'Matrix4', "other", "Matrix cannot be inverted")
Found: ArgumentError([dynamic])

#0      NoSuchMethodError._throwNew (dart:core-patch/errors_patch.dart:188)
#1      Matrix4.Matrix4.inverted (.../packages/vector_math/lib/src/vector_math_64/matrix4.dart:206)

More Refactoring type names

With the recent change from vec3 to Vector3 ect.
consider to change for example aabb to AABB and all other other classes that are lowercased

Please consider pull request #83

John,

Please consider merging #83

Make setRotationMatrix() compatible, in respect to inversion, with setViewMatrix().
Add helper setModelMatrix().
Add slightly simpler/faster setViewMatrix2().
setViewMatrix(RunTime): 118.21728336682823 us.
setViewMatrix2(RunTime): 73.02201613786556 us.

Thanks,
Everton

Immutable/const versions?

How about providing immutable versions of vector/matrix (and/or const constructors)?
I.e. convert these into 'value types'.

Call chaining support

I think call/method chaining is a nice feature and even better, Dart comes with support for that! So how about dropping the call chaining support in vector_math?

Pro:

  • Why adding something that is already supported?
  • Better distinction between methods that return itself for chaining and methods that really return a new instance: For example, normalize vs normalized. I know that there is already the naming convention, but it could be easier.

Cons:

  • BREAKING CHANGE
  • Typing one more '.'?
  • Work, programmers are lazy (but I could do it, if we decide to go this way)

I'm not sure about the performance influence of this change. This is something for a person with in-depth knowledge. Maybe there was a good reasons forthe decision to implement call chaining (or Dart doesn't supported it back then).

Matrix operator*

The Matrix operator* will always fail with "NoSuchMethodError" when the operand is not a double/vector or matrix instead of ArgumentError as the comparison
{number} == arg.dimension
assumes its some object with a getter "dimension" (which most probably has not one).

I think this should be
arg is Matrix* && {number} == arg.dimension

Proposal to add setFromUnitVectors and dot methods to Quaternion library

I am working on porting some of the controls from the three.js engine into three.dart and I noticed that some of the "convenience" methods that were included in three.js's Quaternion library did not make it into this project (understandably so). Please let me know if I missed them.

Therefore, I was wondering if you would like to accept them into your project? The methods I am referring to are:

  • Quaternion.setFromUnitVectors( vFrom, vTo ) Reference Documentation - yields the quaternion describing the rotation between the two directional unit vectors that are provided. The three.js project authors seem to have adopted it from an implementation discussed here.
  • Quaternion.dot( v ) - dot product of two quaternions.

Curiously enough, I could not find the second method (.dot()) in the three.js documentation, but it is shown in the source here.

If you think that these are a good fit for this project, I can certainly provide a PR.

Please see my rather hackish implementations here:

I will, of course, clean these up to conform to the existing vector_math project source and style on a PR.

Please let me know if this of interest.

More methods to modify a vector list

When working with vector lists one often has to create new vector instances to modify the list:

var v = new Vector(a, b, c);
list.store(index, v);

I was working on some code and missed some shortcuts. I would like to add more methods to directly modify the VectorList like the following ones:

  • setValues(index, x, y, ...)
  • add(index, vec)
  • sub(index, vec)
  • scale(index, factor)
  • multiply(index, vec)
  • addScaled(index, vec, factor)
  • setZero(index)

It is questionable if it makes sense to add them to the VectorList base class or only to the derived ones. For example setValues wouldn't make sense on the base class as it would have different arguments for each derived class.

PS: This is not an issue but more a todo list for myself ;-) I will send a PR later, after the current plans are completed.

Extending classes/factory constructors

@Fox32 Extending classes with factory constructors is kind of a pain, especially if a class only has factory constructors, like in Quaternion. I think it should be possible to extend all vector_math classes cleanly, without having to use delegation, so my suggestion would be that we go back to using normal constructors again. Any thoughts?

Colors

Vector4 is designed to hold color values, too. What I'm missing are methods to convert colors to and from other formats like:

  • RGB(A)
  • Hex RGB String (like CSS color)
  • (HSV)

A colors class with definition of some known colors would be nice for fast prototyping, like:

colors.red => new Vector4(1.0, 0.0, 0.0, 1.0)
colors.green => new Vector4(0.0, 1.0, 0.0, 1.0)
...
colors.all => [colors.red, colors.green, ...] // Allows to choose a random color if needed

I could implement this. But the question is, is this more a vector_math or spectre related thing? Or is a own color class, like three.js has, the way to go?

Noise isn't noisy

The SimplexNoise class seems to produce a regular patten, not noise.

The screenshot below compares my own Simplex noise code on top, with the vector_math SimplexNoise class on bottom. The following code was used to produce both images:

  var simplex = new SimplexNoise();
  var canvas = document.querySelector("#canvas");
  var ctx = canvas.getContext('2d');

  var img = ctx.createImageData(canvas.width, canvas.height);

  for (var y = 0; y < canvas.height; y++) {
    for (var x = 0; x < canvas.width; x++) {
      var noise = simplex.noise2D(x/50, y/50.0);
      int val = ((noise + 1) * 128).round();
      int i = x + y*canvas.width;
      img.data[i*4 + 0] = val;
      img.data[i*4 + 1] = val;
      img.data[i*4 + 2] = val;
      img.data[i*4 + 3] = 255;
    }
  }

  ctx.putImageData(img, 0, 0);

image

Aabb2 rotation broken

Aabb2 z = new Aabb2.minMax(new Vector2(1.0, 1.0), new Vector2(2.0, 2.0));

print(z.min); // [1.0,1.0]
print(z.max); // [2.0,2.0]

z.rotate(new Matrix3.rotationZ((PI/2))); // Rotate 90 degrees

print(z.min); // still [1.0,1.0]
print(z.max); // still [2.0,2.0]

I believe this is because an absolute rotation is being applied to min and max separately.

pub.dartlang.org

Has the latest been published? There aren't any tags for the versions, making it difficult to compare pub to github.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.