Created
August 23, 2019 22:07
-
-
Save TorbenKoehn/dd04a08fc40235ad3f30fe12e4c17eb7 to your computer and use it in GitHub Desktop.
2D-affine matrices
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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