--- 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)); ```