Linear algebra • Rotation matrix
06.01.2023

Let’s write an algorithm in JavaScript to rotate a square by an angle around its center, repeat the high
school program. We will use the `Math`

class for calculations, and Canvas for displaying the results.

Development of thought, volumetric model: Spinning cube in space.

We calculate the coordinates of the new point using the formulas of the rotation matrix for
two-dimensional space. We rotate the point `t`

relative to the point `t0`

— we get the point `t'`

.

The origin of the coordinates is in the upper left corner, the coordinate axes are directed to the right and
down. The central point for rotations `t0`

is located in the center of the figure. A square is an array of
four points-vertices. We bypass the array of points, rotate each of them by an angle, then link the points
with lines and draw lines on the canvas. We renew the image at a frequency of 20 frames per second.

```
<canvas id="canvas" width="300" height="300" style="border: 1px solid gray;">
<p>Canvas for displaying computations results</p>
</canvas>
```

```
'use strict';
let canvas = document.getElementById('canvas');
// original array of points-vertices of square
let square = [{x:50,y:50},{x:50,y:250},{x:250,y:250},{x:250,y:50}];
// figure center, we'll perform a rotation around it
let t0 = {x:150, y:150};
// rotation angle in degrees
let deg = 1;
```

```
// figure rotation and image refresh
function repaint() {
// rotate the original array of points by an angle
for (let i = 0; i < square.length; i++)
square[i] = rotateOnDegree(t0, square[i], deg);
// draw the current array of points
drawFigure(canvas, square);
}
```

```
// rotate the point (t) by an angle (deg) relative to the point (t0)
function rotateOnDegree(t0, t, deg) {
let t_new = {};
// convert angle of rotation from degrees to radians
let rad = (Math.PI / 180) * deg;
// calculate the coordinates of the new point using the formula
t_new.x = t0.x+(t.x-t0.x)*Math.cos(rad)-(t.y-t0.y)*Math.sin(rad);
t_new.y = t0.y+(t.x-t0.x)*Math.sin(rad)+(t.y-t0.y)*Math.cos(rad);
// return new point
return t_new;
}
```

```
// draw a figure by points from an array
function drawFigure(canvas, arr) {
let context = canvas.getContext('2d');
// clear the entire canvas
context.clearRect(0, 0, canvas.width, canvas.height);
// bypass the array of points and link them with lines
context.beginPath();
for (let i = 0; i < arr.length; i++)
if (i == 0)
context.moveTo(arr[i].x, arr[i].y);
else
context.lineTo(arr[i].x, arr[i].y);
context.closePath();
// draw lines on the canvas
context.lineWidth = 2.2;
context.strokeStyle = '#222';
context.stroke();
}
```

```
// after loading the page, set the image refresh rate at 20 Hz
document.addEventListener('DOMContentLoaded',()=>setInterval(repaint,50));
```

Let’s add one more point, which we’ll rotate backwards. The point is distant from the center of the figure by a quarter of the length of the side of the square. let’s shift the center of the square to this point — shift the array of its vertices. We will rotate the square itself clockwise, and its central point — counterclockwise. This code works in conjunction with the previous one.

```
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
<p>Canvas for displaying computations results</p>
</canvas>
```

```
'use strict';
let canvas2 = document.getElementById('canvas2');
// current array of points
let square2 = [];
// spinning point
let t2 = {x:100, y:100};
```

```
// figure rotation and image refresh
function repaint2() {
// rotate the point in the opposite direction
t2 = rotateOnDegree(t0, t2, -deg);
// bypass the points of the original array and shift
for (let i = 0; i < square.length; i++) {
// current point
square2[i] = {};
// shifting the point of the original array
square2[i].x = square[i].x - t0.x + t2.x;
square2[i].y = square[i].y - t0.y + t2.y;
}
// draw the current array of points
drawFigure(canvas2, square2);
}
```

```
// after loading the page, set the image refresh rate at 20 Hz
document.addEventListener('DOMContentLoaded',()=>setInterval(repaint2,50));
```

© Golovin G.G., Code with comments, translation from Russian, 2023