由一组基点描述的曲线(样条曲线,贝塞尔曲线路径等)

时间:2013-05-15 18:37:26

标签: algorithm computational-geometry

作为输入,我设置了“基点”(例如9点),作为输出,我必须返回另一组描述曲线的点。

A1-A9是输入;这些是“基础”点。我的任务是返回一组点,用户可以从中构建描绘的曲线,A1-A9的黑线

Puzzle piece

我的数学技能很低,谷歌搜索并不是很有帮助。据我所知,这可以是一个三次样条。我找到了一些基于C的源代码,但是当我尝试构建样条曲线部分时,这段代码无休止地循环,nextPoint.x < currentPoint.x

请解释一下,我应该为我的任务使用什么样的样条曲线,bezier路径或其他结构。如果你指的是代码,算法或傻瓜的好手册,那将是非常好的。

3 个答案:

答案 0 :(得分:1)

使用Interpolation methods生成曲线上的中间点。

例如,给定CubicInterpolate函数:

double CubicInterpolate(
   double y0,double y1,
   double y2,double y3,
   double mu)
{
   double a0,a1,a2,a3,mu2;

   mu2 = mu*mu;
   a0 = y3 - y2 - y0 + y1;
   a1 = y0 - y1 - a0;
   a2 = y2 - y0;
   a3 = y1;

   return(a0*mu*mu2+a1*mu2+a2*mu+a3);
}

要在三次样条曲线上找到point[1]point[2]之间的点,您可以使用:

newPoint.X = CubicInterpolate(point[0].X, point[1].X, point[2].X, point[3].X, 0.5);
newPoint.Y = CubicInterpolate(point[0].Y, point[1].Y, point[2].Y, point[3].Y, 0.5);

point[0]point[3]会影响point[1]point[2]之间的曲线部分。在曲线的任一端,只需再次使用终点。

为了确保点之间的距离大致相等,您可以计算输入点之间的距离,以确定要生成多少个中间点(和mu值)。因此,对于相距较远的点,您可以在mu0之间使用更多1个值。相反,对于非常接近的点,您可能根本不需要添加中间点。

答案 1 :(得分:0)

谢谢大家。我找到了解决方案。对于按基本点构建2D曲线,我遵循:
我找到了this关于C ++和C#示例的三次样条的文章。此示例允许通过基点查找“一维”三次样条的插值。因为我需要一个二维三次样条 - 我创建两个一维样条 - 用于'x'和'y'轴。接下来,接下来,我从第一个点到终点运行一个循环,并且在循环的每个迭代中我找到了插值。从插值中我得到了一个观点。所以,当循环结束时,我会得到一条曲线。

伪代码(使用上面文章中提到的spline类):

- (array*)splineByBasePoints:(array*)basePoints
{
    int n = basePoints.count;
    cubic_spline xSpline, ySpline;
    xSpline.build_spline(basePoints.pointNumbers, basePoints.XValuesOfPoints, n);
    ySpline.build_spline(basePoints.pointNumbers, basePoints.YValuesOfPoints, n);
    array curve;
    int t = 1; //t - intermediate point. '1' because number of point, not index

    for (; t <= n; t += step)
    {
        [curve addToArray:PontWithXY([xSpline f:t], [ySpline f:t])];
    }
    return array;
}

答案 2 :(得分:0)

如果您有MATLAB许可证,

x = -4:4;
y = [0 .15 1.12 2.36 2.36 1.46 .49 .06 0];
cs = spline(x,[0 y 0]);
xx = linspace(-4,4,101);
y=ppval(cs,xx);