2009-11-25 2 views
5

描画する座標系にはCGPathがあります。そうするためには、古い座標系をコンテキスト上にスケーリングする必要があります。その目的のために、私はCGContextConcatCTM()を使用し、すべての点を必要に応じて変換します。しかし、スケーリング操作であるので、水平/垂直線幅はに変更されます。例えば。 x方向に10のスケール、y方向に1のスケールは、水平ラインの10倍の垂直ラインにつながります。変換行列(例えば、CGAffineTransform)の使い易さを保ちながら同時に線幅をスケーリングしない方法があるかどうか。 CGPathApplyAffineTransformToPointsのような機能?コンテキスト内のすべての点をCGAffineTransformでスケーリングするときに線幅を維持する

乾杯

MrMage

答えて

3

あなたは、パス内の要素を反復処理するCGPathApplyを使用することができます。 1つのライナーより少し複雑ですが、簡単なヘルパー関数でパッケージ化すれば、あなたにとっては便利かもしれません。

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

を、あなたはどうしたらそれを使用するには(これは私がヘルパー関数の内部で置く部分です):ここに新しいパスを作成し、それを変換バージョンは1つである

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

    CGPathApply(originalPath, &info, PathTransformer); 

変換パスこの時点でinfo.pathにあります。

+0

ありがとうございました!これは私が求めたことをするでしょうが、残念ながらパス全体を再作成する必要がないというパフォーマンスの向上は得られません。これが唯一の答えである場合、私はそれを解決策としてマークします。 – MrMage

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); 
+0

私はもう問題はありませんが、これを試しましたか?説明どおりに動作すれば、より良い答えになります。 – MrMage

+0

@MrMageはい、私は同じ問題を抱えていたときにあなたの質問を見つけました。そして、少し後に私自身の解決策を考え出しました。 – bugloaf

+0

ありがとう、これは私のために働いた。それは公式の答えでなければならないようだ。 –

関連する問題