貝塞爾曲線在android中運用廣泛,可以用來繪製各類複雜曲線,因為貝塞爾曲線只需要指定控制點,就能繪製出特定的曲線。其次是做點和點的平滑過渡。為什麼可以做到如上兩點,看下面的講解:
首先來說,貝塞爾曲線有階的概念,這個階可以理解為控制點,一階的控制點只有兩個。如上是一階的方程,其中t取值為0到1,可以理解為時間,從開始到結束。**如下:
圖中可以看到,點隨著t的變化從p0到p1運動,一階的貝塞爾其實就是一條直線。
那麼二階又是如何呢:
方程如上,可以通過一階方程推導出來,這裡不做演算,看看**:
**中可以看到,有3個控制點。在控制點p0到p1之間有乙個點隨著t變化而運動,在p1到p2之間也有點隨著變動,他們兩個點遵循一階方程,而兩個點的連線上又有乙個點隨著t運動,這個點也遵循一階方程,所以可以推導出上訴方程。
再來看看三階方程和**:
接下來是四階和五階的貝塞爾曲線**:
從上面的圖中可以看出:
1. 貝塞爾曲線,可以由控制點來控制曲線的走勢。
1. 拐點處,曲線可以平滑過渡
由以上兩點結論,可以看出,貝塞爾曲線可以用來方便簡單的繪製各類曲線,同時,可以用於平滑處理拐點。後面將講解示例。
//二階
public void quadto(float x1, float y1, float x2, float y2)
public void rquadto(float dx1, float dy1, float dx2, float dy2)
//三階
public void cubicto(float x1, float y1, float x2, float y2,float x3, float y3)
public void rcubicto(float x1, float y1, float x2, float y2,float x3, float y3)
在path類中有如上四個方法是有關於貝塞爾曲線的,其中前面兩個是二階,後面兩個是三階。
這裡quadto以及cubicto方法都是直接接收控制點的座標,而rquadto以及rcubicto接收的是相對座標,即相對上乙個控制點的相對座標
例如:
path.moveto(100,300);
path.rquadto(100,-100,200,0);
path.rquadto(100,100,200,0);
等價於
path.moveto(100,300);
path.quadto(200,200,300,300);
path.quadto(400,400,500,300);
假設我們有四個個資料點,需要繪製出他們組成的連線,資料點資料為,。那麼繪製出來的結果如下:
這就是四個點依次連線所組成的連線,看起來是沒有問題的。如果,這裡有乙個需求,需要將這個折線變成平滑的曲線,那麼我們應該怎麼做呢。從上面講解的知識知道,折線的過渡,可以使用貝塞爾曲線。
貝塞爾曲線的核心在於找到合適的控制點,因為控制點中,曲線一定會經過首尾兩個點,那麼圖中的四個點,應該分別為首尾控制點。
先看一下最終繪製的曲線:
看起來確實平滑了,這四個紅色的點就是上面的資料點,根據上面的結論,要讓曲線經過他們,他們必須相鄰的兩個點為首尾控制點,那麼這裡使用幾階的貝塞爾合適呢。
我們以第二和第三兩個點作為入手點(因為任意兩個點是控制點的首尾,屬於同一組控制點),要讓曲線從點1平滑過渡到點2,再從點3平滑過渡到點四,那麼這曲線的走勢必然要受到點1,點4的影響,也就是說,兩個相鄰資料點之間的曲線走勢,不僅受到自己的所在位置的影響,還受到前後兩點的影響,加起來其實影響這段曲線走勢的就有四個點。那麼可以推斷出來,四個點的貝塞爾曲線,當然是三階曲線。
那麼既然相鄰兩個資料點是控制點的首尾點,那麼另外兩個控制點又該如何求得呢,從上面的分析可以知道,另外兩個控制點,是為了控制曲線的走勢。我們先來完整控制點的圖:
圖中綠色的為控制點,紅色的為資料點,每個資料點實際上也是控制點之一(只是首尾點),因此資料點既有紅色也有綠色。可以看到點2和點3之間的兩個控制點,乙個靠近點2,乙個靠近點3,靠近點2的控制點比點2高,靠近點3的控制點也比點3高,這是為什麼呢。
先看上圖,將靠近點2和點3的兩個控制點分別標識為點a,和點b。
現在的問題在於,如何求的點a和點b的座標。
點a,點b作為資料點2,和3之間的控制點,他們的作用,其實是為了體現前後資料點的連線趨勢。先來看點a,點a要起到的作用就是要順利的讓資料點2平滑的過渡從資料點1來的曲線,並且要將曲線平滑的過渡到資料點3,那麼點a相關的點就應該有資料點1,資料點2,以及資料點3。也就是說,點a的值應該由這3個點求出。同理,點b也會由他臨近的資料點,以及該資料點前面的資料點和後面的資料點求得。也就是資料點3,資料點2,資料點4求得。
**如下:
final float line_smoothness = 0.2f;
final float firstdiffx = (currentpointx - prepreviouspointx);
final float firstdiffy = (currentpointy - prepreviouspointy);
final float seconddiffx = (nextpointx - previouspointx);
final float seconddiffy = (nextpointy - previouspointy);
final float firstcontrolpointx = previouspointx + (line_smoothness * firstdiffx);
final float firstcontrolpointy = previouspointy + (line_smoothness * firstdiffy);
final float secondcontrolpointx = currentpointx - (line_smoothness * seconddiffx);
final float secondcontrolpointy = currentpointy - (line_smoothness * seconddiffy);
path.cubicto(firstcontrolpointx, firstcontrolpointy, secondcontrolpointx, secondcontrolpointy,currentpointx, currentpointy);
**中,最後的path.cubicto就是呼叫了四階貝塞爾曲線的方法。其中firstcontrolpointx對應的是點a的x座標,secondcontrolpointx對應的是點b的x座標,currentpointx對應資料點3的x座標。previouspointx對應了前乙個資料點也就是資料點2的x座標,prepreviouspointx對應了資料點1,nextpointx對應了資料點4。
以上的**可以看出,點a,點b的相關點與我們之前分析的一致。那麼這裡除了這些數值以外,還有乙個變數line_smoothness,這個是做什麼的呢。從它的名字可以看出,他是調整曲線的平滑程度的,值變化會引起控制點a,b的變化,從而影響曲線的形態。
final float line_smoothness = 0.4f;
來看看值調整為0.2,和0.4的對比曲線:左邊為0.2右邊為0.4,可以根據具體需求調整值 貝塞爾曲線
1.概述 貝塞爾曲線 b zier curve 又稱 貝茲曲線或貝濟埃曲線,是應用於二維圖形應用程式的數學曲線。一般的向量圖形 軟體通過它來精確畫出曲線,貝茲曲線由 線段與節點組成,節點是可拖動的支點,線段像可伸縮的皮筋,我們在繪圖工具上看到的鋼筆工具就是來做這種向量曲線的。貝塞爾曲線是計算機圖形學...
貝塞爾曲線
由於工作需要,最近在研究乙個類似qq訊息劃掉的效果 很多強迫症患者童鞋對這個簡直是愛不釋手,當然這個也包括我自己 貝塞爾曲線就是這樣的一條曲線,它是依據四個位置任意的點座標繪製出的一條 光滑曲線 在歷史上,研究貝塞爾曲線的人最初是按照已知曲線 引數方程 來確定四個點的思路設計出這種向量曲線繪製法。貝...
貝塞爾曲線
給定點p0 p1,線性貝茲曲線只是一條兩點之間的直線。這條線由下式給出 且其等同於線性插值。二次方貝茲曲線的路徑由給定點p0 p1 p2的函式b t 追蹤 truetype字型就運用了以貝茲樣條組成的二次貝茲曲線。p0 p1 p2 p3四個點在平面或在三維空間中定義了三次方貝茲曲線。曲線起始於p0走...