【问题标题】:Rotate triangles around center point without overlap围绕中心点旋转三角形而不重叠
【发布时间】:2017-02-15 22:43:49
【问题描述】:

我有一个 400x300 的 HTML 画布,我正在尝试使用一个圆圈和 7 个三角形来绘制一个太阳。为了绘制三角形,我按照this SO Answer 的说明进行平移、旋转和平移。但是,有些三角形重叠在一起,就好像它们的角度相同。

http://codepen.io/ralrom/pen/bgZYRO

我不知道出了什么问题,我检查了计算出的弧度,它们都在 0 到 2*PI 之间。

var drawSun = function () {

    // Circle
    context.beginPath();
    context.arc(75, 75, 30, 0, Math.PI * 2, true);
    context.closePath();
    context.fill();

    context.save();

    // Triangles
    for (var i = 0; i < 7; i++) {

        // Rotate the canvas around a point
        angle = i * 360 / 7;
        console.log(angle, angle * Math.PI / 180);
        context.translate(75, 75);
        context.rotate(angle * Math.PI / 180);
        context.translate(-75, -75);

        // Draw the triangle
        context.beginPath();
        context.fillStyle = 'rgba(0,0,0,0.5)';
        context.moveTo(60, 35);
        context.lineTo(75, 15);
        context.lineTo(90, 35);
        context.closePath();
        context.fill();

        context.restore();
    }
}

【问题讨论】:

    标签: html5-canvas geometry


    【解决方案1】:

    有时这里的答案有很多要点,但实际上并不是那么好。使用 ctx.setTransform 可以更轻松地处理转换,因为它完全取代了现有的转换。因此,无需保存状态即可知道您的位置。

    当渲染对象时,它也有助于始终围绕它们自己的旋转中心布置它们的坐标。你把那个中心移到你需要的地方。

    无论如何,以下是您可以做到的。该函数将处理不同的点数,并且更有条理,没有不必要的关闭路径,保存恢复和从 Deg 到弧度的转换。

    var ctx = canvas.getContext('2d');
    
    var drawSun = function(x,y,rad,count) {
      var drawRay = function(ang){
        // Half width, note I get width from 2PI*r but as I need half I drop the 2
        var width = (Math.PI * (rad + 5)) / count;
        ctx.setTransform(1,0,0,1,x,y);
        ctx.rotate(ang);  
        ctx.beginPath();
        ctx.moveTo(-width, rad + 5);
        ctx.lineTo(0, rad + 20);
        ctx.lineTo(width, rad + 5);
        ctx.fill();
      }
      ctx.fillStyle = "#F90";
      ctx.setTransform(1,0,0,1,x,y); // move sun center to where it should be.
      ctx.beginPath();
      ctx.arc(0, 0, rad, 0, Math.PI * 2, true); // draw sun at 0,0
      ctx.fill();
    
      for (var i = 0; i < count; i++) {
        drawRay((i / count) * Math.PI * 2);
        // if you want to draw with first ray top center 
        // you need to offset by half a step
        //drawRay(((i / count)-(count/2)) * Math.PI * 2);
      }
      // done and if you want you can reset to the default transform with
      // ctx.setTransform(1,0,0,1,0,0);
    }
    drawSun(100,100,30,7);
    &lt;canvas id="canvas" width=200 height=200&gt;&lt;/canvas&gt;

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-07-30
      • 1970-01-01
      • 2013-12-17
      • 2012-04-08
      • 2023-01-08
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多