CSS TRANSFORM MATRIX AND SAT APPLICATION
HTML
<!-- <div class="test-area">
<div class="item"></div>
<div class="itemb"></div>
</div>
-->
<div class="test-area">
<canvas id="canvas" width="300px" height="250px" />
</div>
SCSS
body {
background: #f2f3f5;
}
.test-area {
position: relative;
width: 300px;
height: 250px;
background: black;
margin: 10px 0 0 0;
> .item {
position: absolute;
width: 50px;
height: 50px;
background: white;
top: 20px;
left: 20px;
transform-origin: 50% 50%;
transform: rotate(20deg);
}
> .itemb {
position: absolute;
width: 50px;
height: 50px;
background: red;
top: 100px;
left: 20px;
transform-origin: 50% 50%;
transform:
translate(10px, 10px)
scale(1.5, 1.5)
rotate(20rad);
}
> canvas {
}
}
JavaScript
class Matrix {
constructor(matrix = []) {
this._matrix = matrix
}
get matrix() {
return this._matrix
}
static transpose(target) {
return target.matrix[0].map((col, i) => target.matrix.map(row => row[i]))
}
static dot(matrixA, matrixB) {
let result = new Array(matrixA.length).fill(0).map(row => new Array(matrixB[0].length).fill(0))
let matrix = result.map((row, i) => {
return row.map((val, j) => {
return matrixA[i].reduce((sum, elm, k) => sum + (elm * matrixB[k][j]), 0)
})
})
return new Matrix(matrix)
}
}
class TransformMatrix {
// IN PIXELS
static translate(x = 0, y = 0) {
return new Matrix([
[1, 0, x],
[0, 1, y],
[0, 0, 1]
])
}
// IN INTEGER
static scale(x = 1, y = 1) {
return new Matrix([
[x, 0, 0],
[0, y, 0],
[0, 0, 1]
])
}
// IN RADIANS
static skew(x = 0, y = 0) {
return new Matrix([
[1, Math.tan(x), 0],
[Math.tan(y), 1, 0],
[0, 0, 1]
])
}
// IN RADIANS
static rotate(angle) {
let a = Math.cos(angle) || 1
let b = Math.sin(angle) || 0
let c = -Math.sin(angle) || 0
let d = Math.cos(angle) || 1
return new Matrix([
[a, c, 0],
[b, d, 0],
[0, 0, 1]
])
}
static transform(...matrixes) {
let clean = new Matrix([
[1, 0, 0],
[0, 1, 0],
[0, 0, 1]
])
return matrixes.reduce((old, current, index) => Matrix.dot(old.matrix, current.matrix), clean)
}
}
class Point {
constructor(x = 0, y = 0) {
this.x = x
this.y = y
}
mult(scalar) {
this.x *= scalar;
this.y *= scalar;
return this;
}
div(scalar) {
this.x /= scalar;
this.y /= scalar;
return this;
}
dot(vector) {
return this.x * vector.x + this.y * vector.y
}
mag() {
return Math.sqrt((this.x * this.x) + (this.y * this.y));
}
normalize() {
const mag = this.mag()
if (mag > 0)
return this.div(mag)
else
...