Skip to content

Instantly share code, notes, and snippets.

@TorbenKoehn
Created August 23, 2019 22:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save TorbenKoehn/dd04a08fc40235ad3f30fe12e4c17eb7 to your computer and use it in GitHub Desktop.
Save TorbenKoehn/dd04a08fc40235ad3f30fe12e4c17eb7 to your computer and use it in GitHub Desktop.
2D-affine matrices
export default class TransformationMatrix
{
a;
b;
c;
d;
tx;
ty;
get determinant()
{
return (this.a * this.d) - (this.b * this.c);
}
constructor(a, b, c, d, tx, ty)
{
this.a = typeof d !== 'undefined' ? a : 1;
this.b = b || 0;
this.c = c || 0;
this.d = typeof d !== 'undefined' ? d : 1;
this.tx = tx || 0;
this.ty = ty || 0;
}
reset()
{
this.a = 1;
this.b = 0;
this.c = 0;
this.d = 1;
this.tx = 0;
this.ty = 0;
return this;
}
translate(vec2)
{
this.tx += vec2.x || 0;
this.ty += vec2.y || 0;
return this;
}
scale(vec2)
{
return this.multiply(new TransformationMatrix(
typeof vec2.x !== 'undefined' ? vec2.x : 1,
0,
0,
typeof vec2.y !== 'undefined' ? vec2.y : 1,
0,
0
));
}
rotate(angle)
{
let cos = Math.cos(angle),
sin = Math.sin(angle);
return this.multiply(new TransformationMatrix(cos, sin, -sin, -cos, 0, 0));
}
skew(vec2)
{
return this.multiply(new TransformationMatrix(
1,
Math.tan(vec2.y),
Math.tan(vec2.x),
1,
0,
0
));
}
invert()
{
let det = this.determinant;
if (det === 0)
throw new Error('The matrix is not inversible since it would require a division through zero');
return new TransformationMatrix(
this.d / det,
-this.b / det,
-this.c / det,
this.a / det,
(this.c * this.ty) - (this.d * this.tx) / det,
(-this.a * this.ty) + (this.b * this.tx) / det
);
}
multiply(other)
{
let {a, b, c, d, tx, ty} = this;
this.a = a * other.a + c * other.b;
this.b = b * other.a + d * other.b;
this.c = a * other.c + c * other.d;
this.d = b * other.c + d * other.d;
this.tx = a * other.tx + c * other.ty + tx;
this.ty = b * other.tx + d * other.ty + ty;
return this;
}
project(vec2)
{
vec2.set({
x: this.a * vec2.x + this.c * vec2.y + this.tx,
y: this.b * vec2.x + this.d * vec2.y + this.ty
});
return vec2;
}
toString()
{
return `matrix(${this.a}, ${this.b}, ${this.c}, ${this.d}, ${this.tx}, ${this.ty})`;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment