Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>We need to observe some thing before applying any algorithm on captured points.</p> <ol> <li>Generally UIKit does not give the points at equal distance.</li> <li>We need to calculate the intermediate points in between two CGPoints[ Which has captured with Touch moved method]</li> </ol> <p>Now to get smooth line, there are so many ways.</p> <p>Some times we can achieve the by applying second degree polynomial or third degree polynomial or catmullRomSpline algorithms</p> <pre><code>- (float)findDistance:(CGPoint)point lineA:(CGPoint)lineA lineB:(CGPoint)lineB { CGPoint v1 = CGPointMake(lineB.x - lineA.x, lineB.y - lineA.y); CGPoint v2 = CGPointMake(point.x - lineA.x, point.y - lineA.y); float lenV1 = sqrt(v1.x * v1.x + v1.y * v1.y); float lenV2 = sqrt(v2.x * v2.x + v2.y * v2.y); float angle = acos((v1.x * v2.x + v1.y * v2.y) / (lenV1 * lenV2)); return sin(angle) * lenV2; } - (NSArray *)douglasPeucker:(NSArray *)points epsilon:(float)epsilon { int count = [points count]; if(count &lt; 3) { return points; } //Find the point with the maximum distance float dmax = 0; int index = 0; for(int i = 1; i &lt; count - 1; i++) { CGPoint point = [[points objectAtIndex:i] CGPointValue]; CGPoint lineA = [[points objectAtIndex:0] CGPointValue]; CGPoint lineB = [[points objectAtIndex:count - 1] CGPointValue]; float d = [self findDistance:point lineA:lineA lineB:lineB]; if(d &gt; dmax) { index = i; dmax = d; } } //If max distance is greater than epsilon, recursively simplify NSArray *resultList; if(dmax &gt; epsilon) { NSArray *recResults1 = [self douglasPeucker:[points subarrayWithRange:NSMakeRange(0, index + 1)] epsilon:epsilon]; NSArray *recResults2 = [self douglasPeucker:[points subarrayWithRange:NSMakeRange(index, count - index)] epsilon:epsilon]; NSMutableArray *tmpList = [NSMutableArray arrayWithArray:recResults1]; [tmpList removeLastObject]; [tmpList addObjectsFromArray:recResults2]; resultList = tmpList; } else { resultList = [NSArray arrayWithObjects:[points objectAtIndex:0], [points objectAtIndex:count - 1],nil]; } return resultList; } - (NSArray *)catmullRomSplineAlgorithmOnPoints:(NSArray *)points segments:(int)segments { int count = [points count]; if(count &lt; 4) { return points; } float b[segments][4]; { // precompute interpolation parameters float t = 0.0f; float dt = 1.0f/(float)segments; for (int i = 0; i &lt; segments; i++, t+=dt) { float tt = t*t; float ttt = tt * t; b[i][0] = 0.5f * (-ttt + 2.0f*tt - t); b[i][1] = 0.5f * (3.0f*ttt -5.0f*tt +2.0f); b[i][2] = 0.5f * (-3.0f*ttt + 4.0f*tt + t); b[i][3] = 0.5f * (ttt - tt); } } NSMutableArray *resultArray = [NSMutableArray array]; { int i = 0; // first control point [resultArray addObject:[points objectAtIndex:0]]; for (int j = 1; j &lt; segments; j++) { CGPoint pointI = [[points objectAtIndex:i] CGPointValue]; CGPoint pointIp1 = [[points objectAtIndex:(i + 1)] CGPointValue]; CGPoint pointIp2 = [[points objectAtIndex:(i + 2)] CGPointValue]; float px = (b[j][0]+b[j][1])*pointI.x + b[j][2]*pointIp1.x + b[j][3]*pointIp2.x; float py = (b[j][0]+b[j][1])*pointI.y + b[j][2]*pointIp1.y + b[j][3]*pointIp2.y; [resultArray addObject:[NSValue valueWithCGPoint:CGPointMake(px, py)]]; } } for (int i = 1; i &lt; count-2; i++) { // the first interpolated point is always the original control point [resultArray addObject:[points objectAtIndex:i]]; for (int j = 1; j &lt; segments; j++) { CGPoint pointIm1 = [[points objectAtIndex:(i - 1)] CGPointValue]; CGPoint pointI = [[points objectAtIndex:i] CGPointValue]; CGPoint pointIp1 = [[points objectAtIndex:(i + 1)] CGPointValue]; CGPoint pointIp2 = [[points objectAtIndex:(i + 2)] CGPointValue]; float px = b[j][0]*pointIm1.x + b[j][1]*pointI.x + b[j][2]*pointIp1.x + b[j][3]*pointIp2.x; float py = b[j][0]*pointIm1.y + b[j][1]*pointI.y + b[j][2]*pointIp1.y + b[j][3]*pointIp2.y; [resultArray addObject:[NSValue valueWithCGPoint:CGPointMake(px, py)]]; } } { int i = count-2; // second to last control point [resultArray addObject:[points objectAtIndex:i]]; for (int j = 1; j &lt; segments; j++) { CGPoint pointIm1 = [[points objectAtIndex:(i - 1)] CGPointValue]; CGPoint pointI = [[points objectAtIndex:i] CGPointValue]; CGPoint pointIp1 = [[points objectAtIndex:(i + 1)] CGPointValue]; float px = b[j][0]*pointIm1.x + b[j][1]*pointI.x + (b[j][2]+b[j][3])*pointIp1.x; float py = b[j][0]*pointIm1.y + b[j][1]*pointI.y + (b[j][2]+b[j][3])*pointIp1.y; [resultArray addObject:[NSValue valueWithCGPoint:CGPointMake(px, py)]]; } } // the very last interpolated point is the last control point [resultArray addObject:[points objectAtIndex:(count - 1)]]; return resultArray; } </code></pre>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
    3. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload