- (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)行插值谤碳,以此類推,使曲線更加的平滑