Bezier曲線的原理Bezier曲線是應用于二維圖形的曲線。曲線由頂點和控制點組成,通過改變控制點坐標可以改變曲線的形狀。 一次Bezier曲線公式: 一次Bezier曲線是由P0至P1的連續點,描述的一條線段 二次Bezier曲線公式: 二次Bezier曲線是 P0至P1 的連續點Q0和P1至P2 的連續點Q1 組成的線段上的連續點B(t),描述一條拋物線。 三次Bezier曲線公式: 二次Bezier曲線的實現#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; } |
|