Pregunta

Tengo un CGPath en algún sistema de coordenadas que me gusta dibujar. Si lo hace, implica la ampliación del sistema de coordenadas de edad en uno del Contexto. A tal fin, yo uso CGContextConcatCTM() la que hace transformar todos los puntos como debería. Pero, ya que es una operación de escalado, la horizontal / ancho de las líneas verticales se ve modificado a. P.ej. una escala de 10 en la dirección x, pero de 1 en la dirección y conducirían a líneas verticales que son 10 veces tan gruesa como las horizontales. ¿Hay una manera de mantener la facilidad de uso de matrices de traducción (por ejemplo, CGAffineTransform) pero no escalar anchos de línea, al mismo tiempo, por ejemplo, una función como CGPathApplyAffineTransformToPoints?

Saludos

MrMage

¿Fue útil?

Solución

Se puede utilizar CGPathApply para iterar a través de los elementos en un camino. Es un poco más complejo que una simple de una sola línea, pero si se empaqueta en una función auxiliar simple, que 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 lo 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);

La ruta transformada es en info.path en este punto.

Otros consejos

Foro de la transformada cuando se agrega el camino, pero a continuación, retire la transformada antes de contornear el trazado. 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);
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top