生成立方贝塞尔椭圆弧的通用公式?

时间:2010-07-28 02:28:17

标签: c++ c algorithm graphics vector

如何在C中实现一个简单的方法来为给定起点和终点的椭圆弧生成2个缺失的控制点?我不需要花哨的误差估计,只需要点A和D,然后生成椭圆弧的控制点B和C,然后我可以使用三次贝塞尔插值算法生成曲线。

类似

void GetArcControlPoints(Point a, Point &b, Point &c, Point d)
{

.....
b = ...
c = ....
}

由于

3 个答案:

答案 0 :(得分:4)

你的问题背后的数学存在一些缺陷:

  1. Bézier曲线是单位区间[0; 1]中参数t的多项式函数。椭圆是使用三角函数定义的,这些函数是超越的,因此不是代数,因此不是多项式。您不能使用Bézier曲线生成椭圆弧(既不是立方也不是任何度数n)。但是我们假设您只想近似椭圆弧。由于您没有指定近似值有多好,因此无法确保Bézier曲线对您来说是“椭圆形”。用较少的术语:您需要一个错误参数。

  2. 无限椭圆弧穿过两个给定点。因此,这两个点给出不足够的信息来指定椭圆,其中的弧可以使用贝塞尔曲线近似。 更糟糕的是,由于你想要一个椭圆弧,而不是整个椭圆,你还必须指定弧所需要“覆盖”多少椭圆(百分比)(100%=整个椭圆) ,弧度(2 * pi =整个椭圆),等等。用更少的术语:你需要更多(输入)参数,只需指定 单个椭圆的单个弧。 / p>

  3. 在数学运算正确之前,您无法进入下一步(编码)。


    修改

    1. 由于你需要一个完整的椭圆,我建议使用两个或四个Bézier补丁而不是一个Bézier曲线。

    2. 您可以将椭圆视为在其中一个维度上“拉伸”的圆。现在,由于“拉伸”变换是线性的,Bézier函数在控制点上是线性的,因此您可以计算近似于90度圆弧的Bézier曲线的控制点,然后将“拉伸”变换应用于控制点,并且vo ,您可以得到近似于“90度”椭圆弧的贝塞尔曲线的控制点。获取整个椭圆只是重复该过程四次。

答案 1 :(得分:1)

以下是单位圆弧段控制点的推导:

http://www.whizkidtech.redprince.net/bezier/circle/kappa/

可以通过应用适当的仿射变换生成每个可能的椭圆。

答案 2 :(得分:0)

kappa公式只是一个近似值。这个是用4立方Bezier绘制圆或椭圆的一个很好的近似:它恰好匹配8个点(两个轴上和两个主要对角线上的那些,kappa公式中考虑的唯一点),但是存在差异在其他地方。

然而,即使我们不能使用这样的样条线来绘制带有贝塞尔曲线的圆或椭圆,也确实存在一个&#34;精确的&#34;基于Bresenham算法,使用算术运算逐个像素地逐渐绘制圆形近似(最多1个半像素的差异)(这样的近似是可能的,因为我们可以计算完全< / em>,仅使用加法,指向圆心的点的平方距离或到椭圆的两个焦点的距离之和,并检查像素是否为&#34;内部&#34;或&#34它的外部&#34;并且因为我们知道圆或椭圆上的起点的确切位置,所以我们可以测试两个可能的邻居中的哪一个,在8个扇区中的任何一个中,最接近于圆或椭圆)。

这种增量算法近似椭圆弧与贝塞尔样条曲线的增量算法完全不同,但它也非常有效(实际上甚至比绘制任意贝塞尔样条曲线时更快)。