Bezier曲線的原理Bezier曲線是應(yīng)用于二維圖形的曲線。曲線由頂點(diǎn)和控制點(diǎn)組成,通過(guò)改變控制點(diǎn)坐標(biāo)可以改變曲線的形狀。 一次Bezier曲線公式: 一次Bezier曲線是由P0至P1的連續(xù)點(diǎn),描述的一條線段 二次Bezier曲線公式: 二次Bezier曲線是 P0至P1 的連續(xù)點(diǎn)Q0和P1至P2 的連續(xù)點(diǎn)Q1 組成的線段上的連續(xù)點(diǎn)B(t),描述一條拋物線。 三次Bezier曲線公式: 二次Bezier曲線的實(shí)現(xiàn)#include <vector>class CBezierCurve {public: CBezierCurve();~CBezierCurve();void SetCtrlPoint(POINT& stPt);bool CreateCurve();void Draw(CDC* pDC); private:// 主要算法,計(jì)算曲線各個(gè)點(diǎn)坐標(biāo)void CalCurvePoint(float t, POINT& stPt);private:// 頂點(diǎn)和控制點(diǎn)數(shù)組std::vector<POINT> m_vecCtrlPt;// 曲線上各點(diǎn)坐標(biāo)數(shù)組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個(gè)頂點(diǎn)一個(gè)控制點(diǎn) assert(m_vecCtrlPt.size() == 3); // t的增量, 可以通過(guò)setp大小確定需要保存的曲線上點(diǎn)的個(gè)數(shù) 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) { // 畫出曲線上個(gè)點(diǎn),若不連續(xù)可以用直線連接各點(diǎn) 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個(gè)頂點(diǎn)一個(gè)控制點(diǎn) assert(m_vecCtrlPt.size() == 3); // 計(jì)算曲線點(diǎn)坐標(biāo),此為2次算法,改變此處可以實(shí)現(xiàn)多次曲線 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; } |
|
來(lái)自: felwell > 《智能機(jī)器人開(kāi)發(fā)》