当我想绘制通过三个点的线条,并在第二个点处做一个圆角时。然后问题发生,如果两条线之间的角度小于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(); }
答案 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
产生错误的影响。要解决此问题,请在计算k1
和k2
之后添加以下代码:
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; "; />