Bezier曲線是應用於二維圖形的曲線。曲線由頂點和控制點組成,經過改變控制點座標能夠改變曲線的形狀。算法
一次Bezier曲線公式:數組
一次Bezier曲線是由P0至P1的連續點,描述的一條線段spa
二次Bezier曲線公式:3d
二次Bezier曲線是 P0至P1 的連續點Q0和P1至P2 的連續點Q1 組成的線段上的連續點B(t),描述一條拋物線。code
三次Bezier曲線公式:blog
#include <vector> class CBezierCurve { public: CBezierCurve(); ~CBezierCurve(); void SetCtrlPoint(POINT& stPt); bool CreateCurve(); void Draw(CDC* pDC); private: // 主要算法,計算曲線各個點座標 void CalCurvePoint(float t, POINT& stPt); private: // 頂點和控制點數組 std::vector<POINT> m_vecCtrlPt; // 曲線上各點座標數組 std::vector<POINT> m_vecCurvePt; };
#include <math.h> #include "BezierCurve.h" CBezierCurve::CBezierCurve() { } CBezierCurve::~CBezierCurve() { } void CBezierCurve::SetCtrlPoint(POINT& stPt) { m_vecCtrlPt.push_back(stPt); } void CBezierCurve::CreateCurve() { // 確保是二次曲線,2個頂點一個控制點 assert(m_vecCtrlPt.size() == 3); // t的增量, 能夠經過setp大小肯定須要保存的曲線上點的個數 float step = 0.01; for (float t = 0.0; t <= 1.0; t += step) { POINT stPt; CalCurvePoint(t, stPt); m_vecCurvePt.push_back(stPt); } } void CBezierCurve::Draw(CDC* pDC) { // 畫出曲線上個點,若不連續能夠用直線鏈接各點 int nCount = m_vecCurvePt.size(); for (int i = 0; i < nCount; ++i) { pDC->SetPixel(m_vecCurvePt[i], 0x000000); } } void CBezierCurve::CalCurvePoint(float t, POINT& stPt) { // 確保是二次曲線,2個頂點一個控制點 assert(m_vecCtrlPt.size() == 3); // 計算曲線點座標,此爲2次算法,改變此處能夠實現屢次曲線 float x = (float)m_vecCtrlPt[0].x * pow(1 - t, 2) + (float)m_vecCtrlPt[1].x * t * (1 - t) * 2 + (float)m_vecCtrlPt[2].x * pow(t, 2); float y = (float)m_vecCtrlPt[0].y * pow(1 - t, 2) + (float)m_vecCtrlPt[1].y * t * (1 - t) * 2 + (float)m_vecCtrlPt[2].y * pow(t, 2); stPt.x =x; stPt.y= y; }