【问题标题】:How can I draw a circle on a canvas?如何在画布上画一个圆圈?
【发布时间】:2015-07-14 08:02:38
【问题描述】:

我正在使用 javascript 和画布绘制数学设计的刻度(用于测量扭矩,它包括牛顿米和英尺磅)。我一直在使用三角法定位我的刻度,并使用arc 绘制弧线,很自然。当他们需要排队时,问题就来了,但出现了一些奇怪的失真。然后我画了一个非常大的圆圈并将其与 GIMP 中的圆形选择进行比较,结果出现了变形。这些圆在圆周围每 45 度是一致的,但在这些节点之间,画布绘制的圆向外偏离,就像一个八边形,可以向外圆得太远而无法近似圆。

为什么会出现这些扭曲?如何在画布上绘制一个真正的圆形?

这是我用来生成扭曲圆圈的代码。

<!DOCTYPE html>
<html>
  <body>
    <canvas width=8000 height=8000 id='myCanvas'></canvas>
    <script>
      var canvas = document.getElementById('myCanvas');
      var context = canvas.getContext('2d');
      context.beginPath();
      context.arc(4000, 4000, 3200, 0, Math.PI*2, false);
      context.lineWidth = 1;
      context.strokeStyle = '#ff0000';
      context.lineCap = 'square';
      context.stroke();
    </script>
  </body>
</html>

这可能不是最小的,我不知道context.lineCap 的相关性,但它是它所基于的代码的遗迹。 以下截图显示了 GIMP 绘制的圆和 Chrome 绘制的圆的区别

【问题讨论】:

  • 你有示例代码吗?
  • @JonSaw 当然。我将添加用于生成我的圈子的代码。
  • 在 Safari (8.0.6)、Chrome (43.0.2357.132) 和 Firefox (36.0.4) 上运行您的代码——在我的身上看起来不错。 JS斌here。只是出于好奇,您使用的是什么浏览器?
  • Chrome 42.0.2311.135
  • 也许我对平滑圆的定义可能与您的不同。如果可以的话,也许是您想要实现的目标的屏幕截图?

标签: javascript html canvas


【解决方案1】:

这是Chromium Bug #164241(已宣布修复,尽管修复可能还没有完成)。简短的回答是:Chrome 是 approximating circles with composite Bezier curves

我自己无法在 Chromium(43.0.2357.130,Ubuntu)上复制它,但它确实发生在 Firefox 39 上,尽管我找不到 Firefox 的类似错误报告。它每 90 度正确(不是 45 度,至少对我来说不是)这一事实表明圆被 4 条曲线逼近,因为曲线端点保证是正确的。

幸运的是,有一个简单的解决方法:创建一个包含 4 条以上曲线的路径。对于您使用的半径,8 甚至 6 应该足够了,但如果您想安全地使用它,您可以使用更多。或者您可以根据半径增加曲线的数量,尽管计算最优函数(对于给定半径 r 产生精确圆的最小 n)并非易事。

context.beginPath();
var n=8; // 4 is the default behaviour. higher is better, also slower
for (var i=0; i<n; i++) {
    context.arc(4000, 4000, 3200, Math.PI*2*i/n, Math.PI*2*(i+1)/n, false);
}
context.stroke();

另见this question

(是的,lineCap 是一个红鲱鱼。)

【讨论】:

  • 多么令人失望。我想我只需要自己写一个更好的近似值。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-07-25
  • 1970-01-01
  • 2015-10-22
  • 1970-01-01
  • 2012-11-12
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多