【问题标题】:javascript canvas draw multiple rectangles around a circle facing the centrejavascript canvas围绕一个面向中心的圆绘制多个矩形
【发布时间】:2020-04-25 07:00:12
【问题描述】:

我正在寻找一种方法以面向中心的角度围绕圆绘制多个矩形。到目前为止我所拥有的,目前只是围绕一个面向一个方向的圆绘制矩形,而没有向中心倾斜的角度 -

https://thysultan.com/projects/thyplayer/

我想要的是让矩形倾斜一个角度,使每个矩形在其指定位置面向圆心。 如何做到这一点?

【问题讨论】:

    标签: javascript math canvas trigonometry angle


    【解决方案1】:

    三角法

    要使线条向中心移动,您可以使用变换或三角数学。就个人而言,我发现在这种情况下使用数学更容易,所以这里有一个例子。

    有关如何使用转换的示例,请参阅 @markE 的回答(转换在视觉上和在代码中通常更容易)。

    一些先决条件:

    • 我们知道画布的方向是 0° 角指向右侧。如果您想以某种方式标记频率范围,这是必不可少的。
    • 我们需要计算从外半径到中心(内半径)的直线长度
    • 我们需要根据角度计算直线的端点。

    一个简单的解决方案是创建一个函数,计算中心(cx, cy) 在某个angle(以弧度为单位)处的一条线,t 为长度,t 在 [0, 1 范围内](作为 FFT 浮点缓冲区箱)。我们还提供了外半径和内半径来限制直线:

    function getLine(cx, cy, angle, t, oRadius, iRadius) {
    
        var radiusDiff = oRadius - iRadius,            // calc radius diff to get max length
            length = radiusDiff * t;                   // now we have the line length
    
        return {
            x1: oRadius * Math.cos(angle),             // x1 point (outer)
            y1: oRadius * Math.sin(angle),             // y1 point (outer)
            x2: (oRadius - length) * Math.cos(angle),  // x2 point (inner)
            y2: (oRadius - length) * Math.sin(angle)   // y2 point (inner)
        }
    }
    

    我们现在需要做的就是从 FFT 分析器向其提供数据。

    注意:由于所有线都指向中心,因此您将拥有一个拥挤的中心区域。在确定线宽和内半径以及要使用的 bin 数量时要牢记一些事情。

    示例演示

    对于示例,我将只为“FFT”使用一些随机数据并绘制 64 个 bin。

    // angle - in radians
    function getLine(cx, cy, angle, t, oRadius, iRadius) {
    
      var radiusDiff = oRadius - iRadius,            // calc radius diff to get max length
          length = radiusDiff * t;                   // now we have the line length
    
      return {
        x1: cx + oRadius * Math.cos(angle),             // x1 point (outer)
        y1: cy + oRadius * Math.sin(angle),             // y1 point (outer)
        x2: cx + (oRadius - length) * Math.cos(angle),  // x2 point (inner)
        y2: cy + (oRadius - length) * Math.sin(angle)   // y2 point (inner)
      }
    }
    
    // calculate number of steps based on bins
    var ctx = document.querySelector("canvas").getContext("2d"),
        fftLength = 64,
        angleStep = Math.PI * 2 / fftLength,
        angle = 0,
        line;
    
    ctx.beginPath();                                    // not needed in demo, but when animated
    
    while(angle < Math.PI*2) {
      // our line function in action:
      line = getLine(250, 250, angle, getFFT(), 240, 50);
      
      ctx.moveTo(line.x1, line.y1);                    // add line to path
      ctx.lineTo(line.x2, line.y2);
      angle += angleStep                               // get next angle
    }
    
    ctx.lineWidth = 5;                                 // beware of center area
    ctx.stroke();                                      // stroke all lines at once
    
    // to smooth the "FFT" random data
    function getFFT() {return Math.random() * 0.16 + 0.4}
    &lt;canvas width=500 height=500&gt;&lt;/canvas&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2013-11-10
      • 1970-01-01
      • 2014-01-23
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多