Advertisement

Distance Formula Too Slow

Started by February 12, 2000 04:08 PM
7 comments, last by nes8bit 25 years ago
How can you make this faster? Function Distance(Orig as D3DVECTOR, Dest as D3DVECTOR) as single Distance = ((Orig.X - Dest.X)^2 + (Orig.X - Dest.X)^2 + (Orig.X - Dest.X)^2) ^ .5 End Function I tried to subtract the verticies first and multiply them by themselves then sqr''d them and increased the framerate slightly. I was wondering if there is a faster function or just an faster way to square root it.
If you only need the distace values for comparison,
you could just compare squares of distances.
Advertisement
The square root function is very slow, it takes many cycles. Make yourself a lookup table, and precalculate it before the start. This is the only thing I can think of.
Andre LaMothe includes a distance between two points function in Tricks of the Windows Game Programming Gurus. Its not quite as accurate (within 3%), but it may well be good enough for you. It shouldn''t be hard to modify it to use D3DVECTORs.

Here it is:
float Fast_Distance_3D(float fx, float fy, float fz){// this function computes the distance from the origin to x,y,zint temp;  // used for swapingint x,y,z; // used for algorithm// make sure values are all positivex = fabs(fx) * 1024;y = fabs(fy) * 1024;z = fabs(fz) * 1024;// sort valuesif (y < x) SWAP(x,y,temp)if (z < y) SWAP(y,z,temp)if (y < x) SWAP(x,y,temp)int dist = (z + 11*(y >> 5) + (x >> 2) );// compute distance with 8% errorreturn((float)(dist >> 10));}
hmm, great! Just what I was looking for. I ported the code, but what do these things do?

SWAP(x,y,temp)
is it like iif?

(y >> 5) + (x >> 2)
does this perform bit-shifting?

I''m clueless and C++ impared.
Swap is probably a macro that just swaps the value of the first two parameters in it.

>> is bit shifting , so (y >> 5) is basically a cheap way to divide y by 32 (32 = 2^5).

>> is divison by powers of 2, and << is multiplication by powers of 2.
Advertisement
Code for using table based Square root.

#include
#include

/* MOST_SIG_OFFSET gives the (int *) offset from the address of the double
* to the part of the number containing the sign and exponent.
* You will need to find the relevant offset for your architecture.
*/

#define MOST_SIG_OFFSET 1

/* SQRT_TAB_SIZE - the size of the lookup table - must be a power of four.
*/

#define SQRT_TAB_SIZE 16384

/* MANT_SHIFTS is the number of shifts to move mantissa into position.
* If you quadruple the table size subtract two from this constant,
* if you quarter the table size then add two.
* Valid values are: (16384, 7) (4096, 9) (1024, 11) (256, 13)
*/

#define MANT_SHIFTS 7

#define EXP_BIAS 1023 /* Exponents are always positive */
#define EXP_SHIFTS 20 /* Shifs exponent to least sig. bits */
#define EXP_LSB 0x00100000 /* 1 << EXP_SHIFTS */
#define MANT_MASK 0x000FFFFF /* Mask to extract mantissa */

int sqrt_tab[SQRT_TAB_SIZE];

void init_sqrt_tab()
{
int i;
double f;
unsigned int *fi = (unsigned int *) &f + MOST_SIG_OFFSET;

for (i = 0; i < SQRT_TAB_SIZE/2; i++)
{
f = 0; /* Clears least sig part */
*fi = (i << MANT_SHIFTS) / (EXP_BIAS << EXP_SHIFTS);
f = sqrt(f);
sqrt_tab = *fi & MANT_MASK;

f = 0; /* Clears least sig part */
*fi = (i << MANT_SHIFTS) / ((EXP_BIAS + 1) << EXP_SHIFTS);
f = sqrt(f);
sqrt_tab = *fi & MANT_MASK;<br> }<br>}<br><br>double fsqrt( double f)<br>{<br> unsigned int e;<br> unsigned int *fi = (unsigned int *) &f + MOST_SIG_OFFSET;<br><br> if (f == 0.0) return(0.0);<br> e = (*fi >> EXP_SHIFTS) - EXP_BIAS;<br> *fi &= MANT_MASK;<br> if (e & 1)<br> *fi /= EXP_LSB;<br> e >>= 1;<br> *fi = (sqrt_tab[*fi >> MANT_SHIFTS]) /<br> ((e + EXP_BIAS) << EXP_SHIFTS);<br> return(f);<br>} </i>
you need to include math.h and stdio.h. Sorry if this board fudged up the formatting of the code.
Thanks Kyle Radue. I just wanted to claify those functions. As for the Anonymous Poster, when I meant C++ impared, I meant that I know Visual Basic and barely know C++. Thanks for the code. I have no clue on how to use it.
I''ll figure out how to use it though.

This topic is closed to new replies.

Advertisement