Sorry your browser is not supported!

You are using an outdated browser that does not support modern web technologies, in order to use this site please update to a new browser.

Browsers supported include Chrome, FireFox, Safari, Opera, Internet Explorer 10+ or Microsoft Edge.

Code Snippets / [DBC/DBP] Distance calculation between two objects

Author
Message
TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 4th May 2008 20:53
This function will return the distance between two objects:



How to use:
dis#=get distance(player x, player y, player z, enemy x, enemy y, enemy z)

With this you can calculate where the nearest enemy is

Oooooops!!! I accidentally formated drive c.
Zotoaster
19
Years of Service
User Offline
Joined: 20th Dec 2004
Location: Scotland
Posted: 4th May 2008 21:46
You can't put a space in a function in DBC or DBP.

Don't you just hate that Zotoaster guy?
KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 4th May 2008 22:29
Not wanting to steal any of your thunder, but in the interests of sharing what I've found...

The code you posted works well, but is slow. There's another method using vector length, but it's slow too.

In another thread there were several of us that tested a few theories and came up with the following solution as the least processor intensive way to get a distance between two objects.



In effect it's the same calculations as the formula you showed. It just uses fewer processor cycles to do it.

Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 5th May 2008 07:56 Edited at: 5th May 2008 08:21
@KISTech
In this scenario:
Quote: "With this you can calculate where the nearest enemy is"

The method you propose is very applicable for comparing known values at a good speed(for example if you were going to slice more processing time off you wouldn't use if dist# <= (500 * 500); but instead if dist# <= 250000) but it doesn't return the distance between two points (the unknown value).

Still on your method, wouldn't it even be faster to (though I haven't tested the speed of this ) :



Enjoy your day.
KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 5th May 2008 19:35
Fair enough, although once you call the function you can use dist# for your exact distance amount in whatever comparison you need.

Quote: "
if abs(x2#-x1#) > xdst# or abs(y2#-y1#) > ydst# or abs(z2#-z1#) > zdst#
"


A similar method was proposed in the thread where we were looking for the fastest calculation for distance and it was proven to be inacurate.

Quote: "
slice more processing time off you wouldn't use if dist# <= (500 * 500); but instead if dist# <= 250000)
"


True, that was mainly a way to simplify the use, but yes, that would speed things up a bit too.. (pun intended..)

With this function you can set your comparison range in a variable. You only have to set that once before your comparison loop. So at somewhere in the program you say range# = 500 * 500 using 500, because it's easier to think in terms of your game units then to square it each time you want to think about it. So with your range set the distance comparison can run very quickly in a loop. If at some point you need the actual distance then you can take dist# and get the square root of it. You're still doing the basic calculations from the original post, just not through every loop.

Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 5th May 2008 22:42
Quote: "A similar method was proposed in the thread where we were looking for the fastest calculation for distance and it was proven to be inacurate"

Of course, even just at a 45 degree angle the actual distance would be farther than the limits of xdst#,ydst# and zdst# - I should have seen that coming!

Quote: "If at some point you need the actual distance then you can take dist# and get the square root of it"

That makes sense. Don't use the sqrt until you actually need it. If you're just comparing a range you might not need the true distance.

Enjoy your day.
Scraggle
Moderator
20
Years of Service
User Offline
Joined: 10th Jul 2003
Location: Yorkshire
Posted: 7th May 2008 16:56
Quote: "There's another method using vector length, but it's slow too."


Are you sure?

The tests I have made show vector length to be by far the fastest method.



KISTech
16
Years of Service
User Offline
Joined: 8th Feb 2008
Location: Aloha, Oregon
Posted: 7th May 2008 18:56
Here's the code I submitted in the other thread to see if we could prove out the question of which method was faster.

The "Simple Distance" formula was consistently faster.

Now, one might say "Of course it's faster, you aren't getting the sqrt until after the timed loop.", however, that's the point of the exercise. If you need a distance then you can get it any time, if you need to compare the distance to a known value, then in your comparison you multiply the value by itself and compare it with the distance result. No sqrt needed, which speeds it up considerably.

The savings is of course just a few milliseconds, but if you're doing that comparison even a few hundred times each loop, it adds up quick.



TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 10th May 2008 23:09
@KisTech

That is a great solution for DBP, but it also has to work with DBC. The fastest method for DBC (I think) is this one:



Oooooops!!! I accidentally formated drive c.
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 11th May 2008 04:09
I'll bet the length command is just the distance formula but it's in machine code under the hood and therefore isn't subject to translation of the BASIC equivalents (sqrt x*x etc ) - that's why it seems faster. I wrote a DLL function of the distance formula (for DBC) and of course it's way faster than the same function in DBC. So if we really wanted to crank out the speed, a custom DLL function WITHOUT the sqrt() would probably fly!

Enjoy your day.
TheComet
16
Years of Service
User Offline
Joined: 18th Oct 2007
Location: I`m under ur bridge eating ur goatz.
Posted: 11th May 2008 21:23
You wrote it? Post it!

Oooooops!!! I accidentally formated drive c.
Latch
17
Years of Service
User Offline
Joined: 23rd Jul 2006
Location:
Posted: 14th May 2008 01:04 Edited at: 14th May 2008 01:05
Quote: "You wrote it? Post it!"

The distance function is part of a math DLL and I'm not sure I'm ready to make that public domain. However, I did put together an example that returns the squared distance value. If I return a float directly from the DLL in a large loop, DBC returns garbage. It seems that DBC can't update the float variable as fast as it can be calculated in the DLL function. To solve this, I return the float in a memblock pointer and use the memblock to retrieve the result.

In the following example, the DLL actually calculates the formula twice internally. One for the return value (if you don't put the call in a loop) and 1 for the memblock. Both values are returned but you'll notice the memblock value is consistant. Even with this double calculation, the function is about twice as fast as native DBC. However, once SYNC is set, both methods are subject to the loop rate set as a result of the screen refressh. In the example with the two times calculating DLL function, it is a little bit slower than DBC. However, when I remove the second calculation and only return the memblock value, it is a little bit faster.

This DLL is for example purposes only - it has two calculations and is set to return a float. Ideally there would be one calculation and no return value - just the memblock being updated through it's pointer. Example attached.

Enjoy your day.

Attachments

Login to view attachments

Login to post a reply

Server time is: 2024-05-04 23:39:32
Your offset time is: 2024-05-04 23:39:32