Qt 繪製平滑Bezier曲線

2021-10-03 01:13:01 字數 2695 閱讀 4312

1、二階bezier

static qpointf quadvalue

(const qpointf& p0,

const qpointf& p1,

const qpointf& p2, qreal t)

static qpointf quadderived

(const qpointf& p0,

const qpointf& p1,

const qpointf& p2, qreal t)

2、三階bezier

static qpointf cubicvalue

(const qpointf& p0,

const qpointf& p1,

const qpointf& p2,

const qpointf& p3, qreal t)

static qpointf cubicderived

(const qpointf& p0,

const qpointf& p1,

const qpointf& p2,

const qpointf& p3, qreal t)

如果不考慮對平滑的要求,那麼繪製時,只需要將t在[0,1]區間分成n段,逐段繪製即可。

static

void

createquadpoints

(qvector

& points,

const qpointf& from,

const qpointf& ctrl,

const qpointf& to)

}

採用上面的做法,會存在乙個問題:應該分成多少段?

如果分段過少,那麼就會有明顯的』不平滑『現象

如果分段過多,那麼就會嚴重影響效能,而且只要曲線足夠長,仍然有可能出現』不平滑『現象

我們可以這樣解決問題:保證每段與所處位置切線夾角小於或等於某個閾值θ

\theta

θ0、初始狀態:只有曲線的兩個端點,t的範圍為[0,

1]

[0, 1]

[0,1

],在t=0.5處插入1個點

1、在t範圍為[l,

r]

[l, r]

[l,r

]的段上,求t

0t_0

t0​處曲線上的點,插入到結果中,並將範圍分成[l,

t0

][l, t_0]

[l,t0​

]和[t0,

r]

[t_0, r]

[t0​,r

]兩段,記第一段為s

0s_0

s0​,第二段為s

1s_1

s1​2、求t

0t_0

t0​處的切線

3、求段s

0s_0

s0​與切線的夾角,如果夾角大於閾值θ

\theta

θ,那麼對段s

0s_0

s0​遞迴執行操作1

4、求段s

1s_1

s1​與切線的夾角,如果夾角大於閾值θ

\theta

θ,那麼對段s

1s_1

s1​遞迴執行操作1

static

void

createcubicpoints

(qlinkedlist

& points, qlinkedlist

::iterator iter,

const qpointf& from,

const qpointf& c1,

const qpointf& c2,

const qpointf& to, qreal t,

qreal fromt, qreal tot)

// 右邊

auto p1 =

*(iter+1)

;auto v1 = p1 - point;

auto deg1 =

degreebetween

(v1, derived);if

(deg1 > threshold)

}static

void

createcubicpoints

(qvector

& points,

const qpointf& from,

const qpointf& c1,

const qpointf& c2,

const qpointf& to)

;// 在[0, 1]之間的0.5處插入1個點

createcubicpoints

(tmppoints, tmppoints.

begin()

+1, from, c1, c2, to,

0.5,0,

1);for

(const

auto

& p : tmppoints)

}

// 繪製相關**

// points就是上面方法中產生的points

painter-

>

drawpolyline

(&points[0]

, points.

size()

);

Bezier曲線繪製方法

de casteljau演算法能簡單快速地求出某個t值的曲線值,複雜度是o n 2 的乘法與加法。這裡平方級的計算感覺比較慢,如果應用秦九韶演算法來求該多項式值的話,複雜度降低到了o n 難度是因為數值穩定性的原因?而如果是繪製一條曲線的話,如果要用m個等間距的點來逼近這條曲線的話,複雜度是o m ...

繪製貝塞爾Bezier曲線

trainingtools.cpp 定義控制台應用程式的入口點。include include include include include include using namespace std const int ww max mark count 40 最大40個控制點 int mark c...

OpenGL繪製Bezier曲線的方法

專案要求 使用滑鼠在螢幕中任意設定控制點,並生成曲線 使用滑鼠和鍵盤的互動操作實現對曲線的修改。專案總體介紹 本專案利用bezier曲線生成演算法生成可由使用者自定義的曲線。可實現核心功能如下 1 使用者用滑鼠左擊螢幕任意處產生記錄點。2 滑鼠右擊螢幕任意處由先前的任意個數記錄點和其先後關係生成be...