平滑多條曲線

2022-07-05 06:33:10 字數 1866 閱讀 8088

canvas 畫曲線(非圓弧)有兩個方法:

1. quadraticcurveto(cpx, cpy, x, y)

2. beziercurveto(cp1x, cp1y, cp2x, cp2y, x, y)

本文只講quadraticcurveto(),先來看如何畫一條曲線。

我們需要曲線的 開始點(p0) 和 結束點(p1),外加乙個控制點(pc),雖然說有3個點,但實際畫圖時,我們關心的只是開始點和結束點

可以看到曲線經過 p0 和 p1 兩個點,控制點pc 只是用來調整曲線的形狀的。

如果曲線要經過3個點呢?不好做了吧?

這裡介紹乙個公式,從上圖可知,曲線不經過控制點,但曲線肯定會經過某個點,這個點怎麼求呢?

xc = x1 * 2 - (x0 + x2) / 2; 

yc = y1 * 2 - (y0 + y2) / 2;

(x0, y0) 是開始點,(x2, y2) 是結束點,(xc, yc) 是控制點,而 (x1, y1) 則是曲線會經過的某點。

繼續剛才的3點畫線,我們可以把第二個點當作點(x1, y1),於是

如果有4個點呢?這裡需要總結乙個演算法,先看乙個圖:

首先宣告一下,這張圖原本不是用來解釋本文的,我從別處截來,但是可以講解我想說的東西。

這條曲線很平滑,注意中間的兩個黑點,他倆都是相鄰控制點的中點,於是我得出了以下結論:

通過第乙個控制點,迴圈算出之後的控制點,相鄰的兩個控制點的中點是曲線會經過的點。

仔細看3個點的例子,我們算出了控制點,它就是第乙個控制點。

第二個控制點怎麼算呢?

我們知道曲線會經過p2,所以 p2 是第乙個控制點 和 第二個控制點的中點,於是

// (ctrlx, ctrly) 是第乙個控制點

ctrlx = 2 * x2 - ctrlx;

ctrly = 2 * y2 - ctrly;

之後的控制點都可以這樣計算,下面我給出一段演算法:

/**

* @param c 即canvas.getcontext('2d')

* @param points 陣列元素格式為

*/function drawmultiplecurves(c, points)

// 計算第乙個控制點

var ctrlx = 2 * points[1].x - 0.5 * (points[0].x + points[2].x);

ctrly = 2 * points[1].y - 0.5 * (points[0].y + points[2].y);

// 畫出前三個點的曲線

c.beginpath();

c.moveto(points[0].x, points[0].y);

c.quadraticcurveto(ctrlx, ctrly, points[2].x, points[2].y);

if (len === 3)

for (var i = 2; i < len - 1; i++)

c.stroke();

}

最後看乙個經過6個點的曲線吧

Qt畫平滑曲線

初學qt繪圖,使用drawling 繪製的直線在兩端點間距離較小時總是出現折點 鋸齒 非常不美觀。後來發現使用qpainter setrenderhint qpainter antialiasing 能消除鋸齒。setrenderhint用於設定呈現樣式,antialiasing是反鋸齒。例 qpa...

畫平滑的roc曲線

使用matlab畫roc曲線 本來malab曲線的平滑有2種方法 clc,clear a 1 1 6 橫座標 b 8.0 9.0 10.0 15.0 35.0 40.0 縱座標 plot a,b,b 自然狀態的畫圖效果 hold on 第一種,畫平滑曲線的方法 c polyfit a,b,2 進行擬...

Qt 繪製平滑Bezier曲線

1 二階bezier static qpointf quadvalue const qpointf p0,const qpointf p1,const qpointf p2,qreal t static qpointf quadderived const qpointf p0,const qpoin...