2009-11-25 14 views
5

Tengo un CGPath en algún sistema de coordenadas que me gustaría dibujar. Hacerlo implica escalar el antiguo sistema de coordenadas al del Contexto. Para ese propósito, uso CGContextConcatCTM() que transforma todos los puntos como debería. Pero, como es una operación de escala, los anchos de línea horizontal/vertical cambian a. P.ej. una escala de 10 en dirección x, pero de 1 en dirección y llevaría a que las líneas verticales sean 10 veces más gruesas que las horizontales. ¿Hay alguna manera de mantener la facilidad de uso de las matrices de traducción (por ejemplo, CGAffineTransform) pero no escalar anchos de línea al mismo tiempo, p. una función como CGPathApplyAffineTransformToPoints?Conservar el ancho de línea al escalar todos los puntos en el contexto con CGAffineTransform

Saludos

MrMage

Respuesta

3

Puede utilizar CGPathApply para recorrer los elementos de una ruta. Es un poco más complejo que solo un trazador de líneas, pero si lo empaqueta en una sencilla función auxiliar, podría ser útil para usted. Aquí es una versión que crea un nuevo camino y lo transforma:

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

Para usarlo usted haría (esta es la parte que me gustaría poner dentro de una función de ayuda):

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

    CGPathApply(originalPath, &info, PathTransformer); 

El camino transformado está en info.path en este punto.

+0

Gracias! Esto hará lo que solicité, pero desafortunadamente no me dará la ganancia de rendimiento de no tener que recrear todo el camino. Si esta sigue siendo la única respuesta, lo marcaré como la solución. – MrMage

6

Haga la transformación cuando agregue la ruta, pero luego elimine la transformación antes de recorrer la ruta. En lugar de esto:

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 

Haga lo siguiente:

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

Ya no tengo el problema en este momento, pero ¿probaste esto? Si funciona como se describe, sería la mejor respuesta. – MrMage

+0

@MrMage Sí, encontré su pregunta cuando estaba teniendo el mismo problema, y ​​luego se me ocurrió mi propia solución un poco más tarde. – bugloaf

+0

Gracias, esto funcionó para mí. Parece que debería ser la respuesta oficial. –

Cuestiones relacionadas