Rotate a polygon by given degrees in p5.js

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 (x,y) in the Cartesian plane:

     {x}' = x cos(\theta ) - y sin(\theta )
     {y}' = x sin(\theta ) + y cos(\theta )

We’ll solve the problem in iterations starting from the base-code:

  1. The base-code: We’ll use p5.js for this purpose to make it more interactive. Here’s our base index.html file

    Code:



    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    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>

    chevron_right

    
    

  2. 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 and sin 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:

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    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);
      }
    }

    chevron_right

    
    

  3. 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:

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    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)
    }

    chevron_right

    
    

  4. 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:

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    code

    function translatePolygon(vertices, x, y) {
        for (let i = 0; i < vertices.length; i++) {
          vertices[i].x += x;
          vertices[i].y += y;
        }
    }

    chevron_right

    
    

The final program combination of above iteration: Here is our final sketch.js file based on the above iterations:

  • Code:

    filter_none

    edit
    close

    play_arrow

    link
    brightness_4
    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);
    }

    chevron_right

    
    

  • 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.




My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.