CGAffineTransform を使用してコンテキスト内のすべてのポイントをスケーリングしながら線幅を維持します
-
22-09-2019 - |
質問
私は持っています CGPath
描画したい座標系で。これには、古い座標系をコンテキストの座標系にスケール変更することが含まれます。その目的のために、私が使用するのは、 CGContextConcatCTM()
これにより、すべてのポイントが適切に変換されます。ただし、拡大縮小操作なので、水平/垂直の線幅が変更されます。例えば。x 方向のスケールが 10 ですが、y 方向のスケールが 1 の場合、垂直線の太さは水平線の 10 倍になります。翻訳行列の使いやすさを維持する方法はありますか (例: CGAffineTransform
)ただし、同時に線幅をスケーリングすることはありません。のような関数 CGPathApplyAffineTransformToPoints
?
乾杯
ミスターメイジ
解決
あなたは、パス内の要素を反復処理する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);
所属していません StackOverflow