UIBezierPath(貝塞爾曲線)

引言:

UIBezierPath類只是CGPathRef數(shù)據(jù)類型和path繪圖屬性的一個(gè)封裝。

參考:

貝塞爾曲線

貝塞爾曲線(UIBezierPath)屬性、方法匯總

摘要:
1.一般的矢量圖形軟件通過它來精確畫出曲線,貝茲曲線由線段與節(jié)點(diǎn)組成,節(jié)點(diǎn)是可拖動(dòng)的支點(diǎn),線段像可伸縮的皮筋,我們在繪圖工具上看到的鋼筆工具就是來做這種矢量曲線的。

2.出現(xiàn)的原因:
由于用計(jì)算機(jī)畫圖大部分時(shí)間是操作鼠標(biāo)來掌握線條的路徑,與手繪的感覺和效果有很大的差別。即使是一位精明的畫師能輕松繪出各種圖形,拿到鼠標(biāo)想隨心所欲的畫圖也不是一件容易的事。這一點(diǎn)是計(jì)算機(jī)萬萬不能代替手工的工作,所以到目前為止人們只能頗感無奈。使用貝塞爾工具畫圖很大程度上彌補(bǔ)了這一缺憾。
貝塞爾曲線是計(jì)算機(jī)圖形圖像造型的基本工具,是圖形造型運(yùn)用得最多的基本線條之一。它通過控制曲線上的四個(gè)點(diǎn)(起始點(diǎn)、終止點(diǎn)以及兩個(gè)相互分離的中間點(diǎn))來創(chuàng)造、編輯圖形。


UIBezierPath類 介紹

說到底,就是直接用這個(gè)類來畫二維圖形,也是666


找到一篇很不錯(cuò)的博客

iOS之UI--CAShapeLayer

摘要出一部分,有空的話,看看全文比較好
ps:發(fā)現(xiàn)該作者的其它博客也很不錯(cuò),有空看看

1、CAShapeLayer繼承自CALayer,可以使用CALayer的所有屬性值
2、CAShapeLayer需要與貝塞爾曲線配合使用才有意義
3、使用CAShapeLayer與貝塞爾曲線可以實(shí)現(xiàn)不在view的drawRect方法中畫出有一些想要的圖形
4、CAShapeLayer屬于CoreAnimation框架,其動(dòng)畫渲染直接提交到手機(jī)的GPU當(dāng)中,相較于view的drawRect方法使用CPU渲染而言,其效率極高,能大大優(yōu)化內(nèi)存使用情況。
個(gè)人經(jīng)驗(yàn):可以重寫UIView的子類中的drawRect來實(shí)現(xiàn)進(jìn)度條效果,但是UIView的drawRect是用CPU渲染實(shí)現(xiàn)的,而使用CAShapeLayer效率更高,因?yàn)樗玫氖荊PU渲染。


創(chuàng)建的步驟:
(1)創(chuàng)建一個(gè)Bezier path對象(這沒什么好說的)
(2)使用方法moveToPoint:去設(shè)置初始線段的起點(diǎn)。這就不得不吐槽了,為什么是moveToPoint呢?這命名讓人感覺好像終點(diǎn)的樣子,假如改成moveFromPoint多好,能降低誤導(dǎo)概率

    [_path moveToPoint:CGPointMake(startX, startY)];

(3)添加line或者curve去定義一個(gè)或者多個(gè)subpaths。

line是直線段,curve是曲線段

//3.1三次貝塞爾曲線舉個(gè)例子:(三次和二次addQuadCurveToPoint,貌似咋一看最大的區(qū)別是能加三個(gè)還是兩個(gè)參數(shù))

    //三點(diǎn)曲線--讓小方塊的下滑線路
    [_path addCurveToPoint:CGPointMake(0, 600)/*終點(diǎn)*/ controlPoint1:CGPointMake(startX, startY) /*起點(diǎn)*/controlPoint2:CGPointMake(startX - 180, startY - 200)];/*中途點(diǎn)*/

//3.2直線繪制多邊形舉個(gè)例子:

多邊形是一些簡單的形狀,這些形狀是由一些直線線條組成,我們可以用moveToPoint: 和 addLineToPoint:方法去構(gòu)建
方法moveToPoint:設(shè)置我們想要?jiǎng)?chuàng)建形狀的起點(diǎn)。從這點(diǎn)開始,我們可以用方法addLineToPoint:去創(chuàng)建一個(gè)形狀的線段。
我們可以連續(xù)的創(chuàng)建line,每一個(gè)line的起點(diǎn)都是先前的終點(diǎn),終點(diǎn)就是指定的點(diǎn)。

下面的代碼描述了如何用線段去創(chuàng)建一個(gè)五邊形。第五條線通過調(diào)用closePath方法得到的,它連接了最后一個(gè)點(diǎn)(0,40)和第一個(gè)點(diǎn)(100,0)
說明:closePath方法不僅結(jié)束一個(gè)shape的subpath表述,它也在最后一個(gè)點(diǎn)和第一個(gè)點(diǎn)之間畫一條線段,如果我們畫多邊形的話,這個(gè)一個(gè)便利的方法我們不需要去畫最后一條線

//自定義view里面自定義繪制這個(gè)view
- (void)drawRect:(CGRect)rect  
{  
    UIColor *color = [UIColor redColor];  
    [color set]; //設(shè)置線條顏色  
      
    UIBezierPath* aPath = [UIBezierPath bezierPath];  
    aPath.lineWidth = 5.0;  
      
    aPath.lineCapStyle = kCGLineCapRound; //線條拐角  
    aPath.lineJoinStyle = kCGLineCapRound; //終點(diǎn)處理  
      
    // Set the starting point of the shape.  
    [aPath moveToPoint:CGPointMake(100.0, 0.0)];  
      
    // Draw the lines  
    [aPath addLineToPoint:CGPointMake(200.0, 40.0)];  
    [aPath addLineToPoint:CGPointMake(160, 140)];  
    [aPath addLineToPoint:CGPointMake(40.0, 140)];  
    [aPath addLineToPoint:CGPointMake(0.0, 40.0)];  
    [aPath closePath];//第五條線通過調(diào)用closePath方法得到的  
      
    [aPath stroke];//Draws line 根據(jù)坐標(biāo)點(diǎn)連線  
} 

至于繪制矩形(bezierPathWithRect)圓形/橢圓形(bezierPathWithOvalInRect)之類的是系統(tǒng)對常用的一點(diǎn)封裝而已。

ps:1.繪圖呢,調(diào)用drawRect(重繪父view)和CALayer都可以,但是相比之下CALayer調(diào)用GPU來進(jìn)行繪制,性能會(huì)更好點(diǎn)。如果要組合成動(dòng)畫,還是要用CALayer,(不過很多時(shí)候用它的子類CAShapeLayer)
2.它這種直線段繪圖(addLineToPoint)跟代碼順序有關(guān),所以敲的時(shí)候要注意了
3.另外如果調(diào)起 [aPath stroke],它是會(huì)自動(dòng)連上起點(diǎn)和終點(diǎn)的,當(dāng)然也可以用填充模式[aPath fill]替代[aPath stroke]畫線模式
==

(4)改變UIBezierPath對象跟繪圖相關(guān)的屬性。
例如,我們可以設(shè)置stroked path的屬性lineWidth和lineJoinStyle。也可以設(shè)置filled path的屬性usesEvenOddFillRule。

貝塞爾曲線的修改:

1.底層修改(比較麻煩):

雖然通常我們可以用UIBezierPath類的方法去添加直線段和曲線段,UIBezierPath類還提供了一個(gè)屬性CGPath,我們可以用來直接修改底層的path data type。如果我們希望用Core Graphics 框架函數(shù)去創(chuàng)建path,則我們要用到此屬性。

>有兩種方法可以用來修改和UIBezierPath對象相關(guān)的path??梢酝耆氖褂肅ore Graphics函數(shù)去修改path,也可以使用Core Graphics函數(shù)和UIBezierPath函數(shù)混合去修改。第一種方法在某些方面相對來說比較容易。我們可以創(chuàng)建一個(gè)CGPathRef數(shù)據(jù)類型,并調(diào)用我們需要修改path信息的函數(shù)。

如果我們使用Core Graphics函數(shù)和UIBezierPath函數(shù)混合方法,我們必須小心的移動(dòng)path 信息在兩者之間。因?yàn)閁IBezierPath類擁有自己底層的CGPathRef data type,我們不能簡單的檢索該類型并直接的修改它。相反,我們應(yīng)該生成一個(gè)副本,然后修改此副本,然后賦值此副本給CGPath屬性,如下代碼:

UIBezierPath*    aPath = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, 300, 300)];
 
// Get the CGPathRef and create a mutable version.
CGPathRef cgPath = aPath.CGPath;
CGMutablePathRef  mutablePath = CGPathCreateMutableCopy(cgPath);
 
// Modify the path and assign it back to the UIBezierPath object
CGPathAddEllipseInRect(mutablePath, NULL, CGRectMake(50, 50, 200, 200));
aPath.CGPath = mutablePath;
 
// Release both the mutable copy of the path.
CGPathRelease(mutablePath);

ps:名稱解釋之GPU

GPU相當(dāng)于專用于圖像處理的CPU,正因?yàn)樗鼘#运鼜?qiáng),在處理圖像時(shí)它的工作效率遠(yuǎn)高于CPU,但是CPU是通用的數(shù)據(jù)處理器,在處理數(shù)值計(jì)算時(shí)是它的強(qiáng)項(xiàng),它能完成的任務(wù)是GPU無法代替的,所以不能用GPU來代替CPU。

時(shí)下的GPU多數(shù)擁有2D或3D圖形加速功能。如果CPU想畫一個(gè)二維圖形,只需要發(fā)個(gè)指令給GPU,如“在坐標(biāo)位置(x, y)處畫個(gè)長和寬為a×b大小的長方形”,GPU就可以迅速計(jì)算出該圖形的所有像素,并在顯示器上指定位置畫出相應(yīng)的圖形,畫完后就通知CPU “我畫完了”,然后等待CPU發(fā)出下一條圖形指令。
有了GPU,CPU就從圖形處理的任務(wù)中解放出來,可以執(zhí)行其他更多的系統(tǒng)任務(wù),這樣可以大大提高計(jì)算機(jī)的整體性能

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺,僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 說起這個(gè)貝塞爾曲線,其實(shí)可以實(shí)現(xiàn)很多功能的:曲線圖、折線圖、進(jìn)度條、畫板、不規(guī)則圖形等等。下邊我們就來看看這條線。...
    和玨貓閱讀 2,962評論 3 19
  • TopicList 一, UIBezierPath 簡介 二, UIBezierPath 初始化方法 三, UIB...
    爨鄉(xiāng)的云閱讀 24,825評論 4 56
  • 關(guān)于 UIBezierPath UIBezierPath這個(gè)類在UIKit中, 是Core Graphics框架關(guān)...
    劉光軍_MVP閱讀 59,218評論 18 202
  • 我不是天生富二代的命, 人生的路上我一直在打拼, 告訴自己不能泄氣,因?yàn)閻燮床艜?huì)贏; 我沒有百毒不侵的身心, 無助...
    劉宏教育蒲公英閱讀 575評論 0 0
  • 為了加深我們對黨史的認(rèn)識,培養(yǎng)我們對紅軍的感情,讓廣大幼兒教師接受革命傳統(tǒng)教育,提高思想政治素質(zhì),幼兒園利用暑假組...
    L鴨蛋閱讀 167評論 0 0

友情鏈接更多精彩內(nèi)容