Core Graphicsグラフィック変換
6399 ワード
単純な座標変換:
Quarzd 2 Dは3つのAPIを提供して座標変換を行う:
変換後の座標系では、原点は元の座標系(tx,ty)に位置する.従来の座標系では,すべての点の横縦座標がtxとtyをそれぞれ増加させることにも相当する.
点A 1が座標変換されてA 2になったと仮定し、座標原点をOと記す.A 1 O=A 2 O(A 2はOを中心とし、A 1 Oの長さを半径とする円上にある)であり、⑨A 1 OA 2=angelである.ここの回転は時計回りに回転します.反時計回りに回したいなら-angelを使えばいいです.
新しい座標系のすべての点の横縦座標は、元の横縦座標にスケール係数sxとsyをそれぞれ乗じたものに等しい.ここでの変換関数は、コンテキスト(context)に作用することに注意してください.しかし、前述の図面設定の変更とは異なり、これらのAPIは座標系の状態を変更し、CGcontextDrawPathメソッドを呼び出しても設定を復元できない.
座標系状態の保存と復元
このペアのメソッドを呼び出して、システムステータスの保存とリカバリを行うことができます.
1つの図面コンテキストは、図面システムのステータスのスタックを維持します.コンテキストが初期化されると、このスタックは空になるので、CGcontextSaveGStateメソッドを呼び出し、現在のシステム状態をスタックに入れ、リカバリが必要な場合にCGcontextRestoreGStateを呼び出します.ここでの「状態」(State)には、現在の座標系の状態だけでなく、設定された塗りつぶしスタイル、線スタイル、シャドウスタイルなど様々な状態が含まれています.なお,状態を保存せずに座標変換のAPIを呼び出すと,二度と復元できない.CGcontextRestoreGStateメソッドを呼び出そうとすると、空のスタックに対してスタックメソッドが実行され、エラーが発生します.
*マトリクスによる変換
Quartz 2 Dは、以上の3つの変換方法に加えて、マトリクスを用いて座標変換を処理するより一般的な方法を提供する.
変換マトリクスCGAffineTransform transformは、次のように作成できます.
この3つの方法はそれぞれ回転変換,スケーリング変換,平行移動変換のAPIに対応するので説明しない.
さらに一般的な変換行列を作成することもできます.
行列の演算規則と平行移動変換の変換法則によれば、点A(x,y)がtransform行列によって作用した後の点A’の左側は(ax+cy+tx,bx+dy+ty)であるべきである.
高校の数学の知識に基づいて、よく見られるいくつかの変換行列を得た.
既存のマトリクスを変更することもできます
変換行列は,コンテキストの座標系だけでなく,CGPoint,CGSize,CGRectなどにも作用する.それだけでなく、UIView自身にはtransform属性があり、変換マトリクスの設定をサポートし、UIコントロール自体を座標変換することができます.
Quarzd 2 Dは3つのAPIを提供して座標変換を行う:
//1.
CGContextTranslateCTM(CGContextRef c, CGFloat tx, CGFloat ty);
変換後の座標系では、原点は元の座標系(tx,ty)に位置する.従来の座標系では,すべての点の横縦座標がtxとtyをそれぞれ増加させることにも相当する.
//2.
CGContextRotateCTM(CGContextRef c, CGFloat angle);
点A 1が座標変換されてA 2になったと仮定し、座標原点をOと記す.A 1 O=A 2 O(A 2はOを中心とし、A 1 Oの長さを半径とする円上にある)であり、⑨A 1 OA 2=angelである.ここの回転は時計回りに回転します.反時計回りに回したいなら-angelを使えばいいです.
//3.
CGContextScaleCTM(CGContextRef c, CGFloat sx, CGFloat sy);
新しい座標系のすべての点の横縦座標は、元の横縦座標にスケール係数sxとsyをそれぞれ乗じたものに等しい.ここでの変換関数は、コンテキスト(context)に作用することに注意してください.しかし、前述の図面設定の変更とは異なり、これらのAPIは座標系の状態を変更し、CGcontextDrawPathメソッドを呼び出しても設定を復元できない.
座標系状態の保存と復元
このペアのメソッドを呼び出して、システムステータスの保存とリカバリを行うことができます.
CGContextSaveGState(CGContextRef c);// 。
CGContextRestoreGState(CGContextRef c);// 。
1つの図面コンテキストは、図面システムのステータスのスタックを維持します.コンテキストが初期化されると、このスタックは空になるので、CGcontextSaveGStateメソッドを呼び出し、現在のシステム状態をスタックに入れ、リカバリが必要な場合にCGcontextRestoreGStateを呼び出します.ここでの「状態」(State)には、現在の座標系の状態だけでなく、設定された塗りつぶしスタイル、線スタイル、シャドウスタイルなど様々な状態が含まれています.なお,状態を保存せずに座標変換のAPIを呼び出すと,二度と復元できない.CGcontextRestoreGStateメソッドを呼び出そうとすると、空のスタックに対してスタックメソッドが実行され、エラーが発生します.
*マトリクスによる変換
Quartz 2 Dは、以上の3つの変換方法に加えて、マトリクスを用いて座標変換を処理するより一般的な方法を提供する.
CGContextConcatCTM(CGContextRef c, CGAffineTransform transform);
//Transform
- (CGAffineTransform)CGContextGetCTM(CGContextRef c);
//
変換マトリクスCGAffineTransform transformは、次のように作成できます.
CGAffineTransform transform1 = CGAffineTransformMakeRotation(CGFloat angle);
CGAffineTransform transform2 = CGAffineTransformMakeScale(CGFloat sx, CGFloat sy);
CGAffineTransform transform3 = CGAffineTransformMakeTranslation(CGFloat tx, CGFloat ty);
この3つの方法はそれぞれ回転変換,スケーリング変換,平行移動変換のAPIに対応するので説明しない.
さらに一般的な変換行列を作成することもできます.
CGAffineTransform transform = CGAffineTransformMake(CGFloat a, CGFloat b, CGFloat c, CGFloat d, CGFloat tx, CGFloat ty);
行列の演算規則と平行移動変換の変換法則によれば、点A(x,y)がtransform行列によって作用した後の点A’の左側は(ax+cy+tx,bx+dy+ty)であるべきである.
高校の数学の知識に基づいて、よく見られるいくつかの変換行列を得た.
CGAffineTransformMake(-1, 0, 0, 1, 0, 0);// X
CGAffineTransformMake(1, 0, 0, -1, 0, 0);// Y
CGAffineTransformMake(0, 1, 1, 0, 0, 0);// Y=X
CGAffineTransformMake(0, -1, -1, 0, 0, 0);// X
CGAffineTransformMake(1, 0, tan(α), 1, 0, 0);// α°
CGAffineTransformMake(1, -tan(α), 0, 1, 0, 0);// α°
既存のマトリクスを変更することもできます
CGAffineTransformScale(CGAffineTransform t, CGFloat sx, CGFloat sy);
CGAffineTransformRotate(CGAffineTransform t, CGFloat angle);
CGAffineTransformTranslate(CGAffineTransform t, CGFloat tx, CGFloat ty);// ,
CGAffineTransformInvert(CGAffineTransform t);//
CGAffineTransformConcat(CGAffineTransform t1, CGAffineTransform t2);// , t1 t2
変換行列は,コンテキストの座標系だけでなく,CGPoint,CGSize,CGRectなどにも作用する.それだけでなく、UIView自身にはtransform属性があり、変換マトリクスの設定をサポートし、UIコントロール自体を座標変換することができます.
CGPoint newPoint = CGPointApplyAffineTransform(CGPoint point, CGAffineTransform t);
CGSize newSize = CGSizeApplyAffineTransform(CGSize size, CGAffineTransform t);
CGRect newRect = CGRectApplyAffineTransform(CGRect rect, CGAffineTransform t);