html5 canvas arcTo上的意外结果

时间:2012-04-07 04:31:50

标签: html5 canvas

当我想绘制通过三个点的线条,并在第二个点处做一个圆角时。然后问题发生,如果两条线之间的角度小于90度,则通过point1和point2在线上会有一些额外的线附加。如果角度大或等于90度,那就没问题了。

你可以在小提琴中看到这个:http://jsfiddle.net/qiu8310/8cFZG/2/

这是javascript代码和结果:


    
    "use strict";
        function Point(x, y){
        this.x = x ? x : 0;
        this.y = y ? y : 0;
        }
    var ctx,
        canvas = document.getElementById('canvas');
    canvas.width = 600;
    canvas.height = 600;

    ctx = canvas.getContext('2d');
    ctx.lineWidth = 2;

    draw(ctx, new Point(50,10), new Point(20, 300), new Point(100, 320) );
    draw(ctx, new Point(200,10), new Point(200, 300), new Point(300, 20) );

    function draw(ctx, p1, p2, p3){
    var k1,k2, k, len, r=8;
    k1 = Math.atan2(p2.y - p1.y, p2.x - p1.x);
    k2 = Math.atan2(p3.y - p2.y, p3.x - p2.x);
    k = (k1-k2)/2;
    len = Math.abs(r/Math.tan(k));  // the distance between point of tangency and p2
    ctx.moveTo(p1.x, p1.y);
    ctx.lineTo(p2.x - len*Math.cos(k1), p2.y - len*Math.sin(k1) ); // lineTo the point of tangency
    ctx.arcTo(p2.x, p2.y, p2.x + len*Math.cos(k2), p2.y + len*Math.sin(k2), r ); // then arc
    ctx.lineTo(p3.x, p3.y); // till p3
    ctx.stroke();
    }

    

2 个答案:

答案 0 :(得分:0)

我无法找到您的错误,因此请再次查看http://jsfiddle.net/yUkK3/6/

似乎工作正常,除非P1和P3的顺序错误。 (关于小提琴的最后一个例子)可以看出它为什么会发生但尚未进行修正。

何时出错的说明。

以P2为原点,旋转P1,使P1到P2沿x轴,P1为正,然后当P3.y为负时,绘制失败。

希望这有帮助

编辑现在已经解决了上述订单问题。 http://jsfiddle.net/yUkK3/7/

答案 1 :(得分:0)

Math.atan2将在角度大于90度时返回负角,这将对角度k产生错误的影响。要解决此问题,请在计算k1k2之后添加以下代码:

kk1 = k1<0 ? k1+Math.PI : k1;
kk2 = k2<0 ? k2+Math.PI : k2;
k = (kk1-kk2)/2;

这是完整的工作代码:

function Point(x, y){
  this.x = x ? x : 0;
  this.y = y ? y : 0;
}

var ctx,
    canvas = document.getElementById('canvas');
canvas.width = 600;
canvas.height = 600;

ctx = canvas.getContext('2d');
ctx.lineWidth = 2;

draw(ctx, new Point(50,10), new Point(20, 300), new Point(100, 320) );
draw(ctx, new Point(200,10), new Point(200, 300), new Point(300, 20) );

function draw(ctx, p1, p2, p3){
  var k1,k2, k, len, r=8, kk1,kk2;

  k1 = Math.atan2(p2.y - p1.y, p2.x - p1.x);
  k2 = Math.atan2(p3.y - p2.y, p3.x - p2.x);
  kk1 = k1<0 ? k1+Math.PI : k1;
  kk2 = k2<0 ? k2+Math.PI : k2;
  k = (kk1-kk2)/2;
  len = Math.abs(r/Math.tan(k));  // the distance between point of tangency and p2

  ctx.moveTo(p1.x, p1.y);
  ctx.lineTo(p2.x - len*Math.cos(k1), p2.y - len*Math.sin(k1) ); // lineTo the point of tangency
  ctx.arcTo(p2.x, p2.y, p2.x + len*Math.cos(k2), p2.y + len*Math.sin(k2), r ); // then arc
  ctx.lineTo(p3.x, p3.y); // till p3
  ctx.stroke();
}
<canvas id='canvas' style="width:600px; height:600px; margin: 0 auto; background-color: yellow; "; />