2009-11-25 14 views
5

Ich habe eine CGPath in einem Koordinatensystem, das ich zeichnen möchte. Dies erfordert das Skalieren des alten Koordinatensystems auf den Kontext. Zu diesem Zweck verwende ich CGContextConcatCTM(), die alle Punkte so umsetzt, wie es sollte. Da es sich jedoch um eine Skalierungsoperation handelt, werden die horizontalen/vertikalen Linienbreiten geändert. Z.B. eine Skala von 10 in x-Richtung, aber von 1 in y-Richtung würde dazu führen, dass vertikale Linien 10 mal so dick sind wie horizontale. Gibt es eine Möglichkeit, die Benutzerfreundlichkeit von Übersetzungsmatrizen (z. B. CGAffineTransform) beizubehalten, aber nicht gleichzeitig die Linienbreiten zu skalieren, z. eine Funktion wie CGPathApplyAffineTransformToPoints?Beibehaltung der Linienbreite beim Skalieren aller Punkte im Kontext mit CGAffineTransform

Prost

MrMage

Antwort

3

können Sie CGPathApply verwenden, um durch die Elemente in einem Pfad zu durchlaufen. Es ist ein bisschen komplexer als nur ein Einzeiler, aber wenn Sie es in einer einfachen Hilfsfunktion verpacken, könnte es für Sie nützlich sein. Hier ist eine Version, die einen neuen Weg erzeugt und transformiert es:

typedef struct { 
    CGMutablePathRef path; 
    CGAffineTransform transform; 
} PathTransformInfo; 

static void 
PathTransformer(void *info, const CGPathElement *element) 
{ 
    PathTransformInfo *transformerInfo = info; 

    switch (element->type) { 
     case kCGPathElementMoveToPoint: 
      CGPathMoveToPoint(transformerInfo->path, &transformerInfo->transform, 
           element->points[0].x, element->points[0].y); 
      break; 

     case kCGPathElementAddLineToPoint: 
      CGPathAddLineToPoint(transformerInfo->path, &transformerInfo->transform, 
           element->points[0].x, element->points[0].y); 
      break; 

     case kCGPathElementAddQuadCurveToPoint: 
      CGPathAddQuadCurveToPoint(transformerInfo->path, &transformerInfo->transform, 
             element->points[0].x, element->points[0].y, 
             element->points[1].x, element->points[1].y); 
      break; 

     case kCGPathElementAddCurveToPoint: 
      CGPathAddCurveToPoint(transformerInfo->path, &transformerInfo->transform, 
            element->points[0].x, element->points[0].y, 
            element->points[1].x, element->points[1].y, 
            element->points[2].x, element->points[2].y); 
      break; 
     case kCGPathElementCloseSubpath: 
      CGPathCloseSubpath(transformerInfo->path); 
      break; 
    } 
} 

es nutzen zu können, tun würde (das ist der Teil I in einer Hilfsfunktion setzen würde):

PathTransformInfo info; 
    info.path = CGPathCreateMutable(); 
    info.transform = CGAffineTransformMakeScale(2, 1); 

    CGPathApply(originalPath, &info, PathTransformer); 

Der transformierte Weg ist in info.path an diesem Punkt.

+0

Thank you! Das wird tun, wonach ich gefragt habe, aber leider wird es mir nicht den Leistungsgewinn bringen, den gesamten Pfad nicht neu erstellen zu müssen. Wenn dies die einzige Antwort bleibt, werde ich es als Lösung markieren. – MrMage

6

Führen Sie die Transformation aus, wenn Sie den Pfad hinzufügen, entfernen Sie dann jedoch die Transformation, bevor Sie den Pfad streichen. Statt dessen:

CGContextSaveGState(ctx); 
CGContextScaleCTM(ctx, 10, 10); // scale path 10x 

CGContextAddPath(ctx, somePath); 

CGContextSetStrokeColorWithColor(ctx, someColor); 
CGContextSetLineWidth(ctx, someWidth); // uh-oh, line width is 10x, too 
CGContextStrokePath(ctx); 

CGContextRestoreGState(ctx);  // back to normal 

tun:

CGContextSaveGState(ctx); 
CGContextScaleCTM(ctx, 10, 10); // scale path 10x 

CGContextAddPath(ctx, somePath); 

CGContextRestoreGState(ctx);  // back to normal 

CGContextSetStrokeColorWithColor(ctx, someColor); 
CGContextSetLineWidth(ctx, someWidth); 
CGContextStrokePath(ctx); 
+0

Ich habe das Problem zur Zeit nicht mehr, aber hast du das ausprobiert? Wenn es wie beschrieben funktioniert, wäre es die bessere Antwort. – MrMage

+0

@MrMage Ja, ich habe Ihre Frage gefunden, als ich das gleiche Problem hatte, und dann kam ich kurze Zeit später zu meiner eigenen Lösung. – bugloaf

+0

Danke, das hat bei mir funktioniert. Scheint so, als sollte es die offizielle Antwort sein. –