热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

如何用Bezier曲线创建圆?-HowtocreatecirclewithBéziercurves?

Wehaveastartpoint(x,y)andacircleradius.Therealsoexistsanenginethatcancreateapath

We have a start point (x, y) and a circle radius. There also exists an engine that can create a path from Bézier curve points.

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

How can I create a circle using Bézier curves?

如何使用Bezier曲线创建一个圆?

9 个解决方案

#1


93  

As already said: there is no exact representation of the circle using Bezier curves.

正如已经说过的:使用Bezier曲线没有精确的圆圈表示。

To complete the other answers : for Bezier curve with n segments the optimal distance to the control points, in the sense that the middle of the curve lies on the circle itself, is (4/3)*tan(pi/(2n)).

为了完成另一个答案:对于Bezier曲线,n段的最优距离为控制点,在这一意义上,曲线的中间部分位于圆本身,即(4/3)*tan(pi/(2n))。

formula for n segments

So for 4 points it is (4/3)*tan(pi/8) = 4*(sqrt(2)-1)/3 = 0.552284749831.

因此,4点是(4/3)*tan(/8) = 4*(√2)-1)/3 = 0.552284749831。

4 point case

#2


25  

Covered in the comp.graphics.faq

在comp.graphics.faq

Excerpt:

Subject 4.04: How do I fit a Bezier curve to a circle?

主题4.04:我如何将一个Bezier曲线贴到一个圆上?

Interestingly enough, Bezier curves can approximate a circle but not perfectly fit a circle. A common approximation is to use four beziers to model a circle, each with control points a distance d=r*4*(sqrt(2)-1)/3 from the end points (where r is the circle radius), and in a direction tangent to the circle at the end points. This will ensure the mid-points of the Beziers are on the circle, and that the first derivative is continuous.
The radial error in this approximation will be about 0.0273% of the circle's radius.

有趣的是,Bezier曲线可以近似一个圆,但不完全适合一个圆。一个常见的近似方法是用四个贝齐尔模型来模拟一个圆,每一个都有一个距离d=r*4*(sqrt(2)-1)/3从端点处(r为圆半径),并在一个方向与圆的端点相切。这将确保Beziers的中点在圆上,并且一阶导数是连续的。这个近似的径向误差大约是圆半径的0.0273%。

Michael Goldapp, "Approximation of circular arcs by cubic polynomials" Computer Aided Geometric Design (#8 1991 pp.227-238)

Michael Goldapp,“三次多项式圆弧的近似”计算机辅助几何设计(# 81991pp.227 -238)

Tor Dokken and Morten Daehlen, "Good Approximations of circles by curvature-continuous Bezier curves" Computer Aided Geometric Design (#7 1990 pp. 33-41). http://www.sciencedirect.com/science/article/pii/016783969090019N (non free article)

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

Also see the non-paywalled article at http://spencermortensen.com/articles/bezier-circle/

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

Browsers and Canvas Element.

Note that some browsers use Bezier curves to their canvas draw arc, Chrome uses (at the present time) a 4 sector approach and Safari uses an 8 sector approach, the difference is noticeable only at high resolution, because of that 0.0273%, and also only truly visible when arcs are drawn in parallel and out of phase, you'll notice the arcs oscillate from a true circle. The effect is also more noticeable when the curve is animating around it's radial center, 600px radius is usually the size where it will make a difference.

注意,一些浏览器使用贝塞尔曲线的帆布画弧,Chrome使用(目前)4部门方法和Safari使用8部门的方法,只在高分辨率的区别是明显的,因为,0.0273%,也只有真正可见弧时并行的阶段,你会注意到弧振动从一个真正的圆。当曲线在它的径向中心周围运动时,效果也会更明显,600像素的半径通常是它会产生影响的大小。

Certain drawing API's don't have true arc rendering so they also use Bezier curves, for example the Flash platform has no arc drawing api, so any frameworks that offer arcs are generally using the same Bezier curve approach.

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

Note that SVG engines within browsers may use a different drawing method.

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

Other platforms

Whatever platform you are trying to use, it's worth checking to see how arc drawing is done, so you can predict visual errors like this, and adapt.

无论你想要使用什么平台,都值得检查一下如何绘制圆弧图,这样你就可以预测出这样的视觉错误,并进行调整。

#3


17  

The answers to the question are very good, so there's little to add. Inspired by that I started to make an experiment to visually confirm the solution, starting with with four Bézier curves, reducing the number of curves to one. Amazingly I found out that with three Bézier curves the circle looked good enough for me, but the construction is a bit tricky. Actually I used Inkscape to place the black 1-pixel-wide Bézier approximation over a red 3-pixel-wide circle (as produced by Inkscape). For clarification I added blue lines and surfaces showing the bounding boxes of the Bézier curves.

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

To see yourself, I'm presenting my results:

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

The 1-curve graph (which looks like a drop squeezed in a corner, just for completeness) :enter image description here

1曲线图(看起来像一个被挤压在角落里的水滴,只是为了完整性):

The 2-curve graph:enter image description here

2-curve图:

The 3-curve graph:enter image description here

3-curve图:

The 4-curve graph: enter image description here

4-curve图:

(I wanted to put the SVG or PDF here, but that isn't supported)

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

#4


9  

It is not possible. A Bezier is a cubic (at least... the most commonly used is). A circle cannot be expressed exactly with a cubic, because a circle contains a square root in its equation. As a consequence, you have to approximate.

这是不可能的。一个Bezier是一个立方体(至少……最常用的是)。一个圆不能用一个立方来表示,因为一个圆在它的方程中包含一个平方根。因此,你必须近似。

To do this, you have to divide your circle in n-tants (e.g.quadrants, octants). For each n-tant, you use the first and last point as the first and last of the Bezier curve. The Bezier polygon requires two additional points. To be fast, I would take the tangents to the circle for each extreme point of the n-tant and choose the two points as the intersection of the two tangents (so that basically your Bezier polygon is a triangle). Increase the number of n-tants to fit your precision.

要做到这一点,你必须将你的圆圈划分成n个元素(例如,象限,八面体)。对于每一个n-分函数,你使用第一个和最后一个点作为Bezier曲线的第一个和最后一个点。Bezier多边形需要两个额外的点。为了快速,我要把切线的每一个端点都取到n个点的每一个端点,然后选择两个点作为两个切线的交点(这样你的贝齐尔多边形就是一个三角形)。增加n-变种的数量以符合你的精度。

#5


7  

The other answers have covered the fact that a true circle is not possible. This SVG file is an approximation using Quadratic Bezier curves, and is the closest thing you can get: http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg

其他的答案涵盖了一个事实,即一个真正的圆是不可能的。这个SVG文件是一个使用二次Bezier曲线的近似,它是您可以得到的最接近的东西:http://en.wikipedia.org/wiki/File:Circle_and_quadratic_bezier.svg。

Here's one with Cubic Bezier curves: http://en.wikipedia.org/wiki/File:Circle_and_cubic_bezier.svg

这里有一个立方体Bezier曲线:http://en.wikipedia.org/wiki/File: circle_and__bezier .svg。

#6


7  

Many answers already but I found a small online article with a very good cubic bezier approximation of a circle. In terms of unit circle c = 0.55191502449 where c is the distance from the axis intercept points along the tangents to the control points.

已经有很多答案了,但我在网上找到了一篇小文章,里面有一个很好的立方体的近似圆形。单位圆c = 0.55191502449,其中c为轴截距沿切线方向与控制点的距离。

As a single quadrant for the unit circle with the two middle coordinates being the control points. (0,1),(c,1),(1,c),(1,0)

作为单位圆的一个象限,两个中间坐标是控制点。(0,1),(c,1),(1 c),(1,0)

The radial error is just 0.019608% so I just had to add it to this list of answers.

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

The article can be found here Approximate a circle with cubic Bézier curves

这篇文章可以在这里找到一个近似圆的立方体贝齐尔曲线。

#7


1  

I'm not sure if i should open new question since this is about aproximation but I'm interested in general formula to get control points for Bezier of any degree and I believe it fits within this question. All solutions I found on the web are only for cubic curves or are paid or I don't even understand (I'm not very good at math). So I decided try to solve this on my own. I was study distance of the control point from center of a circle dependent on given angle and so far I found that:

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

enter image description here

Where N is number of control points for single curve and α is circle arc angle.

其中N是针对单一曲线控制点和α是圆弧角。

For quadratic curve it can be simplified to l ≈ r + r * PI*0.1 * pow(α/90, 2) The PI*0.1 is rather a guess - I didn't calculate perfect value but it's pretty close. This works reasonably good for curve with 1-2 control points giving radius error about 0.2% for cubic curve. For higher degree curves loss of accuracy is noticable. With 3 control points curve look similar to quadratic so obviously I'm miss something but I can't figure it out and this method generally fits my needs for now. Here is demo.

二次曲线可以简化到l≈r + r *π* 0.1 *战俘(α/ 90,2)π* 0.1是猜测,我没有计算但很接近完美的价值。这对1-2控制点的曲线具有相当好的效果,在三次曲线上,半径误差约为0.2%。对于更高的度曲线,精度损失是显而易见的。有3个控制点曲线与二次曲线相似,所以很明显,我错过了一些东西,但我无法确定,这个方法通常适合我现在的需求。这是演示。

#8


0  

Sorry to bring this one back from the dead, but I found this post very helpful along with this page in coming up with an expandable formula.

不好意思把这个从死里拿回来,但是我发现这篇文章很有帮助,这一页的内容是一个可扩展的公式。

Basically, you can create a near circle using an incredibly simple formula that allows you to use any number of Bezier curves over 4: Distance = radius * stepAngle / 3

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

Where Distance is the distance between a Bezier control point and the closest end of the arc, radius is the radius of the circle, and stepAngle is the angle between the 2 ends of the arc as represented by 2π / (the number of curves).

在距离是贝塞尔曲线控制点之间的距离和最近的弧,圆的半径,半径和stepAngle 2的弧之间的角度用2π/(曲线)的数量。

So to hit it in one shot: Distance = radius * 2π / (the number of curves) / 3

所以达到这一箭:距离=半径* 2π/(曲线)/ 3

#9


-1  

It's a heavy approximation that will look reasonable or terrible depending on the resolution and precision but I use sqrt(2)/2 x radius as my control points. I read a rather long text how that number is derived and it's worth reading but the formula above is the quick and dirty.

这是一个很重的近似,根据分辨率和精度,看起来是合理的或者可怕的,但是我使用了sqrt(2)/2 x的半径作为控制点。我读了一个很长的文本,这个数字是如何推导出来的,它值得一读,但上面的公式是快速和肮脏的。


推荐阅读
  • Whatsthedifferencebetweento_aandto_ary?to_a和to_ary有什么区别? ... [详细]
  • 微软头条实习生分享深度学习自学指南
    本文介绍了一位微软头条实习生自学深度学习的经验分享,包括学习资源推荐、重要基础知识的学习要点等。作者强调了学好Python和数学基础的重要性,并提供了一些建议。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • CF:3D City Model(小思维)问题解析和代码实现
    本文通过解析CF:3D City Model问题,介绍了问题的背景和要求,并给出了相应的代码实现。该问题涉及到在一个矩形的网格上建造城市的情景,每个网格单元可以作为建筑的基础,建筑由多个立方体叠加而成。文章详细讲解了问题的解决思路,并给出了相应的代码实现供读者参考。 ... [详细]
  • 本文介绍了南邮ctf-web的writeup,包括签到题和md5 collision。在CTF比赛和渗透测试中,可以通过查看源代码、代码注释、页面隐藏元素、超链接和HTTP响应头部来寻找flag或提示信息。利用PHP弱类型,可以发现md5('QNKCDZO')='0e830400451993494058024219903391'和md5('240610708')='0e462097431906509019562988736854'。 ... [详细]
  • iOS Swift中如何实现自动登录?
    本文介绍了在iOS Swift中如何实现自动登录的方法,包括使用故事板、SWRevealViewController等技术,以及解决用户注销后重新登录自动跳转到主页的问题。 ... [详细]
  • 本文介绍了OpenStack的逻辑概念以及其构成简介,包括了软件开源项目、基础设施资源管理平台、三大核心组件等内容。同时还介绍了Horizon(UI模块)等相关信息。 ... [详细]
  • 本文介绍了响应式页面的概念和实现方式,包括针对不同终端制作特定页面和制作一个页面适应不同终端的显示。分析了两种实现方式的优缺点,提出了选择方案的建议。同时,对于响应式页面的需求和背景进行了讨论,解释了为什么需要响应式页面。 ... [详细]
  • 本文记录了作者对x265开源代码的实现与框架进行学习与探索的过程,包括x265的下载地址与参考资料,以及在Win7 32 bit PC、VS2010平台上的安装与配置步骤。 ... [详细]
  • HTML学习02 图像标签的使用和属性
    本文介绍了HTML中图像标签的使用和属性,包括定义图像、定义图像地图、使用源属性和替换文本属性。同时提供了相关实例和注意事项,帮助读者更好地理解和应用图像标签。 ... [详细]
  • 深入理解CSS中的margin属性及其应用场景
    本文主要介绍了CSS中的margin属性及其应用场景,包括垂直外边距合并、padding的使用时机、行内替换元素与费替换元素的区别、margin的基线、盒子的物理大小、显示大小、逻辑大小等知识点。通过深入理解这些概念,读者可以更好地掌握margin的用法和原理。同时,文中提供了一些相关的文档和规范供读者参考。 ... [详细]
  • 本文介绍了Windows操作系统的版本及其特点,包括Windows 7系统的6个版本:Starter、Home Basic、Home Premium、Professional、Enterprise、Ultimate。Windows操作系统是微软公司研发的一套操作系统,具有人机操作性优异、支持的应用软件较多、对硬件支持良好等优点。Windows 7 Starter是功能最少的版本,缺乏Aero特效功能,没有64位支持,最初设计不能同时运行三个以上应用程序。 ... [详细]
  • IjustinheritedsomewebpageswhichusesMooTools.IneverusedMooTools.NowIneedtoaddsomef ... [详细]
  • 本文讨论了如何在codeigniter中识别来自angularjs的请求,并提供了两种方法的代码示例。作者尝试了$this->input->is_ajax_request()和自定义函数is_ajax(),但都没有成功。最后,作者展示了一个ajax请求的示例代码。 ... [详细]
  • This article discusses the efficiency of using char str[] and char *str and whether there is any reason to prefer one over the other. It explains the difference between the two and provides an example to illustrate their usage. ... [详细]
author-avatar
小张
这个家伙很懒,什么也没留下!
Tags | 热门标签
RankList | 热门文章
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有