三次貝塞爾曲線關於點與長度在C++中實現:
阿新 • • 發佈:2018-11-06
三階貝塞爾曲線只能計算近似解,由於使用時對長度的精度要求不高,因此用部落格
【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;
}