CGRectApplyAffineTransformを適用されたCGRectを元に戻したい
CGAffineTransform の影響で変更された CGRect の値を元に戻すにはどうすればいいでしょうか?
以下が検証として取り組んでいる変換例で、point(10,10), size(100, 100) の四角形を 45 度傾けています。
// 初期状態
CGRect rect = CGRectMake(10, 10, 100, 100); // {{10, 10}, {100, 100}}
CGAffineTransform transform = CGAffineTransformIdentity; // [1, 0, 0, 1, 0, 0]
// 45度回転させる
CGAffineTransform rotate = CGAffineTransformMakeRotation(45.0f * M_PI / 180.0f); // [0.70710677, 0.70710677, -0.70710677, 0.70710677, 0, 0]
transform = CGAffineTransformConcat(transform, rotate); // [0.70710677, 0.70710677, -0.70710677, 0.70710677, 0, 0]
rect = CGRectApplyAffineTransform(rect, transform); // {{-70.710678, 14.142136}, {141.42136, 141.42136}}
// rectを初期状態に復元したい
// ...?
以下のコードはダメでした。
rect = CGRectApplyAffineTransform(rect, CGAffineTransformInvert(transform)); // {{-40, -40}, {200, 200}}
ちなみに、
CGAffineTransformConcat(transform, CGAffineTransformInvert(transform)) // [0.99999994, 0, 0, 0.99999994, 0, 0]
であり、誤差はあるものの、行列自体は CGAffineTransformInvert() で戻せるようです。が、CGRect が期待どおりに戻りません。
実際に使用する際は、初期状態が CGAffineTransformIdentity とは限らず、どのような行列が適用されているかはわかりません。また、CGAffineTransformIdentity なときの CGRect も取得できるとは限りません。言い換えれば、ある行列が既に適用済みの CGRect から CGAffineTransformIdentity な状態の CGRect を算出するのが目的です。
今回の例では、45度傾けることで {{-70.710678, 14.142136}, {141.42136, 141.42136}}
になってしまったものを {{10, 10}, {100, 100}}
に変換できれば成功です。