Frage

habe ich ein CGPath in einigem Koordinatensystem, dass ich ziehen möchte. Dabei beinhaltet das alte Koordinatensystem auf den eigenen Kontext Skalierung. Zu diesem Zweck verwende ich CGContextConcatCTM(), welche die Punkte alle tun verwandeln, wie es sollte. Aber, da es eine Skalierungsoperation ist, erhalten die horizontale / vertikale Linienbreiten geändert. Z.B. eine Skala von 10 in x-Richtung, aber von 1 in Y-Richtung auf vertikale Linien so dick wie diejenigen horizontal sind 10mal führen würde. Gibt es eine Möglichkeit, die einfache Bedienung von Umsetzungsmatrizen zu halten (z CGAffineTransform), aber nicht Linienbreiten bei gleichzeitig Skalierung, z.B. eine Funktion wie CGPathApplyAffineTransformToPoints?

Prost

MrMage

War es hilfreich?

Lösung

Sie können CGPathApply iterieren durch die Elemente in einem Pfad verwenden. Es ist ein wenig 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 und transformiert es schafft:

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 Pfad ist in info.path an dieser Stelle.

Andere Tipps

Sie verwandeln das, wenn Sie den Pfad hinzufügen, aber dann die Transformation entfernen, bevor Sie Schlaganfall den Weg. 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 Sie dies:

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);
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top