3

Windowsフォームアプリケーションのクライアント領域にUIハンドル(回転、サイズ変更など)を描画する関数を作成しています。この関数は、オブジェクトが選択されたときに呼び出されます。

呼び出し元は、適切に回転、スケーリング、および変換されて、より大きなスキームに適合するグラフィックスオブジェクトを送信します(選択されたオブジェクトには独自の回転/変換/スケールがあり、UIハンドルには選択されたオブジェクトに対する相対的な変換と回転があります)。ここで、親(選択したオブジェクト)のスケールに関係なく、UIハンドルを同じサイズにします。

変換行列のスケールファクターを削除/リセットするにはどうすればよいですか?貴重な平行移動と回転の値を保持したまま、スケールを1にリセットするにはどうすればよいですか?

4

2 に答える 2

1

変換の順序が重要であることに注意する必要があります。したがって、スケールを削除するだけで、次の翻訳の「意味」が変わる可能性があります(たとえばオフセット)。

たぶん、これまでに適用されたスケールの記録を保持し(これを呼びましょうcurrentscale)、変換にスケールを追加1/currentscaleします。

于 2009-05-11T07:18:17.207 に答える
1

Anti-Grain Geometryは、変換のスケーリングを決定するための基本的な方法を使用します(agg_trans_affine.cppにある実装)。それは次のようにして行われます:

  1. 変換の回転を計算する
  2. 変換を複製し、反対の回転を適用します
  3. 2つの既知のポイントを変換し、結果からスケールを計算します

C#に変換すると、次のようになります。

Matrix transform = (Matrix)graphics.Transform.Clone();

PointF[] rotationPoints = new PointF[] { new PointF(0, 0), new PointF(1, 0) };
transform.TransformPoints(rotationPoints);

double rotationRadians = Math.Atan2(rotationPoints[1].Y - rotationPoints[0].Y, rotationPoints[1].X - rotationPoints[0].X);
transform.Rotate((float)(-rotationRadians * (180.0 / Math.PI)));

PointF[] scalePoints = new PointF[] { new PointF(0, 0), new PointF(1, 1) };
transform.TransformPoints(scalePoints);

float xScale = scalePoints[1].X - scalePoints[0].X;
float yScale = scalePoints[1].Y - scalePoints[0].Y;

AGGコードには、これが正しく機能しない縮退したケースがあるという警告も含まれていますが、状況に役立つ場合があります。

于 2009-06-04T23:56:33.143 に答える