the engine is crazy

If you are a new Irrlicht Engine user, and have a newbie-question, this is the forum for you. You may also post general programming questions here.
Post Reply
Guest

the engine is crazy

Post by Guest »

example to get distance from nodes or vectors:

--------------------------------------------------------------
float Distance(vector3df p1, vector3df p2){
float distance = 0;
distance = sqrt(pow(p1.X - p2.X, 2) + pow(p1.Y - p2.Y, 2) + pow(p1.Z - p2.Z, 2));

return distance;
}

----------------------------------------------
vector3df a(0,0,10);
vector3df b(0,0,40);
//f32 vdist = a.getDistanceFrom(b);

float vdist = Distance(a,b);
printf("vdist = %d\n\n", vdist);

================ RETURNS 0 OR CRAZY NUMBERS.

And from the API:

float vdist =a.getDistanceFrom(b);
printf("vdist = %d\n\n", vdist);

============== RETURNS TOO '0' OR CRAZY NUMBERS.

I don't understand anything.
Guest

Re: the engine is crazy

Post by Guest »

Sorry, the problem is the format of printf and the conversion from float to int.

This work OK:

f32 vdist = v.getDistanceFrom(vpos); // <--- from the API of irrlitch
printf("vdist = %f\n\n", vdist);

(returns OK the distance beetween two vectors).
[dx/x]=HUNT3R
Posts: 271
Joined: Sat Aug 23, 2003 5:52 pm
Location: Hurricane Central, Florida

Post by [dx/x]=HUNT3R »

The problem with your distance function was instead of

sqrt(pow(p1.X - p2.X, 2).....

you should of had

sqrt(pow(p2.X - p1.X, 2).....

You were getting wierd answers because you were trying to take the square root of a negative number which is an imaginary result.
Lonesome

Post by Lonesome »

The order of the numbers won't matter, because you are squaring that number. When it is taken to the power of 2, it will cancel out the negative.
[dx/x]=HUNT3R
Posts: 271
Joined: Sat Aug 23, 2003 5:52 pm
Location: Hurricane Central, Florida

Post by [dx/x]=HUNT3R »

Good point... I don't know why he was getting crazy numbers then...
Guest

Post by Guest »

No problem, the simple code with the function vx.getDistanceFrom(vz), works OK from the API, in the vector3df.h.

float vdist =a.getDistanceFrom(b);
printf("vdist = %d\n\n", vdist);

thanks.
tester

Post by tester »

testing....

ok. you guys passed. :)
BlackNinjaGames
Posts: 31
Joined: Mon Sep 05, 2005 4:47 pm
Contact:

Post by BlackNinjaGames »

You probably already know this, but it is faster to say:

Code: Select all

dx*dx;
Rather than:

Code: Select all

pow(dx,2);
So a distance function might look like this:

Code: Select all

float Distance(vector3df p1, vector3df p2)
{
    float dx = p1.x - p2.x;
    float dy = p1.y - p2.y;

    return sqrt(dx*dx+dy*dy);
} 
Not like it matters, since you solved your problem. Just for future reference...
:)
hybrid

Post by hybrid »

BlackNinjaGames wrote:You probably already know this, but it is faster to say:

Code: Select all

dx*dx;
Rather than:

Code: Select all

pow(dx,2);
No, I also thought it wouldn't make a difference, but it's definitely not true! It's often much better to use functions if you're using math expressions. For example for squaring it's much better to use pow because it can be changed to bit shifting by good macros. This is more complicated if you write a usual multiplication. Just be sure that your math header use inline expressions, not real function calls.
So a distance function might look like this:

Code: Select all

float Distance(vector3df p1, vector3df p2)
{
    float dx = p1.x - p2.x;
    float dy = p1.y - p2.y;

    return sqrt(dx*dx+dy*dy);
} 
It's best to use hypot(dx,dy), because this is really optimizable depending on the arithmetics your processor supports. Try to rely on optimizations your (standard) libraries support.
BlackNinjaGames
Posts: 31
Joined: Mon Sep 05, 2005 4:47 pm
Contact:

Post by BlackNinjaGames »

Actually, my benchmarks have proven otherwise.

Calling functions produces overhead. I bet that is the main reason that using your methods are slow. It may be more readable, but that doesnt matter.

Here are the results of the benchmark:
http://www.blackninjagames.com/distance_benchmark.htm

:wink:
hybrid

Post by hybrid »

You should apply aggressive optimization flags, cause otherwise all functions stated as such will remain functions. This truly introduces a major drawback. BTW: Which compiler and compiler flags did you use?
hybrid

Post by hybrid »

Just another quite important thing to mention. sqrt, pow, and hypot are using double precision while your multiplication uses single precision. Try using the functions with an f attached (e.g. sqrtf). And note that some calculations might be slower as long as you stick to IEEE arithmetics. Depends on your compiler if and how to switch that off.
hybrid

Post by hybrid »

So one thing: You're using ints for your sqrt method which could yield very different results. But more importantly: I did the same test on my machine. Here are the results. (Numbers are not comparable to the other benchmark since this was done on Linux, gcc 3.3.3)

Code: Select all

hybrid@zola:g++ -Wall -O4 -ffast-math -march=pentium test.c
hybrid@zola:./a.out
Starting test #1
Starting test #2
Starting test #3
Using sqrt() and multiplies:    21693
Using sqrt() and pow():         145137
Using hypot():  21509
hybrid@zola:g++ -Wall -O4  -march=pentium test.c
hybrid@zola:./a.out
Starting test #1
Starting test #2
Starting test #3
Using sqrt() and multiplies:    253840
Using sqrt() and pow():         350572
Using hypot():  371283
Note that the IEEE precision makes everything much slower (second result), and that without this overhead hypot is faster. Also note that this is only using pentium optimization, could be that newer architectures have much better support for such kind of commands (or worse, it's sometimes not monotonic ...). Anyway, it's usually best to put everything into well structured ways cause that way automatic optimizations can be applied best. It's even more important if you're using high-performance math libraries, or automatically distributed computations such as MPI. You would not get any benefits for the manually optimized code!
Another last minute result: Use of sqrtf and hypotf makes everything up to 4 times faster, while powf makes it about 10 times worse :?
BlackNinjaGames
Posts: 31
Joined: Mon Sep 05, 2005 4:47 pm
Contact:

Post by BlackNinjaGames »

Whoops, didnt even notice the ints.

Hrm, I tried your optimizations for hyopt and pow, but my method was still faster.

Also, I switched everything to double's and my method still ran the same, while, surpisingly, your ran slower. I find that pretty weird, since hypot() and pow() are double functions.

Well, I guess I'll just use mine and you use yours. 8) :?
Post Reply