Domanda

Ho un CGPath in qualche sistema di coordinate che mi piacerebbe disegnare. In questo modo comporta il ridimensionamento del vecchio sistema di coordinate su uno del contesto. A tal fine, io uso CGContextConcatCTM() che fa trasformare tutti i punti come dovrebbe. Ma, in quanto è un operazione di dimensionamento, le larghezze di riga verticale / orizzontale vengono cambiati. Per esempio. una scala 10 in direzione x, ma di 1 in direzione y provocherebbe linee verticali essere 10 volte più spessa come quelli orizzontali. C'è un modo per mantenere la facilità di utilizzo di matrici di traduzione (ad esempio CGAffineTransform) ma linea non regolante larghezze allo stesso tempo, ad esempio una funzione come CGPathApplyAffineTransformToPoints?

Saluti

MrMage

È stato utile?

Soluzione

È possibile utilizzare CGPathApply per scorrere gli elementi in un percorso. E 'un po' più complesso di un semplice one-liner, ma se si confezionarlo in una semplice funzione di supporto, potrebbe essere utile per voi. Ecco una versione che crea un nuovo percorso e lo trasforma:

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;
    }
}

Per usarlo si farebbe (questa è la parte avrei messo dentro una funzione di supporto):

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

    CGPathApply(originalPath, &info,  PathTransformer);

Il percorso è stato trasformato in in info.path a questo punto.

Altri suggerimenti

Do la trasformazione quando si aggiunge il percorso, ma poi rimuovere la trasformazione prima di corsa il percorso. Invece di questo:

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

Fare questo:

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);
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top