什么是貝塞爾曲線
貝塞爾曲線,又稱貝茲曲線或貝濟埃曲線,是應(yīng)用于二維圖形應(yīng)用程序的數(shù)學(xué)曲線。一般的矢量圖形軟件通過它來精確畫出曲線,貝茲曲線由線段與節(jié)點組成,節(jié)點是可拖動的支點,線段像可伸縮的皮筋,我們在繪圖工具上看到的鋼筆工具就是來做這種矢量曲線的。貝塞爾曲線是計算機圖形學(xué)中相當(dāng)重要的參數(shù)曲線。
通過控制曲線上的四個點(起始點、終止點以及兩個相互分離的中間點)來創(chuàng)造、編輯圖形。其中起重要作用的是位于曲線中央的控制線。這條線是虛擬的,中間與貝塞爾曲線交叉,兩端是控制端點。移動兩端的端點時貝塞爾曲線改變曲線的曲率(彎曲的程度);移動中間點(也就是移動虛擬的控制線)時,貝塞爾曲線在起始點和終止點鎖定的情況下做均勻移動。
以上是百科上面的一些介紹,大部分人看完一頭霧水。那么到底什么是貝塞爾曲線呢?簡單的說貝塞爾曲線通過控制曲線上的起始點、終止點以及中間的控制點來生成曲線的路徑。貝塞爾曲線又分為一階曲線、二階曲線、三階曲線和高階曲線。
下面我們用幾張gif圖來行進(jìn)一步說明:
- 一階曲線:
一階曲線本質(zhì)是一個線段,只有起始點和終止點兩個點組成。
- 二階曲線:
二階曲線,二階曲線由三個點組成,即首尾兩個點加一個控制點,二階曲線其實是一條拋物線。
- 三階曲線:
- 高階曲線:
說明:gif動圖來源于網(wǎng)絡(luò)
貝塞爾曲線在iOS中的應(yīng)用
貝塞爾曲線在iOS中有一個對應(yīng)的類,叫做UIBezierPath,UIBezierPath是Core Graphics框架關(guān)于路徑的封裝,我們可以根據(jù)它,畫出直線、橢圓、圓、曲線等各種形狀。
UIBezierPath通常與CAShapeLayer配合使用。CAShapeLayer繼承自CALayer,它擁有CALayer的所有屬性。UIBezierPath為CAShapeLayer提供路徑, CAShapeLayer在提供的路徑中進(jìn)行渲染, 繪制出圖形。
- 一階曲線:
我們用一階曲線畫一個三角形:
let path = UIBezierPath()
//三角形頂點1
path.move(to: CGPoint(x: 100, y: 100))
//三角形頂點2
path.addLine(to: CGPoint(x: view.frame.width - 40, y: 100))
//三角形頂點3
path.addLine(to: CGPoint(x: 100, y: 200))
//path閉合
path.close()
//線寬
path.lineWidth = 2
let shape = CAShapeLayer()
//邊線顏色
shape.strokeColor = UIColor.blue.cgColor
//填充色
shape.fillColor = UIColor.white.cgColor
shape.path = path.cgPath
view.layer.addSublayer(shape)
設(shè)置三角形頂點,然后把path閉合,形成一個三角形
效果圖:
畫圓:
let path = UIBezierPath(ovalIn: CGRect(x: 100, y: 100, width: 100, height: 100))
let shape = CAShapeLayer()
//邊線顏色
shape.strokeColor = UIColor.blue.cgColor
//填充色
shape.fillColor = UIColor.white.cgColor
shape.path = path.cgPath
view.layer.addSublayer(shape)
效果圖:
- 二階曲線:
利用二階曲線,畫一個拋物線
let path = UIBezierPath()
path.lineCapStyle = .round
path.lineJoinStyle = .round
path.move(to: CGPoint(x: 100, y: 200))
//第一個參數(shù)point為path終點坐標(biāo),第二個point參數(shù)為切點坐標(biāo)
path.addQuadCurve(to: CGPoint(x: 300, y: 200), controlPoint: CGPoint(x: 300, y: 100))
let shape = CAShapeLayer()
//邊線顏色
shape.strokeColor = UIColor.blue.cgColor
//填充色
shape.fillColor = UIColor.white.cgColor
shape.path = path.cgPath
view.layer.addSublayer(shape)
效果圖:
- 三階曲線:
let path = UIBezierPath()
path.lineCapStyle = .round
path.lineJoinStyle = .round
path.move(to: CGPoint(x: 100, y: 200))
//第一個參數(shù)point為path終點坐標(biāo),第二個和第三個point參數(shù)為控制點坐標(biāo)
path.addCurve(to: CGPoint(x: view.frame.width - 20, y: 200), controlPoint1: CGPoint(x: 200, y: 100), controlPoint2: CGPoint(x: 300, y: 300))
let shape = CAShapeLayer()
//邊線顏色
shape.strokeColor = UIColor.blue.cgColor
//填充色
shape.fillColor = UIColor.white.cgColor
shape.path = path.cgPath
view.layer.addSublayer(shape)
效果圖:
- 高階曲線:
UIBezierPath最多提供了三階曲線,如果我們想實現(xiàn)高階曲線怎么辦呢,這個時候我們可以多次設(shè)置path的起點以及控制點,如下代碼:
let path = UIBezierPath()
path.lineCapStyle = .round
path.lineJoinStyle = .miter
path.move(to: CGPoint(x: 10, y: 200))
//第一個參數(shù)point為path終點坐標(biāo),第二個和第三個point參數(shù)為控制點坐標(biāo)
path.addCurve(to: CGPoint(x: 200, y: 200), controlPoint1: CGPoint(x: 100, y: 100), controlPoint2: CGPoint(x: 200, y: 300))
//第二次設(shè)置起始點及控制點
path.move(to: CGPoint(x: 200, y: 200))
path.addCurve(to: CGPoint(x: view.frame.width - 20, y: 300), controlPoint1: CGPoint(x: 200, y: 100), controlPoint2: CGPoint(x: 400, y: 200))
let shape = CAShapeLayer()
//邊線顏色
shape.strokeColor = UIColor.blue.cgColor
//填充色
shape.fillColor = UIColor.white.cgColor
shape.path = path.cgPath
view.layer.addSublayer(shape)
效果圖:
注:UIBezierPath的控制點并非曲線頂點,可參考上面動圖展示
本文首發(fā)于公眾號【一個老碼農(nóng)】