5.9 KiB
title | description | sections | tags | scripts | canonical_url | url_translated | title_translated | date | lang | ||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Spinning square on plane | 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... |
|
|
|
/en/2023/01/06/spinning-square-on-plane.html | /ru/2023/01/05/spinning-square-on-plane.html | Вращаем квадрат на плоскости | 2023.01.06 | en |
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]({{ '/en/2023/01/11/spinning-cube-in-space.html' | relative_url }}).
{% include heading.html text="Point rotation on plane" hash="point-rotation-on-plane" type="3" %}
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'
.
{% include image_svg.html src="/img/column-vector2d.svg" style="width: 246.793pt; height: 37.2836pt;" alt="&x'=x_0+(x-x_0)cos\varphi-(y-y_0)sin\varphi,&\&y'=y_0+(x-x_0)sin\varphi+(y-y_0)cos\varphi.&\" %}
{% include heading.html text="Algorithm description" hash="algorithm-description" type="3" %}
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.
{% include heading.html text="Implementation" hash="implementation" type="3" %}
Canvas for displaying computations results
{% include heading.html text="HTML" hash="html1" type="3" %}
<canvas id="canvas" width="300" height="300" style="border: 1px solid gray;">
<p>Canvas for displaying computations results</p>
</canvas>
{% include heading.html text="JavaScript" hash="javascript1" type="3" %}
'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));
{% include heading.html text="Spinning backwards" hash="spinning-backwards" %}
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 for displaying computations results
{% include heading.html text="HTML" hash="html2" type="3" %}
<canvas id="canvas2" width="300" height="300" style="border: 1px solid gray;">
<p>Canvas for displaying computations results</p>
</canvas>
{% include heading.html text="JavaScript" hash="javascript2" type="3" %}
'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));