如何创建圆与 B & # 233; 齐尔曲线?

我们有一个起点(x,y)和一个圆半径。还有一个引擎,可以创建一个路径从贝塞尔曲线点。

如何使用 Bézier 曲线创建一个圆?

93406 次浏览

这是不可能的。Bezier 是立方体(至少... ... 最常用的是立方体)。圆不能用立方体精确表示,因为圆的方程中含有一个平方根。因此,你必须估计。

要做到这一点,你必须用 n 个代数来划分你的圆(例如象限,八角形)。对于每个 n 元素,使用第一个和最后一个点作为 Bezier 曲线的第一个和最后一个点。贝塞尔多边形需要两个额外的点。为了快速起见,我把 n 次方的每个极值点的切线取到圆上,然后选择这两个点作为两个切线的交点(这样基本上你的 Bezier 多边形就是一个三角形)。增加 n 元素的数量以适应你的精度。

包含在 comp.Graphics.faq 中

节选:

实验对象4.04: 如何将贝塞尔曲线拟合成一个圆?

有趣的是,贝塞尔曲线可以近似一个圆,但 不完全符合一个圆。 一个常见的近似方法是使用四个贝塞尔来建模一个圆,每个圆 控制点距离 d = r * 4 * (sqrt (2)-1)/3 (其中 r 是圆的半径) ,并在一个方向相切的 圆的中点。这将确保 Beziers 在圆周上一阶导数是连续的。
在这种近似下,径向误差将约为该方法的0.0273% 圆的半径。

Michael Goldapp,“圆弧的立方近似 《计算机辅助几何设计》(# 81991第227-238页)

Tor Dokken 和 Morten Daehlen,“圆的良好近似 曲率-连续 Bezier 曲线计算机辅助几何 设计(# 71990第33-41页)。 http://www.sciencedirect.com/science/article/pii/016783969090019N(非免费文章)

也可以在 http://spencermortensen.com/articles/bezier-circle/上看到非付费墙的文章

浏览器和画布元素。

请注意,一些浏览器使用 Bezier 曲线来绘制圆弧,Chrome (目前)使用4扇区方法,而 Safari 使用8扇区方法,这种差异只有在高分辨率时才会显现出来,因为它的分辨率只有0.0273% ,而且只有当圆弧平行绘制和相位不同时才会真正显现出来,你会注意到圆弧是由一个真正的圆振荡而来的。当曲线在径向中心附近活动时,效果也更加明显,600像素的半径通常是产生不同效果的尺寸。

某些绘图 API 没有真正的弧线渲染,所以他们也使用 Bezier 曲线,例如 Flash 平台没有弧线绘图 API,所以任何提供弧线的框架通常都使用相同的 Bezier 曲线方法。

请注意,浏览器中的 SVG 引擎可能使用不同的绘图方法。

其他平台

无论您试图使用什么平台,都值得检查弧线绘制是如何完成的,因此您可以预测这样的视觉错误,并进行调整。

其他的答案已经包含了这样一个事实: 真正的圆是不可能的。这个 SVG 文件是使用二次 Bezier 曲线的近似值,它是您能得到的最接近的结果: http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg

这里有一个立方贝塞尔曲线: http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg

这是一个很大的近似值,根据分辨率和精度,它看起来是合理的还是糟糕的,但是我使用 Sqrt (2)/2 x 半径作为我的控制点。我读了一篇相当长的文章,这个数字是如何得出的,值得一读,但上面的公式是快速和肮脏的。

很抱歉让你死而复生,但是我发现这篇文章和 这个页面在提出一个可扩展的公式方面非常有帮助。

基本上,您可以使用一个非常简单的公式创建一个近圆,该公式允许您在4: Distance = radius * stepAngle / 3上使用任意数量的 Bezier 曲线

其中 Distance是 Bezier 控制点与弧线最近端之间的距离,半径是圆的 radius,而 stepAngle是弧线两端之间的夹角,用2π/(曲线数)表示。

所以一击必中: Distance = radius * 2π / (the number of curves) / 3

如前所述: 使用 Bezier 曲线并不能精确地表示圆。

完成其他的答案: 对于贝塞尔曲线与 n分段的 最佳状态距离的控制点,在这个意义上,曲线的中间位于圆本身,是 (4/3)*tan(pi/(2n))

formula for n segments

所以4分是 (4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831

4 point case

我不知道我是否应该打开新的问题,因为这是关于近似,但我感兴趣的一般公式,以获得控制点的贝塞尔任何程度,我相信它适合这个问题。 我在网上找到的所有解决方案都只是三次曲线,或者是付费的,或者我根本不懂(我数学不是很好)。 所以我决定自己解决这个问题。我研究了控制点到圆心的距离取决于给定的角度,到目前为止我发现:

enter image description here

其中 N是单曲线的控制点数,α是圆弧角。

对于二次曲线,可以简化为 l ≈ r + r * PI*0.1 * pow(α/90, 2) PI*0.1是一个相当大的猜测-我没有计算完美的价值,但它相当接近。 对于1-2个控制点,三次曲线半径误差在0.2% 左右的曲线,该方法效果较好。对于高度曲线,精度的损失是显而易见的。3个控制点曲线看起来类似于二次曲线,所以很明显我遗漏了一些东西,但我不能弄清楚,这种方法通常适合我的需要现在。 这里是 小样

许多答案已经,但我发现一个非常好的立方贝塞尔近似圆在线小文章。根据单位圆 c = 0.55191502449,其中 c 是从轴线截点沿切线到控制点的距离。

作为单位圆的一个象限,其中两个中间坐标作为控制点

径向误差只有0.019608% ,所以我只需要把它添加到这个答案列表中。

这篇文章可以在这里找到 用三次 Bézier 曲线逼近圆

这个问题的答案非常好,所以没什么可补充的。受此启发,我开始做一个实验,以 视觉上确认解决方案,从四个 Bézier 曲线开始,减少到一个曲线的数量。令人惊讶的是,我发现三个贝塞尔曲线的圆看起来像 很好为我,但构造有点棘手。实际上,我使用 Inkscape 将黑色1像素宽的 Bézier 近似值放置在红色3像素宽的圆上(由 Inkscape 生成)。为了澄清,我添加了显示 Bézier 曲线边界框的蓝线和曲面。

为了看看你自己,我展示了我的结果:

1-曲线图(看起来像一个水滴挤在一个角落,只是为了完整性) :enter image description here

双曲线图:enter image description here

3条曲线图:enter image description here

4条曲线图:enter image description here

(我想把 SVG 或 PDF 放在这里,但这不受支持)

对于那些只是在寻找代码的人来说:

Https://jsfiddle.net/nooorz24/2u9forep/12/

var c = document.getElementById("myCanvas");
var ctx = c.getContext("2d");


function drawBezierOvalQuarter(centerX, centerY, sizeX, sizeY) {
ctx.beginPath();
ctx.moveTo(
centerX - (sizeX),
centerY - (0)
);
ctx.bezierCurveTo(
centerX - (sizeX),
centerY - (0.552 * sizeY),
centerX - (0.552 * sizeX),
centerY - (sizeY),
centerX - (0),
centerY - (sizeY)
);
ctx.stroke();
}


function drawBezierOval(centerX, centerY, sizeX, sizeY) {
drawBezierOvalQuarter(centerX, centerY, -sizeX, sizeY);
drawBezierOvalQuarter(centerX, centerY, sizeX, sizeY);
drawBezierOvalQuarter(centerX, centerY, sizeX, -sizeY);
drawBezierOvalQuarter(centerX, centerY, -sizeX, -sizeY);
}


function drawBezierCircle(centerX, centerY, size) {
drawBezierOval(centerX, centerY, size, size)
}


drawBezierCircle(200, 200, 64)
<canvas id="myCanvas" width="400" height="400" style="border:1px solid #d3d3d3;">
Your browser does not support the HTML5 canvas tag.</canvas>

这允许画圆,是由4贝塞尔曲线。 用 JS 编写,但可以很容易地翻译成任何其他语言

注意

不要使用贝塞尔曲线,如果你需要绘制一个圆使用 SVG 路径,除非必须这样做。在路径中可以使用 Arc创建2个半圆。

圆绘制与 SVG 的弧路径