2点間の距離
を計らなければいけなくなりました。
まぁ、単純な公式ですよね。
以下のような感じです。
√((x2-x1)^2+(y2-y1)^2)
コレをリアルタイムに延々とやる必要があるわけですね。
でも何となくね。遅いと思うのよ。
そんなにスペック気にしてもってのは有るけどやっぱプログラマーたるもの気にしたいじゃない?
で、確かルートのfakeなアルゴリズムがあったと思ったのでちょっと調べてみる。
しかし割りと精度が要求される気もするのでまずいかなぁと思いつつ。
waybackmachineでdemo.and.or.jpを検索。ソースをにょろにょろと引っ張ってきて見る。
対象のプラットフォームはJAVAなので元から数値演算が早いからbenchとって見ないと使い物にならないかもなぁ。
でも私の記憶してるのはこれじゃないんだよなぁ。
もっと単純なアルゴリズムで効果的なアルゴリズムがあったはず・・・。
色々調べていったらnvidiaのfastmath.cppって言うものを発見。
コレもまた消えていたのでwaybackmachine。
cppなんだけど中身はほぼCなので私のようなヘタレCPP使いでも読めます(笑)
とりあえずsqrtの部分だけ読んでみる・・・
#define FP_BITS(fp) (*(DWORD *)&(fp)) static unsigned int fast_sqrt_table[0x10000]; typedef union FastSqrtUnion { float f; unsigned int i; } FastSqrtUnion; void build_sqrt_table() { unsigned int i; FastSqrtUnion s; for (i = 0; i <= 0x7FFF; i++) { // Build a float with the bit pattern i as mantissa // and an exponent of 0, stored as 127 s.i = (i << 8) | (0x7F << 23); s.f = (float)sqrt(s.f); // Take the square root then strip the first 7 bits of // the mantissa into the table fast_sqrt_table[i + 0x8000] = (s.i & 0x7FFFFF); // Repeat the process, this time with an exponent of 1, // stored as 128 s.i = (i << 8) | (0x80 << 23); s.f = (float)sqrt(s.f); fast_sqrt_table[i] = (s.i & 0x7FFFFF); } } inline float fastsqrt(float n) { if (FP_BITS(n) == 0) return 0.0; // check for square root of 0 FP_BITS(n) = fast_sqrt_table[(FP_BITS(n) >> 8) & 0xFFFF] | ((((FP_BITS(n) - 0x3F800000) >> 1) + 0x3F800000) & 0x7F800000); return n; }
えーっと・・・。
さっぱり解りません(笑)
いややってることは解るんですけど何でコレで√になるの?
うーむ。気もちわりぃ。
気持ち悪いけど早いなら使います。
ええ。それが私の生きる道。