---
title: Вращаем квадрат на плоскости
description: Напишем алгоритм на JavaScript для поворота квадрата на угол вокруг своего центра, повторим программу средней школы. Для расчётов будем использовать класс...
sections: [Линейная алгебра,Матрица поворота]
tags: [javascript,онлайн,canvas,геометрия,графика,изображение,картинка,квадрат]
scripts: [/js/spinning-square.js,/js/spinning-square2.js]
canonical_url: /ru/2023/01/05/spinning-square-on-plane.html
url_translated: /en/2023/01/06/spinning-square-on-plane.html
title_translated: Spinning square on plane
date: 2023.01.05
---
Напишем алгоритм на JavaScript для поворота квадрата на угол вокруг своего центра, повторим программу
средней школы. Для расчётов будем использовать класс `Math`, а для отображения результатов — Canvas.
Развитие мысли, объёмная модель: [Вращаем куб в пространстве]({{ '/ru/2023/01/10/spinning-cube-in-space.html' | relative_url }}).
{% include heading.html text="Поворот точки на плоскости" hash="point-rotation-on-plane" type="3" %}
Рассчитываем координаты новой точки по формулам матрицы поворота для двухмерного пространства.
Поворачиваем точку `t` относительно точки `t0` — получаем точку `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="Описание алгоритма" hash="algorithm-description" type="3" %}
Начало координат находится в верхнем левом углу, координатные оси направлены вправо и вниз. Центральная точка
для поворотов `t0` расположена в центре фигуры. Квадрат — это массив из четырёх точек-вершин. Обходим массив
точек, поворачиваем каждую из них на угол, затем соединяем точки линиями и рисуем линии на холсте. Обновляем
картинку с частотой 20 кадров в секунду.
{% include heading.html text="Реализация" hash="implementation" type="3" %}
{% include heading.html text="HTML" hash="html1" type="3" %}
```html
```
{% include heading.html text="JavaScript" hash="javascript1" type="3" %}
```js
'use strict';
let canvas = document.getElementById('canvas');
// исходный массив точек-вершин квадрата
let square = [{x:50,y:50},{x:50,y:250},{x:250,y:250},{x:250,y:50}];
// центр фигуры, вокруг него будем выполнять поворот
let t0 = {x:150, y:150};
// угол поворота в градусах
let deg = 1;
```
```js
// поворот фигуры и обновление изображения
function repaint() {
// поворачиваем исходный массив точек на угол
for (let i = 0; i < square.length; i++)
square[i] = rotateOnDegree(t0, square[i], deg);
// рисуем текущий массив точек
drawFigure(canvas, square);
}
```
```js
// поворачиваем точку (t) на угол (deg) относительно точки (t0)
function rotateOnDegree(t0, t, deg) {
let t_new = {};
// переводим угол поворота из градусов в радианы
let rad = (Math.PI / 180) * deg;
// рассчитываем координаты новой точки по формуле
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 t_new;
}
```
```js
// рисуем фигуру по точкам из массива
function drawFigure(canvas, arr) {
let context = canvas.getContext('2d');
// очищаем весь холст целиком
context.clearRect(0, 0, canvas.width, canvas.height);
// обходим массив точек и соединяем их линиями
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();
// рисуем линии на холсте
context.lineWidth = 2.2;
context.strokeStyle = '#222';
context.stroke();
}
```
```js
// после загрузки страницы, задаём частоту обновления изображения 20 Гц
document.addEventListener('DOMContentLoaded',()=>setInterval(repaint,50));
```
{% include heading.html text="Вращение в обратную сторону" hash="spinning-backwards" %}
Добавим ещё одну точку, которую будем вращать в обратную сторону. Точка удалена от центра фигуры на
четверть длины стороны квадрата. Сместим центр квадрата в эту точку — сдвинем массив его вершин. Сам
квадрат будем вращать по часовой стрелке, а его центральную точку — против часовой стрелки. Этот код
работает вместе с предыдущим.
{% include heading.html text="HTML" hash="html2" type="3" %}
```html
```
{% include heading.html text="JavaScript" hash="javascript2" type="3" %}
```js
'use strict';
let canvas2 = document.getElementById('canvas2');
// текущий массив точек
let square2 = [];
// вращающаяся точка
let t2 = {x:100, y:100};
```
```js
// поворот фигуры и обновление изображения
function repaint2() {
// поворачиваем точку в обратную сторону
t2 = rotateOnDegree(t0, t2, -deg);
// обходим точки исходного массива и сдвигаем
for (let i = 0; i < square.length; i++) {
// текущая точка
square2[i] = {};
// сдвигаем точку исходного массива
square2[i].x = square[i].x - t0.x + t2.x;
square2[i].y = square[i].y - t0.y + t2.y;
}
// рисуем текущий массив точек
drawFigure(canvas2, square2);
}
```
```js
// после загрузки страницы, задаём частоту обновления изображения 20 Гц
document.addEventListener('DOMContentLoaded',()=>setInterval(repaint2,50));
```