Javascript HTML5画布:带角度的逆时针圆弧>;2π

Javascript HTML5画布:带角度的逆时针圆弧>;2π,javascript,html,canvas,Javascript,Html,Canvas,我试图找出为什么角度>2π在顺时针和逆时针绘制圆弧时不会给出相同的结果 看看这个代码片段,在第一行,我画了“顺时针”3个红色圆弧,起始角为0,结束角为π,2*PI和3*PI。 然后我用相同的参数“逆时针”画3条蓝色弧 第三个结果让我困惑。。。谁能给我解释一下吗 var c=document.getElementById(“myCanvas”); var ctx=c.getContext(“2d”); //顺时针,角度=π ctx.beginPath(); ctx.arc(50,50,40,0,

我试图找出为什么角度>2π在顺时针和逆时针绘制圆弧时不会给出相同的结果

看看这个代码片段,在第一行,我画了“顺时针”3个红色圆弧,起始角为0,结束角为π,2*PI和3*PI。 然后我用相同的参数“逆时针”画3条蓝色弧

第三个结果让我困惑。。。谁能给我解释一下吗

var c=document.getElementById(“myCanvas”);
var ctx=c.getContext(“2d”);
//顺时针,角度=π
ctx.beginPath();
ctx.arc(50,50,40,0,Math.PI,false);
ctx.closePath();
ctx.stroke();
ctx.fillStyle=“红色”;
ctx.fill();
//顺时针,角度=2π
ctx.beginPath();
ctx.arc(150,50,40,0,2*Math.PI,false);
ctx.closePath();
ctx.stroke();
ctx.fillStyle=“红色”;
ctx.fill();
//顺时针,角度=3π
ctx.beginPath();
ctx.arc(250,50,40,0,3*Math.PI,false);
ctx.closePath();
ctx.stroke();
ctx.fillStyle=“红色”;
ctx.fill();
//逆时针方向,角度=π
ctx.beginPath();
ctx.arc(50,150,40,0,Math.PI,true);
ctx.closePath();
ctx.stroke();
ctx.fillStyle=“蓝色”;
ctx.fill();
//逆时针方向,角度=2π
ctx.beginPath();
ctx.arc(150150,40,0,2*Math.PI,真);
ctx.closePath();
ctx.stroke();
ctx.fillStyle=“蓝色”;
ctx.fill();
//逆时针方向,角度=3π
ctx.beginPath();
ctx.arc(250、150、40、0、3*Math.PI,真);
ctx.closePath();
ctx.stroke();
ctx.fillStyle=“蓝色”;
ctx.fill()

逆时针旋转时,0之后是2PI。您应该尝试以下方法:

//逆时针方向,角度=3π
ctx.beginPath();
ctx.arc(250、150、40、2*Math.PI,0,真);
ctx.closePath();
ctx.stroke();
ctx.fillStyle=“蓝色”;
ctx.fill();
更新: 在OP的评论之后,我添加了一个动画演示:

var c=document.getElementById(“myCanvas”);
var ctx=c.getContext(“2d”);
设δ=0;
函数绘图(){
requestAnimationFrame(绘制)
delta+=0.01;
ctx.clearRect(0,0,c.宽度,c.高度)
//顺时针:设置端点动画
ctx.beginPath();
弧(50,50,40,0,δ,假);
ctx.closePath();
ctx.stroke();
//按顺时针方向,设置起点动画
ctx.beginPath();
弧(150,50,40,0,-δ,真);
ctx.closePath();
ctx.stroke();
}
Draw()
根据:

如果逆时针方向为假,且startAngle的端角等于或大于2π,或者,如果逆时针方向为真,且startAngle的端角等于或大于2π,则弧是该椭圆的整个圆周,以及该圆圆周上startAngle处的点,从椭圆的半长轴顺时针测量弧度,作为起点和终点

否则,沿该圆圆周的startAngle和endAngle处的点(从椭圆的半长轴以弧度顺时针测量)分别为起点和终点,圆弧为沿该椭圆圆周从起点到终点的路径,如果逆时针为真,则为逆时针方向,反之则为顺时针方向。由于这些点位于椭圆上,而不是简单地与零成角度,因此圆弧永远不能覆盖大于2π弧度的角度

输入可能更清晰的伪代码:

if(
  (anticlockwise === false && (endAngle - startAngle) >= 2π) ||
  (anticlockwise === true  && (startAngle - endAngle) >= 2π)
  ) {
  arc_circumference = 2π;
}
else {
  startAngle = startAngle % 2π;
  endAngle = endAngle % 2π;
}
在你的例子中,startAngle=0,endAngle=3π,anticlowkwise=true,如果我们运行上面的算法,我们会在else的情况下结束(0-3π<2π),endAngle现在是(3π%2π=1π)

通过交换startAngle和endAngle,我们可以在没有逆时针标志的情况下实现相同的输出:

var ctx=canvas.getContext(“2d”);
//逆时针方向,角度=-3π(从OP开始)
ctx.beginPath();
ctx.arc(50,150,40,0,3*Math.PI,真);
ctx.stroke();
ctx.fillStyle=“蓝色”;
ctx.fill();
//顺时针,角度=-3π
ctx.beginPath();
ctx.arc(50,50,40,3*Math.PI,0);
ctx.stroke();
ctx.fillStyle=“红色”;
ctx.fill()

如果我正确理解你的答案,就像逆时针方向,所有角度都像模(2*PI),但不是顺时针方向。。。所以我应该按顺时针顺序从端到端,而不是按逆时针顺序从端到端,以避免这种行为。但这种行为是预期的路径,还是副作用?我想你是赖特。我已经添加了一个动画演示,显示发生了什么。请看一看。@enxaneta你似乎没有完全明白发生了什么。。。看看我的答案:重要的是开始角和结束角之间的差异,或者相反。所以,如果一个动画让你看得更清楚。在这里,您将看到值确实是经过调制的。