Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Quality improvements to matrix and its test suite #21

Open
wants to merge 3 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 11 additions & 5 deletions lib/matrix.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,13 @@ var Matrix = function Matrix (rows, cols, isIdentity) {
}

//square matrices can be declared as identities:
if(this.rows === this.cols && isIdentity){
for(var i = 0; i<this.rows; i++)
this.m[i][i] = 1;
if ( isIdentity ) {
if (this.rows !== this.cols) {
throw new Error('this is not a square matrix');
} else {
for(var i = 0; i<this.rows; i++)
this.m[i][i] = 1;
}
}

this.isVector = false;
Expand Down Expand Up @@ -180,9 +184,10 @@ Matrix.prototype = {
// construct this iteration's lower triangular matrix:
l = new Matrix(this.rows, this.cols, true);
for (row = iter; row < this.rows; row++) {
if(A.m[iter - 1][iter - 1] === 0)
if(A.m[iter - 1][iter - 1] === 0){
//bail out to the brute force calculation
return this.cofactorDet()
}
l.m[row][iter - 1] = -1 * A.m[row][iter - 1] / A.m[iter - 1][iter - 1];
L.m[row][iter - 1] = -1 * l.m[row][iter - 1];
}
Expand Down Expand Up @@ -217,7 +222,7 @@ Matrix.prototype = {
if (this.rows === 4 && this.cols === 4)
return new v(this.get(0, 3), this.get(1, 3), this.get(2,3));
else
return new Error('this is not a homogeneous matrix');
throw new Error('this is not a homogeneous matrix');
},

getRot: function () {
Expand Down Expand Up @@ -247,4 +252,5 @@ Matrix.prototype = {
};



exports = module.exports = Matrix;
70 changes: 70 additions & 0 deletions tests/matrix-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,15 @@ describe('Creating matrices: ', function () {
D.should.eql(7);
done();
});
it('allows identity matrix iff matrix is square', function (){
(function () {
var A = new Matrix(7, 3, true);
}).should.throw();
});
describe('2x2 matrices: ', function () {
var A = new Matrix(2,2);
var B = new Matrix(2,2);
var D = new Matrix(2,2);

it('should set a specific value', function () {
// var A = new Matrix(3,4);
Expand Down Expand Up @@ -84,11 +90,29 @@ describe('Creating matrices: ', function () {
C.get(1,1).should.eql(-4);

});

it('scale detects out of bounds access', function () {
D.set(0,0,2);
D.set(0,1,4);
D.set(0,2,Infinity);
D.set(1,0,6);
D.set(1,1,8);
D.set(1,2,Infinity);
var C = D.scale(-1);
C.get(0,0).should.eql(-2);
C.get(0,1).should.eql(-4);
C.get(1,0).should.eql(-6);
C.get(1,1).should.eql(-8);
should.not.exist(C.get(0,2));
should.not.exist(C.get(1,2));
});

});

describe('3x3 matrices: ', function () {
var A = new Matrix(3,3);
var B = new Matrix(3,3);
var D = new Matrix(3,3);

it('should set a specific value', function () {
A.set(0,0,1);
Expand Down Expand Up @@ -153,6 +177,18 @@ describe('Creating matrices: ', function () {
it('should calculate the determinant of the matrix', function () {
var C = A.det();
C.should.eql(0);

D.set(0,0,0);
D.set(0,1,1);
D.set(0,2,1);
D.set(1,0,1);
D.set(1,1,1);
D.set(1,2,1);
D.set(2,0,1);
D.set(2,1,1);
D.set(2,2,1);
var C = D.det();
parseFloat(D.det().toFixed(12)).should.eql(0);
});

it('should calculate the trace of the matrix', function () {
Expand Down Expand Up @@ -183,6 +219,40 @@ describe('Creating matrices: ', function () {

parseFloat(A.det().toFixed(10)).should.eql(-23);
});

it('detects non-homogenous matrix', function () {
(function () {
var A = new Matrix(3, 4);
A.getPoint();
}).should.throw();
});

it('returns the specified point', function () {
var A = new Matrix(4, 4);
A.setRow(0, [3,4,4,-1]);
A.setRow(1, [2,1,5,3]);
A.setRow(2, [2,1,3,4]);
A.setRow(3, [0,-2,1,3]);
A.getPoint().v.should.eql([-1,3,4]);
});

it('calculates the rotation vector for the matrix', function () {
var D = new Matrix(4,4);
D.setRow(0, [0.2,1,1,1]);
D.setRow(1, [1,0.3,1,1]);
D.setRow(2, [1,1,0.1,1]);
D.setRow(3, [0,1,1,1]);
D.calcRotVec().should.eql(new Vector(0, 0, 0));

var D = new Matrix(4,4);
D.setRow(0, [-0.03,1,1,1]);
D.setRow(1, [-1,-0.2,1,1]);
D.setRow(2, [-1,-1,-0.1,1]);
D.setRow(3, [0,-1,-1,-1]);
D.calcRotVec().should.eql(new Vector(-1.338968862122, 1.338968862122, -1.338968862122));

});

});
describe('5x5 matrix', function () {
it('should calculate det', function () {
Expand Down
31 changes: 31 additions & 0 deletions tests/vector-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,11 @@ var v = require('../').vector;
var should = require('should');

describe('Creating vectors: ', function () {
it('truly creates a vector', function () {
var a = new v(1);
a.isVector.should.eql(true);
});

it('Should pass with 3 arguments', function () {
var a = new v(1,0,0);
a.v.length.should.eql(3);
Expand Down Expand Up @@ -29,28 +34,54 @@ describe('Creating vectors: ', function () {

var a = new v(1,0,0);
var b = new v(1,1,0);
var d = new v(0,1,1);

describe('Between two vectors: ', function () {
it('should add two vectors easily', function () {
var c = a.add(b);
c.v.length.should.eql(3);
c.v.should.eql([ 2, 1, 0 ]);

var c = a.add(d);
c.v.length.should.eql(3);
c.v.should.eql([ 1, 1, 1 ]);
});

it('should calculate the dot product', function () {
var c = a.dot(b);
c.should.eql(1);

var c = a.dot(d);
c.should.eql(0);
});

it('should calculate the cross product', function () {
var c = a.cross(b);
c.v.length.should.eql(3);
c.v.should.eql([0,0,1]);

var c = b.cross(a);
c.v.length.should.eql(3);
c.v.should.eql([0,0,-1]);

var c = a.cross(d);
c.v.length.should.eql(3);
c.v.should.eql([0,-1,1]);

var c = d.cross(b);
c.v.length.should.eql(3);
c.v.should.eql([-1,1,-1]);
});

it('should calculate the distance between the two', function () {
var c = a.distanceFrom(b);
c.should.eql(1);

var c = a.distanceFrom(a);
c.should.eql(0);

var c = b.distanceFrom(d);
c.should.eql(Math.sqrt(2));
});

it('should calculate the length of the vector', function () {
Expand Down