« 小休止の重要性 | トップページ | 無駄なコード »

2010年6月14日 (月)処理を減らすための数学5

おはようございます。本日の当番、プログラマーのK.Yです。

前回のブログでアークタンジェントのお話をしましたが、
その話の最後の方で【 atan2 を自作する】のも方法の1つだと紹介しました。

今回はその自作の方法をどうしたらいいのか、
そもそも自作したその関数は本当に軽くなるのかなど、
いくつか例を挙げながら紹介をしていこうと思います。

まずは前回の復習から

アークタンジェント関数とは座標を渡すと角度が取得できる関数
例えばオブジェクトをプレイヤーの方向に向かせたい時などに使います。

オブジェクトの座標を ( ox , oy )
プレイヤーの座標を  ( px , py ) としたとき

そこまでのベクトルは以下のようになります。
vx = px - ox
vy = py - oy
このベクトル ( vx , vy ) をアークタンジェント関数に入れるとそこへの角度が取得できます。
そして、キャラクターの向きをその角度に回転させることで目的の方向を向くことになります。
 
2010_0611_01
 
 
では、いよいよ自作してみましょう。
(今回自作する関数は、ある程度その方向を向けばいいキャラクターに使うものです)

自作と言いましても、そんなすごい計算をするというわけではありません。
内容としては座標を渡したら角度を返すだけの関数ですので、
前もってデータを作っておき、その中から条件に合う値を返す感じで考えてみます。

というわけでまずは以下のようなデータを用意します。

  |y|/|x| 角度(°)
  0.00000  0
  0.01746  1
  0.03492  2
  0.05241  3
  0.06993  4
  0.08749  5
  :
  1.00000  45
  :
 19.08113  87
 28.63626  88
 57.28996  89

で、この関数に渡された x y の絶対値の比を上のデータから順番に見ていって
その数を超えたところの角度を返します。
例えば
x = 100
y = 6
の時は、その比が 0.06 になりますので取得できる角度は 3°になります。

この後 x y のそれぞれの符号を見ることで実際の角度に変更します。
x プラス ・y プラス :そのまま
x プラス ・y マイナス:取得した角度をマイナスにする
x マイナス・y プラス :180°から取得した角度を引く
x マイナス・y マイナス:180°から取得した角度を引いたものをマイナスにする

ここで注意しないといけないことがいくつかあります。

ひとつは、渡した x の値が 0 の時の場合です。
比を出すために割ろうとするとゼロ徐算になってしまいプログラムが動きません。
この関数の頭で x が 0 の時のチェックをを忘れないようにしましょう。

そしてもうひとつは、比の値が 57.29004 を超えた場合です。
この場合はこれ以上比べる数値がありませんので返す角度は 90°になります。

以上で一応角度の取得はできるようになりました。
しかし、このままでは atan2f と処理負荷はあまり変わりません。
というか、むしろこっちの方が処理負荷がかかってしまう場合もあります。
 
 
というわけでここからが処理軽減の本題になります。
上で紹介した関数にさらに手を加えていきましょう。
やり方はいろいろあるとは思いますが、今回は簡単にできそうな方法をいくつか紹介します。
 
 
処理軽減の方法その1:データ量を減らす

上の例では、角度 0°から 90°の間で 1°ごとに取得するデータを使っています。
ゲームの仕様にもよりますが、もう少し大雑把な角度の取得でいいのであれば
この取得する角度を 2°や 3°ごとにすることで調べるデータ量を半分以下にできます。
当然ながら処理速度もそれだけ減らすことができます。
 
 
処理軽減の方法その2:渡した値が真ん中より大きいか小さいかでデータの参照場所を変える

これは、方法その1が使えない時や、データ量を減らしたとしてもまだデータが大きな場合に使えます。
例えば上で使っているデータでいうと、比:1.00000 角度:45°の場所がちょうど真ん中になります。
ですので x y の絶対値の比が 1.00000 より大きいか小さいかでデータを見ていく場所を変えていきます。

まずは、関数の一番上で、比の値を調べます。
そして、例えば 1.00000 より小さかったら最初から真ん中まで調べればいいですし、
1.00000 より大きかったら真ん中から最後まで調べていけば必要な値が取得できます。
これだけで、元々の関数からは半分の処理で済むようになります。

あとはこの方法の1・2をうまく組み合わせることでさらなる処理軽減も可能になってきます。
 
 
今回は座標から角度を求めるためのデータを例としてあげましたが
それ以外にも大きなデータから必要な値を取得する場面はいろいろとあると思います。

みなさんも、関数が1つできたからとそこで安心することなく、
その関数をさらに軽くすることができないか考えてみてはどうでしょうか?
オブジェクトを1個多く出せたりエフェクトを少しだけ豪華にできるかも知れませんよ。

follow us in feedly
result = encodeURIComponent( "http://www.accessgames-blog.com/blog/2010/06/post-f00d.html" );document.write( "result = " , result );&media=https%3A%2F%2Ffarm8.staticflickr.com%2F7027%2F6851755809_df5b2051c9_z.jpg&description=Next%20stop%3A%20Pinterest">

| | コメント (0) | トラックバック (0)

« 小休止の重要性 | トップページ | 無駄なコード »

プログラマー」カテゴリの記事

コメント

この記事へのコメントは終了しました。

トラックバック


この記事へのトラックバック一覧です: 処理を減らすための数学5:

« 小休止の重要性 | トップページ | 無駄なコード »