--- title: Spinning square on plane description: 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... sections: [Linear algebra,Rotation matrix] tags: [javascript,canvas,geometry,graphics,image,picture,square] scripts: [/js/spinning-square.js,/js/spinning-square2.js] canonical_url: /en/2023/01/06/spinning-square-on-plane.html url_translated: /ru/2023/01/05/spinning-square-on-plane.html title_translated: Вращаем квадрат на плоскости date: 2023.01.06 lang: 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 }}). ### Point rotation on plane {#point-rotation-on-plane} 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.&\\" %} ### Algorithm description {#algorithm-description} 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. ### Implementation {#implementation}

Your browser does not support Canvas

### HTML {#html1} ```html

Your browser does not support Canvas

``` ### JavaScript {#javascript1} ```js '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; ``` ```js // figure rotation and image update 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); } ``` ```js // 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; } ``` ```js // 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(); } ``` ```js // after loading the page, set the image refresh interval document.addEventListener('DOMContentLoaded',()=>setInterval(repaint,50)); ``` ## Spinning backwards {#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.

Your browser does not support Canvas

### HTML {#html2} ```html

Your browser does not support Canvas

``` ### JavaScript {#javascript2} ```js 'use strict'; let canvas2 = document.getElementById('canvas2'); // current array of points let square2 = []; // spinning point let t2 = {x:100, y:100}; ``` ```js // figure rotation and image update 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); } ``` ```js // after loading the page, set the image refresh interval document.addEventListener('DOMContentLoaded',()=>setInterval(repaint2,50)); ```