Given an array of vectors representing each vertex of the polygon, we have to rotate the polygon by the midpoint by the given number of degrees (say n). Note the problem asks us not to draw a rotated polygon but to rotate a polygon. Meaning that built-in transformation objects are useless in this scenario. In a nutshell, we need to rotate the polygon itself and not the entire coordinate-system.
The fundamental idea is to rotate each vertex in the polygon by n-degrees. The following formula rotates a given point in the Cartesian plane:
We’ll solve the problem in iterations starting from the base-code:
- The base-code: We’ll use p5.js for this purpose to make it more interactive. Here’s our base index.html file
Code:
<!DOCTYPE html>
<
html
>
<
head
>
<
meta
charset
=
"UTF-8"
>
<
title
>Rotating a Polygon</
title
>
<
script
type
=
"text/javascript"
</
script
>
<
script
type
=
"text/javascript"
src
=
"sketch.js"
></
script
>
</
head
>
<
body
>
</
body
>
</
html
>
- Rotating the Polygon: Here’s the function which rotates the polygon. Note that we convert the angle to radians since the input will be in degrees. But in p5.js,
cos
andsin
expect values in radians by default. Also, note that lists in JavaScript are passed by reference so if we modify the passed argument then that have the effect on the original list as well.Code:
function
rotatePolygon(vertices,degree){
// Converting degree to radians!
degree = radians(degree);
for
(let i = 0; i < vertices.length; ++i){
// Storing the previous values so
// they don't get overwritten
let x = vertices[i].x, y = vertices[i].y;
vertices[i].x = x*cos(degree)-y*sin(degree);
vertices[i].y = x*sin(degree)+y*cos(degree);
}
}
- Calculating the midpoint: Now we can rotate the polygon right now but the problem asks us to rotate it with respect to its midpoint, so first we need to calculate that. To rotate a polygon by its midpoint we first need to calculate it’s the midpoint. The mid-point of a polygon is simply the average of all the co-ordinates. Here’s the function which calculates the mid-point.
Code:
function
calcMidpoint(vertices){
let midpoint = createVector(0, 0)
for
(let i = 0; i < vertices.length; i++)
midpoint.add(vertices[i]);
return
midpoint.div(vertices.length)
}
- Translating the mid-point: The process of rotating the polygon about its midpoint will involve some translation. Hopefully, this step is very intuitive and self-declarative.
Code:
function
translatePolygon(vertices, x, y) {
for
(let i = 0; i < vertices.length; i++) {
vertices[i].x += x;
vertices[i].y += y;
}
}
The final program combination of above iteration: Here is our final sketch.js file based on the above iterations:
-
Code:
var
starPolygon = []
function
setup() {
// Init the HTML5 Canvas of given size
createCanvas(800, 600);
/* Vertices for a star-polygon (decagon) */
let x = [440, 468, 534, 486, 498,
440, 382, 394, 346, 412];
let y = [230, 290, 300, 344, 410,
380, 410, 344, 300, 290];
/* Converting given vertices to
an array of vectors */
for
(let i = 0; i < x.length; ++i)
starPolygon.push(createVector(x[i], y[i]));
}
function
rotatePolygon(vertices, degree){
// Converting degree to radians!
degree = radians(degree);
for
(let i = 0; i < vertices.length; ++i) {
// Storing the previous values so they
// don't get overwritten
let x = vertices[i].x, y = vertices[i].y;
vertices[i].x = x*cos(degree)-y*sin(degree);
vertices[i].y = x*sin(degree)+y*cos(degree);
}
}
function
calcMidpoint(vertices) {
let midpoint = createVector(0, 0)
for
(let i = 0; i < vertices.length; i++)
midpoint.add(vertices[i]);
return
midpoint.div(vertices.length)
}
function
translatePolygon(vertices, x, y) {
for
(let i = 0; i < vertices.length; i++){
vertices[i].x += x;
vertices[i].y += y;
}
}
function
draw() {
// Clear everything with grey background
background(255);
rotatePolygon(starPolygon,1);
drawPolygon(starPolygon);
let a = calcMidpoint(starPolygon);
// Origin the polygon to center
// and draw it at (400, 300)
translatePolygon(starPolygon, 400-a.x, 300-a.y)
}
// This is how you draw a polygon in p5.js
function
drawPolygon(vertices) {
beginShape();
for
(let i = 0; i < vertices.length; ++i)
vertex(vertices[i].x, vertices[i].y);
fill(255, 217, 0);
// If you don't close it then it'd
// draw a chained line-segment
endShape(CLOSE);
}
- Output:
The simple principles discussed in this article can be applied to solve a variety of problems related to computer graphics. While we don’t talk about it yet one can easily scale the polygon in a similar way one translates the polygon (simply scale each vertex by the same factor). The midpoint-finding algorithm can be used for finding the midpoint of chained line-segments and not just polygon. Also, note that the same principles are applied for transforming the entire coordinate-system and p5.js itself provides built-in transformation objects but we didn’t use them since we were asked to rotate the polygon and not the coordinate system.