📜  在 p5.js 中将多边形旋转给定度数

📅  最后修改于: 2022-05-13 01:56:38.222000             🧑  作者: Mango

在 p5.js 中将多边形旋转给定度数

给定一个表示多边形每个顶点的向量数组,我们必须将多边形旋转中点给定的度数(例如 n)。请注意,问题要求我们不要绘制旋转的多边形,而是旋转多边形。这意味着内置的转换对象在这种情况下是无用的。简而言之,我们需要旋转多边形本身,而不是整个坐标系。

基本思想是将多边形中的每个顶点旋转 n 度。以下公式旋转给定点(x,y)在笛卡尔平面上:

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

我们将从基本代码开始在迭代中解决问题:

  1. 基本代码:我们将为此使用 p5.js 以使其更具交互性。这是我们的基本index.html文件

    代码:

    
    
      
        
        Rotating a Polygon
        
        
      
      
      
    
    
  2. 旋转多边形:这是旋转多边形的函数。请注意,我们将角度转换为弧度,因为输入将以度为单位。但在 p5.js 中, cossin默认情况下需要以弧度表示的值。另外,请注意 JavaScript 中的列表是通过引用传递的,因此如果我们修改传递的参数,那么也会对原始列表产生影响。

    代码:

    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);
      }
    }
    
  3. 计算中点:现在我们可以旋转多边形,但问题要求我们相对于它的中点旋转它,所以首先我们需要计算它。要通过中点旋转多边形,我们首先需要计算它的中点。多边形的中点只是所有坐标的平均值。这是计算中点的函数。

    代码:

    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)
    }
    
  4. 平移中点:围绕中点旋转多边形的过程将涉及一些平移。希望这一步非常直观和自我声明。

    代码:

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

上述迭代的最终程序组合:这是我们基于上述迭代的最终sketch.js文件:

  • 代码:
    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);
    }
    
  • 输出:

本文讨论的简单原理可用于解决与计算机图形相关的各种问题。虽然我们不谈论它,但我们可以很容易地以类似的方式缩放多边形,一种平移多边形(只需按相同的因子缩放每个顶点)。中点查找算法可用于查找链式线段的中点,而不仅仅是多边形。另外,请注意,相同的原则适用于转换整个坐标系,p5.js 本身提供了内置的转换对象,但我们没有使用它们,因为我们被要求旋转多边形而不是坐标系。