الحفاظ على عرض الخط أثناء توسيع جميع النقاط في السياق باستخدام cgaffinetransform

StackOverflow https://stackoverflow.com/questions/1798441

سؤال

انا املك CGPath في نظام الإحداثيات الذي أود رسمه. يتضمن القيام بذلك توسيع نطاق نظام الإحداثيات القديم على نظام السياق. لهذا الغرض ، أستخدم CGContextConcatCTM() الذي يحول جميع النقاط كما ينبغي. ولكن ، نظرًا لأنها عملية تحجيم ، يتم تغيير عرض الخط الأفقي/العمودي. على سبيل المثال ، يمكن أن يؤدي مقياس 10 في الاتجاه x ، ولكن من 1 في الاتجاه y إلى أن يكون خطوط عمودية 10 أضعاف السميكة مثل الخطوط الأفقية. هل هناك طريقة للحفاظ على سهولة استخدام مصفوفات الترجمة (على سبيل المثال CGAffineTransform) ولكن ليس عرض خط التحجيم في نفس الوقت ، مثل وظيفة مثل CGPathApplyAffineTransformToPoints?

هتافات

Mrmage

هل كانت مفيدة؟

المحلول

يمكنك استخدام 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 عند هذه النقطة.

نصائح أخرى

قم بالتحويل عند إضافة المسار ، ولكن بعد ذلك قم بإزالة التحويل قبل أن تضغط على المسار. بدلا من هذا:

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);
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top