貝塞爾曲線

2021-07-11 17:40:32 字數 4384 閱讀 7205

貝塞爾曲線在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走...