web-dev-qa-db-ja.com

ポイントの周りの回転のためのワンステップアフィン変換?

CGAffineTransformMake()を1回呼び出すだけで、sin()、cos()などのmath.hトリガー関数を使用して、角度aの点x、yを中心に回転するCore Graphicsアフィン変換を作成する方法他のCG呼び出しはありません。

ここでの他の答えは、複数のCore Graphics呼び出しを使用して、複数のスタック変換またはマルチステップ変換を使用して移動、回転、および移動することに関するもののようです。それらの答えは私の特定の要件を満たしていません。

42
hotpaw2

点(x、y)を中心とした角度aの回転は、アフィン変換に対応します。

CGAffineTransform transform = CGAffineTransformMake(cos(a),sin(a),-sin(a),cos(a),x-x*cos(a)+y*sin(a),y-x*sin(a)-y*cos(a));

回転を時計回りにするか反時計回りにするかによって、-aの代わりに-aをプラグインする必要があります。また、座標系が上下逆になっているかどうかに応じて、yではなく-yをプラグインする必要があります。

また、次のコードを使用して、3行のコードでまったく同じことを実現できます。

CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
transform = CGAffineTransformRotate(transform, a);
transform = CGAffineTransformTranslate(transform,-x,-y);

これをビューに適用している場合は、CGAffineTransformMakeRotation(a)を介して回転変換を使用することもできます。ただし、ビューのレイヤーのanchorPointプロパティを設定して、回転させたいポイントを反映させます。ただし、これをビューに適用することに興味がないようです。

最後に、これを非ユークリッド2D空間に適用する場合、アフィン変換はまったく必要ない場合があります。アフィン変換はユークリッド空間のアイソメトリです。つまり、角度だけでなく標準のユークリッド距離も保持されます。スペースがユークリッドでない場合、必要な変換は実際にはアフィンではない可能性があります。アフィンである場合、回転のマトリックスは、上で書いたsinとcosほど単純ではない可能性があります。たとえば、双曲線空間にいる場合は、式内の異なる+および-記号とともに、双曲線トリガー関数sinhおよびcoshを使用する必要があります。

追伸また、ここまで読んだ人に、「アフィン」は「アスク」のように短い「a」で発音され、「アブル」のように長い「a」ではないことを思い出したかった。私もApple従業員がWWDCの講演でそれを誤解していると聞きました。

117
landweber

私のような人にとっては、画像を回転させて適切に拡大縮小するための完全なソリューションを探して苦労していますが、数時間後にこれは私が得た最も完全で完璧なソリューションです。

ここでのコツは、関連する変換(スケールと回転の両方)の前に、基準点を変換することです。その後、完全なアフィン変換を取得するために、2つの変換を連結する必要があります。

ソリューション全体を ここに要点 できるCIFilterサブクラスにまとめました。

コードの関連部分に従う:

CGFloat a = _inputDegree.floatValue;
CGFloat x = _inputImage.extent.size.width/2.0;
CGFloat y = _inputImage.extent.size.height/2.0;

CGFloat scale = [self calculateScaleForAngle:GLKMathRadiansToDegrees(a)];

CGAffineTransform transform = CGAffineTransformMakeTranslation(x, y);
transform = CGAffineTransformRotate(transform, a);
transform = CGAffineTransformTranslate(transform,-x,-y);


CGAffineTransform transform2 = CGAffineTransformMakeTranslation(x, y);
transform2 = CGAffineTransformScale(transform2, scale, scale);
transform2 = CGAffineTransformTranslate(transform2,-x,-y);

CGAffineTransform concate   = CGAffineTransformConcat(transform2, transform);
2
valvoline

for Swift 4

print(x, y) // where x,y is the point to rotate around
let degrees = 45.0
let transform = CGAffineTransform(translationX: x, y: y)
    .rotated(by: degrees * .pi / 180)
    .translatedBy(x: -x, y: -y)
2
Ming Chu

このリンクを確認してください: iPhoneビューをポイントの周りで回転させる 。あなたを助けるかもしれません。記事の最後に向かって、「アンカーポイントの変更」というタイトルのセクションがあります。ビューを相殺しないようにするためにいくつかの補正が必要ですが、これはおそらくあなたのニーズに最も適しています。

0
aopsfan