Search code examples
ioscore-graphicscgpath

How to get last point of each dash-line created after CGContextSetLineDash of a CGPath


I am converting the path into dashline to get multiple segments of a CGPATH.

float dash[2]={20 ,1}; 
int index =0;
    CGContextSetLineDash(context,0,dash,2);
    CGContextReplacePathWithStrokedPath(context);
    dashedpath = CGContextCopyPath(context);                                    
   CGPathApply(dashedpath, &thepobj, visitdashedpath);

and in visitdashedpath I am trying to find the end point of previous (each) dash-line.

void visitdashedpath(void* info, const CGPathElement* element)
{
int nPoints;
pathObj * dasharray = (pathObj *)info;
switch (element->type)
{
  case kCGPathElementMoveToPoint:
      dasharray[index-1].endpoint   =  CGPathGetCurrentPoint(dasharray[index-1].path); [my-option1]
        dasharray[index].path   =  CGPathCreateMutable ();
    break;

    case kCGPathElementAddLineToPoint:

    CGPathAddLineToPoint(dasharray[index].path,NULL,element->points[0].x,element->points[0].y);    
    dasharray[index].endpoint   =  CGPathGetCurrentPoint(dasharray[index].path);//[my-option1]

brek;
case kCGPathElementAddcurve:
CGPathAddCurveToPoint(path,c1.x,c1.y,c2.x,c2.y,c3.x,c3.y);
  ----

I want to know the the co-ordinates of last point(dasharray[index-1].endpoint) by processing completed dash line I tried CGPathGetCurrentPoint but it gives start point of dash line. I guess each dash line is made a close-path by CGContextCopyPath. may be thats why I am getting end point as start point.


Solution

  • You're missing a key point of what CGContextReplacePathWithStrokedPath and CGPathCreateCopyByStrokingPath do:

    The new path is created so that filling it draws the same pixels as stroking the original path.

    So, how would you create a fillable path for a line or curve?

    Probably something like:

    1. moveto
    2. curveto (either the outer or the inner curved edge)
    3. lineto (one end)
    4. curveto (either the inner or the outer curved edge)
    5. closepath (the other end)

    That closepath, of course, returns the current point to where step 1 (moveto) started. That's why that's the result you get.

    The original points you started with no longer exist in this path. Indeed, depending on how long your curve is, the dash pattern may mean that no segment overlaps your final point—the last segment may fall short of it.

    If you want the start and end of each segment, get the current point before and after lineto, and take the average, and do the same for the current point before and after closepath. The two points you get from that are the middle of each straight-line element of the path, which, for a simple curved line segment, will be the start and end of the segment.

    I hope your path doesn't have any loops.