8

私はJavaプロジェクトで文字列を回転させるためにアフィン変換を使用していますが、まだ経験豊富なプログラマーではないため、一見小さなタスクを実行するのに長い時間がかかりました。文字列を回転させるため。

今、私はついにそれが私が望むほど正確に行われていないことを除いて、私が望んでいたように多かれ少なかれ動作するようになりました...まだ。

多くの試行錯誤とアフィン変換の説明を読んだので、それが実際に何をするのかまだよくわかりません。現時点で私が知っていると思うのは、文字列を取得し、文字列の中心(または回転させたい点)を定義することですが、行列はどこから入りますか?(どうやら私はそのheheを知りません)

誰かがアフィン変換がどのように機能するか、言い換えればjava docを説明してくれませんか?多分それは私の実装を微調整するのを助けることができますそしてまた、私は本当に知りたいです:)

前もって感謝します。

4

5 に答える 5

6

アフィン変換とは何か、およびそれがどのように機能するかを理解するには、ウィキペディアの記事を参照してください。

一般に、これは線形変換(スケーリングや反射など)であり、特定の行列による乗算として実装でき、その後、ベクトルを追加することによって変換(移動)が続きます。したがって、各ピクセル[x、y]の新しい位置を計算するには、特定の行列を掛けて(線形変換を実行)、次に特定のベクトルを追加して(変換を実行)する必要があります。

于 2011-04-14T22:08:57.980 に答える
4

他の回答に加えて、より高いレベルのビュー:

  • 画面上の点にはax座標とay座標があります。つまり、ベクトル(x、y)として記述できます。より複雑な幾何学的オブジェクトは、ポイントのコレクションによって記述されると考えることができます。

  • ベクトル(点)に行列を掛けると、結果は別のベクトル(点)になります。

  • 特別な(つまり巧妙に構築された)行列があり、ベクトルを乗算すると、結果のベクトルが回転、スケーリング、スキュー、または入力ポイントの少し巧妙な変換と同等になるという効果があります。

基本的にはこれですべてです。このアプローチには、さらにいくつかの優れた機能があります。

  • 2つの行列を乗算すると、行列が再び取得されます(少なくともこの場合、nit-pickingを停止します;-))。
  • 2つの幾何学的変換に相当する2つの行列を乗算すると、結果の行列は2つの幾何学的変換を次々に実行するのと同じになります(順序は重要です)。
  • これは、これらの幾何学的変換の任意のチェーンを単一の行列にエンコードできることを意味します。また、個々の行列を乗算することで、この行列を作成できます。
  • ところで、これは3Dでも機能します。

詳細については、他の回答を参照してください。

于 2011-04-15T05:33:26.857 に答える
3

他の人からすでに与えられた答えとは別に、私は実用的なヒント、つまり弦や他のオブジェクトを回転させるときに通常適用するパターンを示したいと思います。

  1. を適用して、回転点(x、y)を空間の原点に移動しtranslate(-x,-y)ます。
  2. 回転を行いますrotate(angle)(スケーリングもここで行われます)
  3. すべてを元のポイントに戻しtranslate(x,y)ます。

これらの手順を逆の順序で適用する必要があることを忘れないでください(trashgodの回答を参照)。

最初の変換を使用する文字列の場合、通常、バウンディングボックスの中心を原点に移動し、最後の変換を使用して、文字列を画面上の中心が表示される実際のポイントに移動します。そうすれば、好きな位置に文字列を描くことができます。

Rectangle2D r = g.getFontMetrics().getStringBounds(text, g);
g.translate(final_x, final_y);
g.rotate(-angle);
g.translate(-r.getCenterX(), -r.getCenterY());
g.drawString(text, 0, 0);

または代わりに

Rectangle2D r = g.getFontMetrics().getStringBounds(text, g);
AffineTransform trans = AffineTransform.getTranslateInstance(final_x, final_y);
trans.concatenate(AffineTransform.getRotateInstance(-angle));
trans.concatenate(AffineTransform.getTranslateInstance(-r.getCenterX(), -r.getCenterY()));
g.setTransform(trans);
g.drawString(text, 0, 0);
于 2011-04-15T05:12:12.510 に答える
2

これは、ニーズに合わせて変換行列を設計する方法についての純粋に数学的なビデオガイドですhttp://www.khanacademy.org/video/linear-transformation-examples--scaling-and-reflections?topic=linear-algebra

ただし、このマトリックスがどのように、そしてなぜ機能するのかを理解するには、おそらく以前のビデオを見る必要があります。とにかく、十分な忍耐力があれば、線形代数を学ぶのは良いリソースです。

于 2012-02-12T11:58:46.927 に答える
2

実際問題として、私は理解するのに役立つ2つのことを見つけましたAffineTransform

  1. ここで説明するように、グラフィックスコンテキスト、、またはインターフェイスGraphics2Dを実装する任意のクラスのいずれかを変換できます。Shape

  2. 連結された変換には、明らかに最後に指定された最初に適用された順序があります。これについてもここで説明します。

于 2011-04-14T23:28:33.813 に答える