根據(jù)點(diǎn)串繪制圓滑貝塞爾曲線

- (UIBezierPath*)pathForPoints:(NSArray*)allPoints {

? ? UIBezierPath *path = [UIBezierPath bezierPath];

? ? CGFloatmLineSmoothness =0.18;

? ? CGFloatprePreviousPointX;

? ? CGFloatprePreviousPointY;

? ? CGFloatpreviousPointX;

? ? CGFloatpreviousPointY;

? ? CGFloatcurrentPointX;

? ? CGFloatcurrentPointY;

? ? CGFloatnextPointX;

? ? CGFloatnextPointY;

? ? for(inti =0; i < allPoints.count; i++) {

? ? ? ? CGPointcurrentPoint = [allPoints[i]CGPointValue];

? ? ? ? currentPointX = currentPoint.x;

? ? ? ? currentPointY = currentPoint.y;

? ? ? ? if(i >0) {

? ? ? ? ? ? CGPointprePoint = [allPoints[i-1]CGPointValue];

? ? ? ? ? ? previousPointX = prePoint.x;

? ? ? ? ? ? previousPointY = prePoint.y;

? ? ? ? }else{

? ? ? ? ? ? previousPointX = currentPointX;

? ? ? ? ? ? previousPointY = currentPointY;

? ? ? ? }

? ? ? ? if(i >1) {

? ? ? ? ? ? CGPointprePrePoint = [allPoints[i-2]CGPointValue];

? ? ? ? ? ? prePreviousPointX = prePrePoint.x;

? ? ? ? ? ? prePreviousPointY = prePrePoint.y;

? ? ? ? }

? ? ? ? if(i < allPoints.count-1) {

? ? ? ? ? ? CGPointnextPoint = [allPoints[i+1]CGPointValue];

? ? ? ? ? ? nextPointX = nextPoint.x;

? ? ? ? ? ? nextPointY = nextPoint.y;

? ? ? ? }else{

? ? ? ? ? ? nextPointX = currentPointX;

? ? ? ? ? ? nextPointY = currentPointY;

? ? ? ? }

? ? ? ? if(i ==0) {

? ? ? ? ? ? [pathmoveToPoint:currentPoint];

? ? ? ? }else{

? ? ? ? ? ? CGFloatfirstDiffX = (currentPointX - prePreviousPointX);

? ? ? ? ? ? CGFloatfirstDiffY = (currentPointY - prePreviousPointY);

? ? ? ? ? ? CGFloatsecondDiffX = (nextPointX - previousPointX);

? ? ? ? ? ? CGFloatsecondDiffY = (nextPointY - previousPointY);

? ? ? ? ? ? CGFloatfirstControlPointX = previousPointX + (mLineSmoothness * firstDiffX);

? ? ? ? ? ? CGFloatfirstControlPointY = previousPointY + (mLineSmoothness * firstDiffY);

? ? ? ? ? ? CGFloatsecondControlPointX = currentPointX - (mLineSmoothness * secondDiffX);

? ? ? ? ? ? CGFloatsecondControlPointY = currentPointY - (mLineSmoothness * secondDiffY);

? ? ? ? ? ? [pathaddCurveToPoint:CGPointMake(currentPointX, currentPointY)controlPoint1:CGPointMake(firstControlPointX, firstControlPointY)controlPoint2:CGPointMake(secondControlPointX, secondControlPointY)];//三次曲線

? ? ? ? }

? ? ? ? // 更新

? ? ? ? prePreviousPointX = previousPointX;

? ? ? ? prePreviousPointY = previousPointY;

? ? ? ? previousPointX = currentPointX;

? ? ? ? previousPointY = currentPointY;

? ? ? ? currentPointX = nextPointX;

? ? ? ? currentPointY = nextPointY;

? ? }

? ? returnpath;

}



- (UIBezierPath*)pathForPoints:(NSArray*)allPoints {

? ? UIBezierPath *path = [UIBezierPath bezierPath];

? ? //下面的方法效果更好,但是只支持4個(gè)點(diǎn)及以上情況

? ? if(allPoints.count<4) {

? ? ? ? [pathmoveToPoint:[allPoints[0]CGPointValue]];

? ? ? ? CGPointPrePonit;

? ? ? ? for(inti =0; i < allPoints.count; i++) {

? ? ? ? ? ? CGPointpoint = [allPoints[i]CGPointValue];

? ? ? ? ? ? point =CGPointMake(point.x, point.y);

? ? ? ? ? ? if(i ==0) {

? ? ? ? ? ? ? ? PrePonit = point;

? ? ? ? ? ? }else{

? ? ? ? ? ? ? ? CGPointNowPoint = [allPoints[i]CGPointValue];

? ? ? ? ? ? ? ? [pathaddCurveToPoint:NowPointcontrolPoint1:CGPointMake((PrePonit.x+NowPoint.x)/2, PrePonit.y)controlPoint2:CGPointMake((PrePonit.x+NowPoint.x)/2, NowPoint.y)];//三次曲線

? ? ? ? ? ? ? ? PrePonit = NowPoint;

? ? ? ? ? ? }

? ? ? ? }

? ? }else{

? ? ? ? NSIntegergranularity =10;

? ? ? ? [pathmoveToPoint:[allPoints[0]CGPointValue]];

? ? ? ? [pathaddLineToPoint:[allPoints[1]CGPointValue]];

? ? ? ? for(intindex =3; index < allPoints.count; index++) {

? ? ? ? ? ? CGPointp0 = [allPoints[index -3]CGPointValue];

? ? ? ? ? ? CGPointp1 = [allPoints[index -2]CGPointValue];

? ? ? ? ? ? CGPointp2 = [allPoints[index -1]CGPointValue];

? ? ? ? ? ? CGPointp3 = [allPoints[index]CGPointValue];

? ? ? ? ? ? for(inti =1; i < granularity; i++) {

? ? ? ? ? ? ? ? floatt = (float)i * (1.0/ granularity);

? ? ? ? ? ? ? ? floattt = t * t;

? ? ? ? ? ? ? ? floatttt = tt * t;

? ? ? ? ? ? ? ? CGPointpi;

? ? ? ? ? ? ? ? pi.x=0.5* (2* p1.x+(p2.x- p0.x) * t +(2* p0.x-5* p1.x+4*p2.x- p3.x) * tt + (3* p1.x- p0.x-3*p2.x+ p3.x) *ttt );

? ? ? ? ? ? ? ? pi.y=0.5* (2* p1.y+(p2.y- p0.y) * t +(2* p0.y-5* p1.y+4*p2.y- p3.y) * tt + (3* p1.y- p0.y-3*p2.y+ p3.y) *ttt );

? ? ? ? ? ? ? ? [pathaddLineToPoint:pi];

? ? ? ? ? ? }

? ? ? ? ? ? [pathaddLineToPoint:p2];

? ? ? ? }

? ? ? ? [pathaddLineToPoint:[allPoints[allPoints.count-1]CGPointValue]];

? ? }

? ? returnpath;

}



在這里采用的是Catmull-Rom插值技術(shù)實(shí)現(xiàn)的,其實(shí)就是一個(gè)比較特殊的貝塞爾曲線,如果想用這個(gè)方式進(jìn)行插值棺妓,那么在這個(gè)曲線上最少要有4個(gè)點(diǎn)存在,因?yàn)檫@種方式只能在中間的兩個(gè)點(diǎn)進(jìn)行插值女蜈,例如有4個(gè)點(diǎn)分別是p0、p1色瘩、p2伪窖、p3依次在這個(gè)貝塞爾曲線上,那么我們積可以將值插到p1居兆、p2之間覆山,在上面的代碼中可以看到變量t,t的范圍是[0,1],當(dāng)t=0到t=1變化泥栖,那么曲線就會(huì)從p1(t=0)到p2(t=1)運(yùn)動(dòng)簇宽,計(jì)算出來(lái)的點(diǎn)的切向量和這個(gè)點(diǎn)的周?chē)鷥蓚€(gè)起點(diǎn)和終點(diǎn)的切向量是平行的,那么如果想要使曲線更加的平滑吧享,那么就要取到更多的點(diǎn)p0魏割、p1、p2钢颂、p3钞它、p4,這樣就可以有兩組分別是p0殊鞭、p1须揣、p2、p3和p1钱豁、p2、p3疯汁、p4牲尺,就能夠在p1、p2和p2幌蚊、p3之間進(jìn)行插值谤碳,以此類推,使曲線更加的平滑

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末溢豆,一起剝皮案震驚了整個(gè)濱河市蜒简,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌漩仙,老刑警劉巖搓茬,帶你破解...
    沈念sama閱讀 207,113評(píng)論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件犹赖,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡卷仑,警方通過(guò)查閱死者的電腦和手機(jī)峻村,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,644評(píng)論 2 381
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)锡凝,“玉大人粘昨,你說(shuō)我怎么就攤上這事〈芫猓” “怎么了张肾?”我有些...
    開(kāi)封第一講書(shū)人閱讀 153,340評(píng)論 0 344
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)锚扎。 經(jīng)常有香客問(wèn)我吞瞪,道長(zhǎng),這世上最難降的妖魔是什么工秩? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 55,449評(píng)論 1 279
  • 正文 為了忘掉前任尸饺,我火速辦了婚禮,結(jié)果婚禮上助币,老公的妹妹穿的比我還像新娘浪听。我一直安慰自己,他們只是感情好眉菱,可當(dāng)我...
    茶點(diǎn)故事閱讀 64,445評(píng)論 5 374
  • 文/花漫 我一把揭開(kāi)白布迹栓。 她就那樣靜靜地躺著,像睡著了一般俭缓。 火紅的嫁衣襯著肌膚如雪克伊。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,166評(píng)論 1 284
  • 那天华坦,我揣著相機(jī)與錄音愿吹,去河邊找鬼。 笑死惜姐,一個(gè)胖子當(dāng)著我的面吹牛犁跪,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播歹袁,決...
    沈念sama閱讀 38,442評(píng)論 3 401
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼坷衍,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了条舔?” 一聲冷哼從身側(cè)響起枫耳,我...
    開(kāi)封第一講書(shū)人閱讀 37,105評(píng)論 0 261
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎孟抗,沒(méi)想到半個(gè)月后迁杨,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體钻心,經(jīng)...
    沈念sama閱讀 43,601評(píng)論 1 300
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,066評(píng)論 2 325
  • 正文 我和宋清朗相戀三年仑最,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了扔役。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,161評(píng)論 1 334
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡警医,死狀恐怖亿胸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情预皇,我是刑警寧澤侈玄,帶...
    沈念sama閱讀 33,792評(píng)論 4 323
  • 正文 年R本政府宣布,位于F島的核電站吟温,受9級(jí)特大地震影響序仙,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜鲁豪,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,351評(píng)論 3 307
  • 文/蒙蒙 一潘悼、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧爬橡,春花似錦治唤、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,352評(píng)論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至柜裸,卻和暖如春缕陕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背疙挺。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,584評(píng)論 1 261
  • 我被黑心中介騙來(lái)泰國(guó)打工扛邑, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人铐然。 一個(gè)月前我還...
    沈念sama閱讀 45,618評(píng)論 2 355
  • 正文 我出身青樓蔬崩,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親锦爵。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 42,916評(píng)論 2 344

推薦閱讀更多精彩內(nèi)容