4

以下のコードをより効率的にし、少しクリーンアップするために助けが必要です。

この画像に示されているように、xとyは画面全体の任意の点である可能性があり、角度tを見つけようとしています。ここで行数を減らす方法はありますか?

注:原点は左上隅にあり、右/下に移動すると正の方向に移動します

o := MiddleOfScreenX - x;
a := MiddleOfScreenY - y;

t := Abs(Degrees(ArcTan(o / a)));

if(x > MiddleOfScreenX)then
  begin
    if(y > MiddleOfScreenY)then
      t := 180 + t
    else
      t := 360 - t;
  end
else
  if(y > MiddleOfScreenY)then
    t := 180 - t;

コードはパスカルですが、同様の構文またはc++またはjavaを使用した他の言語での回答も問題ありません。

:= sets the variable to that value
Abs() result is the absolute of that value (removes negatives)
Degrees() converts from radians to degrees
ArcTan() returns the inverse tan
4

3 に答える 3

6

C関数については、このhttp://www.cplusplus.com/reference/clibrary/cmath/atan2/を参照してください。

atan2は2つの別々の引数を取るので、象限を決定できます。

pascalにはarctan2が含まれている可能性があります。http://www.freepascal.org/docs-html/rtl/math/arctan2.htmlまたはhttp://www.gnu-pascal.de/gpc/Run-Time-System.htmlを参照しください

o := MiddleOfScreenX - x;
a := MiddleOfScreenY - y;

t := Degrees(ArcTan2(o, a));
于 2012-06-20T21:19:15.407 に答える
3

コードの行数だけが、考慮する必要のある最適化であるとは限りません。三角関数は、1つの関数が計算を完了するのにかかる時間の点でコストがかかります(つまり、1つのcos()呼び出しでは、実装によっては数百の加算と乗算が必要になる場合があります)。

信号処理で一般的に使用される関数である離散フーリエ変換の場合、何千ものcos()およびsin()計算の結果が事前に計算され、大規模なルックアップテーブルに格納されます。トレードオフは、アプリケーションの実行時に多くのメモリを使用することですが、実行速度ははるかに速くなります。

次の記事を参照するか、「事前に計算されたひねり係数」の重要性を検索してください。これは、本質的に、事前に1トンの複素指数を計算することを意味します。

将来的には、最適化しようとしているもの(つまり、使用されているCPUサイクル、使用されているメモリのバイト数、コストなど)についても言及する必要があります。実行される命令、ひいては使用されるCPUサイクル数の観点から最適化することを意味していると想定することしかできません(つまり、CPUオーバーヘッドを削減したい)。

http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.34.9421&rep=rep1&type=pdf

于 2012-06-20T21:28:00.073 に答える
1

アークタンをどうするかを決定するために必要なテストは1つだけです。既存のテストはによって破壊された情報を回復しますAbs()

atan()通常、-pi/4からpi/4の範囲で戻ります。座標系は少し奇妙です。時計回りに90度回転して、「標準」の座標系を取得atanx/yますy/x。私はすでに頭の中でこれを解決するのに苦労しています。

とにかく、あなたのテストは、あなたがネガティブになっているならa、180度を加えるということである必要があると私は信じています。負の角度を避けたい場合; 負の場合は360度を追加します。

于 2012-06-20T21:30:39.423 に答える