Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/398.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在javascript中从圆弧创建贝塞尔曲线_Javascript_Math_Bezier - Fatal编程技术网

在javascript中从圆弧创建贝塞尔曲线

在javascript中从圆弧创建贝塞尔曲线,javascript,math,bezier,Javascript,Math,Bezier,我想从圆弧上的两个端点(x1,y1,x2,y2)和圆心(cx,cy)或半径创建一条二次贝塞尔曲线 有一次,我认为可以将两个控制点设置为切线的交点,但这似乎不起作用 虽然准确的答案很好,但如果需要的话,我可以接受一个合理的近似值。我的数学能力有限,但会喜欢简单的伪代码。我在谷歌上搜索了一下,有些建议太复杂了,我无法接受 这个问题看起来很简单,但我知道它不简单。要获得圆的良好近似值,请将贝塞尔二次控制点放置在 var cp = (r * 4 * (Math.sqrt( 2 ) - 1)) / 3;

我想从圆弧上的两个端点(x1,y1,x2,y2)和圆心(cx,cy)或半径创建一条二次贝塞尔曲线

有一次,我认为可以将两个控制点设置为切线的交点,但这似乎不起作用

虽然准确的答案很好,但如果需要的话,我可以接受一个合理的近似值。我的数学能力有限,但会喜欢简单的伪代码。我在谷歌上搜索了一下,有些建议太复杂了,我无法接受


这个问题看起来很简单,但我知道它不简单。

要获得圆的良好近似值,请将贝塞尔二次控制点放置在

var cp = (r * 4 * (Math.sqrt( 2 ) - 1)) / 3; 
其中,
r
是点
(x,y)
处圆的半径
cp
是沿切线放置控制点的距离

ctx.moveTo(x-r,y)
ctx.quadCurve(x - r, y - pc, x + r, y - pc, x + r, y); 

将创建一个漂亮的半圆。对底部做同样的操作,得到一个完整的圆。

二次贝塞尔曲线有一个方程式

B(t) = P0 * (1-t)^2+ 2 * P1 * t * (1-t) + P2 * t^2
为了你的案子

P0 = (x1,y1)
P2 = (x2,y2)
为了用贝塞尔近似圆弧,我们可以声明曲线的中点必须和圆弧的中点重合

要找到弧的中点:
我们有弦向量

V = (x2-x1, y2-y1)
垂直矢量(非y符号变化)

它很长

LenP = Sqrt((y1-y2)^2 + (x2-x1)^2)
单位垂直向量

uP = P/LenP = ( (y1-y2) / LenP, (x2-x1) / LenP)
中间弧点

M = C + R * uP = (cx + R * (y1-y2) / LenP, cy + R * (x2-x1) / LenP)
贝塞尔中点

B(1/2) = P0/4 + P1/2 + P2/4 = (x1/4 + px/2 + x2/4, y1/4 + py/2 + y2/4)
现在我们可以写方程了

cx + R * (y1-y2) / LenP = x1/4 + px/2 + x2/4
cy + R * (x2-x1) / LenP = y1/4 + py/2 + y2/4

并找到控制点的
px
py
-坐标。

圆弧和贝塞尔曲线之间没有完美的映射,因为圆具有参数化功能:

ctx.moveTo(x-r,y)
ctx.quadCurve(x - r, y - pc, x + r, y - pc, x + r, y); 
fx(t) = cos(t)
fy(t) = sin(t)
只能以多项式形式表示为无限序列:

fx(t) = ∑(k=0,inf) x^(2k)   * (-1)^k / (2k)!
fy(t) = ∑(k=0,inf) x^(2k+1) * (-1)^k / (2k+1)!

显然,任何有限阶贝塞尔曲线都将始终处于“关闭”状态,尽管阶数越高,我们的“关闭”越少。对于一条三次曲线,我们可以相当合理地近似四分之一圆的弧,尽管任何超过四分之一圆的东西,它看起来都很明显是错误的:有一个关于给定一个角φ的弧的曲线是什么样子的详细说明,值得阅读该部分,然后执行它的解释(或“借用”)来自github的代码,它是公共域代码),以及玩图形来查看当您尝试对超过四分之一的圆进行建模时会出现多大的错误。

您看过d3.js吗?特别是。源代码可以是。d3.js没有将圆弧转换为二次样条曲线的数学例程。我的术语不正确。我应该要一条三次贝塞尔曲线。很抱歉造成混淆。问题其实相对简单,但问题是不能对任何大于四分之一圆一点的圆弧使用三次贝塞尔曲线。我已经添加了一个原因的答案。感谢Blindman67,这可能适用于半圆(180度),但适用于角度不确定的圆弧吗?我猜不会。我需要的东西,适用于任何角度小于180度。我的术语是错误的,我真的需要一个三次贝塞尔曲线从弧。我的错误…谢谢MBo,不过你似乎给了我一个三次贝塞尔曲线的解决方案,我只使用二次贝塞尔曲线。P0、P1、P2、P3,其中P1和P2为控制点。我是否误解了你的解决方案?关于二次贝塞尔解有什么建议吗?没有,我给出了二次贝塞尔解。它们有3个控制点——P0(开始),P1和P2(结束)。有时候只有P1被称为“控制点”,顺便问一下,为什么你只想使用二次型?我有创建贝塞尔面片的代码,但只使用二次贝塞尔面片。P0是弧的起点,P1是控制点,P2是控制点,P3是弧的终点。在我的例子中,圆弧可以穿过小于45度的任何角度。由于只有一个控制点(三次贝塞尔),我无法对其他样条曲线进行足够的控制,因此决定对所有样条曲线都使用二次贝塞尔。我可能使用了不正确的术语。我一直假设一个三次曲线有两个端点和一个控制点,而一个二次贝塞尔曲线有两个端点和两个控制点。是的,你错了。二次曲线-3点,三次曲线-4点