65.9K
CodeProject 正在变化。 阅读更多。
Home

贝塞尔曲线简单实现

2008年4月14日

CPOL

4分钟阅读

viewsIcon

404267

downloadIcon

15145

用 C# 简单实现著名的贝塞尔曲线。 易于理解。

BezierInterpolation.gif

引言

贝塞尔曲线是最基本的曲线,通常用于计算机图形学和图像处理。 这些曲线主要用于插值、近似、曲线拟合和对象表示。 在本文中,我将以一种非常简单直接的方式演示如何构建这些曲线并使用它们。

背景

贝塞尔曲线是参数曲线,非常易于定制和平滑。 它们非常适合许多应用。 它们以法国数学家兼工程师皮埃尔·贝塞尔的名字命名,他在 20 世纪 60 年代后期为汽车制造商雷诺工作时开发了这种计算机绘图方法。 人们说,在同一时期,福特的研究中也发生了同样的发展。 谁先发现它仍然存在争议。

由于我的图像处理背景,我的文章将主要关注插值和曲线拟合。 在插值中,人们只想使用已知值来找到未知点。 这样,一个离散的情况可以用一个更连续的结构来表示,并且我们可以为缺失的点定义一个明确的曲线。 该曲线使用某些数据点进行初始化,它试图生成近似(或插值)旧值的新值。

构造贝塞尔曲线算法

考虑 n+1 个点 P0,…,Pn,并将这些点连接成一条折线,我们将其表示为控制多边形。

figure2.jpg

给定点 Pi,i = 0,...,n,我们的目标是确定一条曲线 g (t),对于所有值 t Î [0,1]。 这个想法在下面进行了演示

figure.jpg

基本算法

这里的目标是在两个相邻点的中间找到点,并重复此过程,直到我们不再有迭代。 点的新值将为我们提供曲线。 著名的贝塞尔方程是这个想法的确切表述。 这是算法

步骤 1:选择一个值 t Î [0,1]。 对于其余步骤,此值保持不变。

步骤 2:设置 Pi[0] (t) = Pi,对于 i = 0,...,n。

步骤 3:对于 j= 0,...,n,设置 simple.jpg 对于 i = j,...,n。

步骤 4:g (t) = Pn[n] (t)

特殊和一般情况

现在,我将给出适用于某些应用程序的常见特殊情况的公式。 本文的代码没有演示任何内容,但它使用了广义公式。 所以,让我从广义公式开始

general.jpg

为了本文和代码中使用的简单性和约定,最好将此公式表示为

notation.jpg

这个方程告诉我们的只不过是上述算法(中点迭代)的公式。 它非常重要,因为整个算法可以总结成一个公式,而直接的实现将产生正确的结果。 这里,n 表示点的数量,P 表示点本身。 这些点的阶乘系数简称为伯恩斯坦基函数,因为创始人以此命名。

以下是特殊情况

线性贝塞尔

f1.jpg

二次贝塞尔

f3.jpg

三次贝塞尔

f2.jpg

理解和使用代码

这是执行所有工作的函数。 我认为它非常短而且非常简单。 因为我们只处理二维曲线,所以我们在 X 和 Y 坐标中有点。 该函数只是计算贝塞尔点。

public void Bezier2D(double[] b, int cpts, double[] p)
{
    int npts = (b.Length) / 2;
    int icount, jcount;
    double step, t;

    // Calculate points on curve

    icount = 0;
    t = 0;
    step = (double)1.0 / (cpts - 1);

    for (int i1 = 0; i1 != cpts; i1++)
    { 
        if ((1.0 - t) < 5e-6) 
            t = 1.0;

        jcount = 0;
        p[icount] = 0.0;
        p[icount + 1] = 0.0;
        for (int i = 0; i != npts; i++)
        {
            double basis = Bernstein(npts - 1, i, t);
            p[icount] += basis * b[jcount];
            p[icount + 1] += basis * b[jcount + 1];
            jcount = jcount +2;
        }

        icount += 2;
        t += step;
    }
}

其余的函数只是辅助函数,参与阶乘计算和基函数计算,我相信这很明显。 要正确使用此函数,请以以下格式提供一组点:XYXYXYXYXYXYXYXYXYXY.... 坐标以及您想在曲线上计算的点数。 该函数将使用路径点填充 p 数组。

关注点

由于阶乘计算的限制,该代码只能计算最多 32 个点的曲线。 更复杂的结构通常由这些曲线的组合表示(如在 Adobe Photoshop、Illustrator 和 Flash - 路径工具中)。

即使 GDI 有一个内置的贝塞尔曲线计算函数,学习使用内置库也永远不好。 你不会总是有 GDI 为你做事! 在某个地方,某个时候,你可能不得不实现它,我想到现在,你应该对这些曲线的工作原理有一个大致的了解了。

© . All rights reserved.