三次贝塞尔曲线关于点与长度在C++中实现:

三阶贝塞尔曲线只能计算近似解,由于使用时对长度的精度要求不高,因此用博客
【Unity】贝塞尔曲线关于点、长度、切线计算在 Unity中的C#实现
中提供的C#方法改写为C++的,只是替换了一个结构体,因为并不懂原文中的Vector3类的使用而已。

  • 定义一个POINT结构体,用于后面计算:
typedef struct
  {
    double x, y;
  } POINT;
  • 定义一个三阶贝塞尔曲线函数,t的范围在[0,1];
  • 输入P0, P1, P2, P3,分别为起始点,控制1点,控制2点,终止点;
    在这里插入图片描述
  • 返回POINT类型,也就是贝塞尔曲线上的点
POINT BezierPoint(double t, POINT p0, POINT p1, POINT p2, POINT p3)
{
    double u = 1 - t;
    double tt = t * t;
    double uu = u * u;
    double uuu = uu * u;
    double ttt = tt * t;

    POINT p;
    p.x = uuu * p0.x;
    p.y = uuu * p0.y;

    p.x += 3 * uu * t * p1.x;
    p.y += 3 * uu * t * p1.y;

    p.x += 3 * u * tt * p2.x;
    p.y += 3 * u * tt * p2.y;

    p.x += ttt * p3.x;
    p.y += ttt * p3.y;

    return p;
}
  • 把当前贝塞尔曲线切割N等份,计算每一段的欧氏距离,累加之后得到近似值,N越大越近似;
  • 计算三阶贝塞尔曲线的长度;
double getBezier_length(POINT p0, POINT p1, POINT p2, POINT p3, int pointCount)
{
    //取点 默认 30个
    pointCount = 30;
    double length = 0.0;
    POINT lastPoint = BezierPoint(0.0 / (double)pointCount, p0, p1, p2, p3);
    for (int i = 1; i <= pointCount; i++)
    {
        POINT point = BezierPoint((doube)i / (double)pointCount, p0, p1, p2, p3);
        length += sqrt((point.x - lastPoint.x) * (point.x - lastPoint.x) + (point.y - lastPoint.y) * (point.y - lastPoint.y));
        lastPoint = point;
    }
    return length;
}

猜你喜欢

转载自blog.csdn.net/subiluo/article/details/83626144