Calculate coordinates of a point with transformation matrix
HTML
<p>
The blue polygon has the same points as the green one + transformation
<br>
Coordinates of the red circles are calculated with transformation matriсes
</p>
<svg height="1000" width="1000" xmlns="http://www.w3.org/2000/svg" viewBox="0 0 1000 1000"></svg>
CSS
circle {
fill: red;
r: 4px;
}
polygon {
fill: #d6ffd6;
stroke: green;
stroke-width: 1px;
}
polygon[transform] {
fill: #d6e1ff;
stroke: blue;
}
JavaScript
const assert = (c, o) => {if (!c) throw Error('Assert failed', o)};
const multiplyMatrices = (a, b) => {
const l = b.length; assert(a[0].length == l);
const m = a.length, c = new Array(m), n = b[0].length;
for (let i = m; --i >=0;) {
const u = a[i], v = c[i] = new Array(n);
for (let j = n; --j >= 0;) {
let s = 0;
for (let k = l; --k >= 0;) s += u[k] * b[k][j];
v[j] = s;
}
}
return c;
}
let polygonPoints = [{x: 100, y: 50}, {x: 175, y: 100}, {x: 50, y: 200}, {x: 25, y: 75}];
let translate = {x: 200, y: 50}, translateMatrix = [
[1, 0, translate.x],
[0, 1, translate.y],
[0, 0, 1],
];
let scale = {x: 1.5, y: 1.5}, scaleMatrix = [
[scale.x, 0, 0],
[0, scale.y, 0],
[0, 0, 1],
];
let angleInDegrees = 25, angleInRadians = angleInDegrees * (Math.PI / 180),
rotateMatrix = [
[Math.cos(angleInRadians), -Math.sin(angleInRadians), 0],
[Math.sin(angleInRadians), Math.cos(angleInRadians), 0],
[0, 0, 1],
];
let transformMatrix = multiplyMatrices(
multiplyMatrices(translateMatrix, scaleMatrix),
rotateMatrix);
let svgElem = document.querySelector('svg');
let polygonElem = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
let transformedPolygonElem = document.createElementNS('http://www.w3.org/2000/svg', 'polygon');
let pointsAttribute = polygonPoints.reduce((previousValue, point) => {
return previousValue + ` ${point.x},${point.y}`;
}, '');
polygonElem.setAttribute('points', pointsAttribute);
transformedPolygonElem.setAttribute('points', pointsAttribute);
transformedPolygonElem.setAttribute('transform', `translate(${translate.x},${translate.y})scale(${scale.x},${scale.y})rotate(${angleInDegrees})`);
svgElem.appendChild(polygonElem);
svgElem.appendChild(transformedPolygonElem);
polygonPoints.forEach((point) => {
let pointMatrix = multiplyMatrices(transformMatrix, [[point.x], [point.y], [1]]);
let newCoordinates = {x: pointMatrix[0], y: pointMatrix[1]};
let circleElem =...