绘制简单贝塞尔曲线的中点算法(分治法)






4.79/5 (19投票s)
一个简单的程序,帮助理解用于构建贝塞尔曲线的中点算法。
引言
贝塞尔曲线是一种参数曲线,常用于计算机图形学及相关领域。在矢量图形中,贝塞尔曲线用于建模可无限缩放的平滑曲线。构建贝塞尔曲线的方法有很多种。这个简单的程序使用中点算法来构建贝塞尔曲线。为了展示算法中分治法的特性,使用递归函数来实现贝塞尔曲线片段的构造。
构建贝塞尔曲线
该程序基于三个可以手动调整的点来构建贝塞尔曲线。下面的动画展示了在代码中,我们用两次中点法迭代构建贝塞尔曲线时究竟发生了什么。
以红色显示的这些点是初始点。在给出初始点之后,它会计算位于三个初始点之间的每条线的中间点。这些新计算的中间点以绿色显示。将颜色变为蓝色的点将在最终的贝塞尔曲线上。颜色变化的顺序与代码中计算贝塞尔曲线点的顺序相同。使用给定的点和两次迭代近似的贝塞尔曲线由一组红色的直线表示。
Using the Code
类
- 类
BezierCurve
:负责构建贝塞尔曲线的类。 - 类
CustomCanvas
:负责曲线的图形视图和点操作的类。
函数
private void CreateBezier(PointF ctrl1, PointF ctrl2, PointF ctrl3)
{
bezierPoints = new List<PointF>();
bezierPoints.Clear();
bezierPoints.Add(ctrl1); // add the first control point
PopulateBezierPoints(ctrl1, ctrl2, ctrl3, 0);
bezierPoints.Add(ctrl3);// add the last control point
}
此函数将三个点作为参数,然后填充曲线的点列表。点 ctrl1
(曲线的起始端点) 显然在曲线上,因此将其添加到列表中,无需任何计算。然后它调用函数 PopulateBezierPoints
来计算曲线上其余的点。最后,点 ctrl3
被添加到列表中,因为它显然是曲线的另一端点。
private void PopulateBezierPoints(PointF ctrl1, PointF ctrl2,
PointF ctrl3, int currentIteration)
{
if (currentIteration < iterations)
{
//calculate next mid points
PointF midPoint1 = MidPoint(ctrl1, ctrl2);
PointF midPoint2 = MidPoint(ctrl2, ctrl3);
PointF midPoint3 = MidPoint(midPoint1, midPoint2);
//the next control point
currentIteration++;
PopulateBezierPoints(ctrl1, midPoint1,
midPoint3, currentIteration);//left branch
bezierPoints.Add(midPoint3);
//add the next control point
PopulateBezierPoints(midPoint3, midPoint2, ctrl3, currentIteration);
//right branch
}
}
此函数将三个初始点与参数 currentIteration
一起作为参数。该函数是递归调用的,在开始时,当前迭代次数为零。在调用此函数之前,应设置算法中的迭代次数。
此函数简单地获取前两个点的中点、后两个点的中点 (来自给定的三个点),以及上面两个新中点的中点 (如果 currentIteration
小于算法中要迭代的 iterations
次数(变量 iterations
的值是用户从用户界面中选择的值)。在计算了三个新的中点后,我们得到了一对三个点。这对点中的一组点用于构造曲线的左半部分,另一组点用于构造曲线的右半部分。根据调用此递归函数的顺序,它将点按从曲线的左半部分到右半部分的顺序添加到列表中。您可以参考上面的动画来更好地了解此函数的执行顺序。
private PointF MidPoint(PointF controlPoint1, PointF controlPoint2)
{
return new PointF(
(controlPoint1.X + controlPoint2.X) / 2,
(controlPoint1.Y + controlPoint2.Y) / 2
);
}
此函数将两个点作为参数,并返回它们的中点。
如何使用
该程序允许您指定三个初始点和迭代次数。然后您可以观察贝塞尔曲线的平滑度和点数。除此之外,您可以通过拖动初始点来移动它们。
备注
当曲线变得更复杂、更平滑时,使用递归函数来构建贝塞尔曲线是不切实际的。在这种情况下,我们必须使用一些有效的方法来构建贝塞尔曲线。