Mik*_*ron 28 math graphics geometry
当绘制二维弧,用Bezier曲线近似,如何计算给定的,你有一个圆圈,开始和结束的角度和半径的中心点在两个控制点?
小智 16
这是一个8年的问题,但是我最近一直在努力解决这个问题,所以我想我会分享我想出的东西.我花了很多时间试图利用从溶液(9)这段文字并不能得到任何合理的数字出来,直到我做了一些谷歌搜索,并了解到,显然,有在方程中一些错别字.根据本博文中列出的更正,给定弧的起点和终点(分别为[x1,y1]和[x4,y4])和圆的中心([xc,yc]),可以推导出三次贝塞尔曲线([x2,y2]和[x3,y3])的控制点,如下所示:
ax = x1 – xc
ay = y1 – yc
bx = x4 – xc
by = y4 – yc
q1 = ax * ax + ay * ay
q2 = q1 + ax * bx + ay * by
k2 = 4/3 * (?(2 * q1 * q2) – q2) / (ax * by – ay * bx)
x2 = xc + ax – k2 * ay
y2 = yc + ay + k2 * ax
x3 = xc + bx + k2 * by
y3 = yc + by – k2 * bx
Run Code Online (Sandbox Code Playgroud)
希望这能帮助除我之外的其他人!
一个很好的解释中的“逼近”提供三次Bezier曲线由圆弧“
长话短说:使用贝塞尔曲线,您可以实现 1.96×10^-4 的最小误差,这对于大多数应用程序来说是相当不错的。
对于正象限弧,使用以下几点:
p0 = [0, radius]
p1 = [radius * K, radius]
p2 = [radius, radius * K]
p3 = [radius, 0]
Run Code Online (Sandbox Code Playgroud)
其中K是一个所谓的“幻数”,它是一个无理数。它可以近似如下:
K = 0.5522847498
Run Code Online (Sandbox Code Playgroud)
我正在通过一些演示来回答这个老问题(它应该属于数学,所以写公式会很糟糕)。
假设P0和P3是弧的起点和终点,P1和P2是贝塞尔曲线的控制点,x是角度除以 2 的度量。假设x小于pi /2。
让PM为线段的中点P0P3和PH弧的中点。为了近似圆弧,我们希望贝塞尔曲线从P0开始,通过PH,在P3结束,并与P0和P3 中的圆弧相切。
(单击“运行代码片段”以显示该图。对 imgur 的诅咒仍然不支持 SVG。)
<svg xmlns="http://www.w3.org/2000/svg" viewBox="10 20 80 80">
<style>text{font-size:40%;font-style:italic;text-anchor:middle}tspan{font-size:50%;font-style:normal}</style>
<rect x="10" y="20" width="80" height="80" fill="none" stroke="gray"></rect>
<path stroke="gray" stroke-dasharray="3,2" fill="none" d="M25,30 62.6,31.62 80,65 22.19,95.13 25,30 80,65 M22.19,95.13 62.6,31.62"></path>
<path stroke="black" fill="none" d="M25,30A65.19 65.19 0 0 1 80,65"></path>
<circle r="1" fill="red" cx="25" cy="30"></circle>
<circle r="1" fill="green" cx="80" cy="65"></circle>
<circle r="1" fill="magenta" cx="22.19" cy="95.13"></circle>
<circle r="1" fill="darkgreen" cx="52.5" cy="47.5"></circle>
<circle r="1" fill="yellow" cx="57.19" cy="40.13"></circle>
<circle r="1" fill="maroon" cx="62.6" cy="31.62"></circle>
<circle r="1" fill="orange" cx="48.27" cy="31"></circle>
<circle r="1" fill="teal" cx="69.24" cy="44.35"></circle>
<text x="25" y="28">P<tspan>0</tspan></text>
<text x="48.27" y="29">P<tspan>1</tspan></text>
<text x="71.24" y="42.35">P<tspan>2</tspan></text>
<text x="83" y="63">P<tspan>3</tspan></text>
<text x="62.6" y="29.62">P<tspan>E</tspan></text>
<text x="59.19" y="47.13">P<tspan>H</tspan></text>
<text x="54.5" y="54.5">P<tspan>M</tspan></text>
</svg>Run Code Online (Sandbox Code Playgroud)
设PE为P0和P3 中与圆弧相切的线的交点。为了使曲线与圆弧相切,P1必须位于线段P0PE 上,P2必须位于P3PE 上。令k为比率P0P1 / P0PE(也等于P3P2 / P3PE):
P1 = (1 - k ) P0 + k PE
P2 = (1 - k ) P3 + k PE
我们还有以下(做一些比例):
PM = ( P0 + P3 ) / 2
PH = PM / cos( x ) = PM sec( x ) = ( P0 + P3 ) 秒( x ) / 2
PE = PH / cos( x ) = PM sec( x )^2 = ( P0 + P3 ) sec( x )^2 / 2
为了简化我们的计算,我认为所有的向量点都是基于中心的,但最终都没有关系。
通用 4 点贝塞尔曲线由以下公式给出
C ( t ) = t ^3 P3 + 3(1 - t ) t ^2 P2 + 3(1 - t )^2 t P1 + (1 - t )^3 P0
我们必须有 C (1/2) = PH,所以
C (1/2) = ( P0 + 3 P1 + 3 P2 + P3 ) / 8
= (( P0 + P3 ) + 3(1 - k ) P0 + 3 k PE + 3(1 - k ) P3 + 3 k PE ) / 8
= (( P0 + P3 ) + 3(1 - k )( P0 + P3 ) + 6 k PE ) / 8
= ( P0 + P3 )(1 + 3(1 - k ) + 3 k秒( x )^2) / 8
所以,这是我们找到k 的等式(乘以 8):
8 C (1/2) = 8 PH
=> ( P0 + P3 )(4 - 3 k + 3 k秒( x )^2) = 4( P0 + P3 ) 秒( x )
让我们摆脱向量( P0 + P3),我们得到:
4 - 3 k + 3 k秒( x )^2 = 4 秒( x )
=> 3 k(秒( x )^2 - 1) = 4(秒( x ) - 1)
=> k = 4 / 3(秒( x ) + 1)
现在您知道在哪里放置控制点。万岁!
如果你有x = pi /4,你会得到k = 0.552...你可能已经看到了这个值。
在处理椭圆弧时,您所要做的就是相应地缩放点的坐标。
如果您必须处理更大的角度,我建议将它们分成更多的曲线。这实际上是一些软件在绘制圆弧时所做的,因为计算贝塞尔曲线有时比使用正弦和余弦更快。
Wolfram MathWorld中有Mathematica代码:Arc的Bézier曲线逼近,应该可以帮助您入门.
也可以看看: