1. 程式人生 > >三次貝塞爾曲線關於點與長度在C++中實現:

三次貝塞爾曲線關於點與長度在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; }