围绕中心点旋转三角形,不重叠

时间:2017-02-15 13:26:33

标签: html5-canvas geometry

我有一个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();
    }
}

1 个答案:

答案 0 :(得分:2)

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

当渲染对象时,它总是有助于围绕自己的旋转中心布置坐标。您将该中心移动到您需要的位置。

无论如何,下面是你如何做到这一点。该函数将处理不同的点数,并且在没有不必要的关闭路径的情况下更加有条理,保存从Deg到弧度的恢复和转换。

&#13;
&#13;
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);
&#13;
<canvas id="canvas" width=200 height=200></canvas>
&#13;
&#13;
&#13;