5

我有一个CGPath我想绘制的坐标系。这样做涉及将旧坐标系缩放到上下文的坐标系上。为此,我使用CGContextConcatCTM()which 确实可以转换所有点。但是,由于它是缩放操作,因此水平/垂直线宽会更改为。例如,x 方向的比例为 10,而 y 方向的比例为 1,将导致垂直线的粗度是水平线的 10 倍。有没有办法保持平移矩阵(例如)的易用性,CGAffineTransform但不能同时缩放线宽,例如像这样的函数CGPathApplyAffineTransformToPoints

干杯

法师先生

4

2 回答 2

6

添加路径时进行变换,然后在描边路径之前删除变换。而不是这个:

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

做这个:

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);
于 2012-11-12T05:57:12.777 回答
3

您可以使用它CGPathApply来遍历路径中的元素。它比单线更复杂一点,但如果你将它打包成一个简单的辅助函数,它可能对你有用。这是一个创建新路径并对其进行转换的版本:

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

要使用它,你会这样做(这是我放在辅助函数中的部分):

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

    CGPathApply(originalPath, &info,  PathTransformer);

转换后的路径就在info.path此时。

于 2009-11-25T18:53:36.050 回答