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;(x0, y0) 是開始點,(x2, y2) 是結束點,(xc, yc) 是控制點,而 (x1, y1) 則是曲線會經過的某點。yc = y1 * 2 - (y0 + y2) / 2;
繼續剛才的3點畫線,我們可以把第二個點當作點(x1, y1),於是
如果有4個點呢?這裡需要總結乙個演算法,先看乙個圖:
首先宣告一下,這張圖原本不是用來解釋本文的,我從別處截來,但是可以講解我想說的東西。
這條曲線很平滑,注意中間的兩個黑點,他倆都是相鄰控制點的中點,於是我得出了以下結論:
通過第乙個控制點,迴圈算出之後的控制點,相鄰的兩個控制點的中點是曲線會經過的點。仔細看3個點的例子,我們算出了控制點,它就是第乙個控制點。
第二個控制點怎麼算呢?
我們知道曲線會經過p2,所以 p2 是第乙個控制點 和 第二個控制點的中點,於是
// (ctrlx, ctrly) 是第乙個控制點之後的控制點都可以這樣計算,下面我給出一段演算法:ctrlx = 2 * x2 - ctrlx;
ctrly = 2 * y2 - ctrly;
/**最後看乙個經過6個點的曲線吧* @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();
}
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...