الحفاظ على عرض الخط أثناء توسيع جميع النقاط في السياق باستخدام cgaffinetransform
-
22-09-2019 - |
سؤال
انا املك 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);