Posted: 27th Nov 2002 10:39
Here is a little function to calculate the distance between two point in a Three-Dimensional space. Only tested in DB V1.x, but should work in DBPro.

Syntax:
Dist3D(x1,y1,z1,x2,y2,z2)
-> x1, y1 and z1 is the xyz co-ordinate of the first object.
-> x2, y2 and z2 is the xyz co-ordinate of the second object.

The Function:
Function Dist3D(x1,y1,z1,x2,y2,z2)
EndFunction SQRT(SQRT(ABS(x1-x2)^2+ABS(y1-y2)^2)+ABS(z1-z2)^2)
Posted: 27th Nov 2002 17:31
you dont need the ABS's as squaring any number will always have a positive result.
Posted: 27th Nov 2002 19:03
Are you sure, that this really works? Okay, I do not mean the formula, this one is a well known formula, but:
Function Dist3D(x1,y1,z1,x2,y2,z2)
EndFunction SQRT(SQRT(ABS(x1-x2)^2+ABS(y1-y2)^2)+ABS(z1-z2)^2)
I had to change to
Function Dist3D(x1,y1,z1,x2,y2,z2)
Value=SQRT(SQRT((x1-x2)^2+(y1-y2)^2)+(z1-z2)^2)
EndFunction Value
No idea why, but your version allways result a 0 in Dark Basic Pro. Probaly a DBP Bug again? (Patch3 applied).
Posted: 27th Nov 2002 20:34
By removing the use of powers (i.e. ^2) you can make this function quicker:

function Dist3D(x1,y1,z1,x2,y2,z2)
xd = x1 - x2
yd = y1 - y2
zd = z1 - z2
value = sqrt(sqrt((xd*xd) + (yd*yd)) + (zd*zd))
endfunction value
Posted: 27th Nov 2002 22:43
hmm... it's a standard length formula... interesting. You realize that that's the easiest way to do collision detection on cylinders and spheres? It would be much faster than box collision because it's only one equation...
Posted: 28th Nov 2002 10:47
The way I wrote the code works fine in DBC.
And thanks for telling me that Powers slow down the code and that squaring will always get positive.
Posted: 2nd Dec 2002 9:23
...hang on, just discoverd that the formula for distance in 3D is this:

distance = sqrt((x1-x2)^2 + (y1-y2)^2 + (z1-z2)^2)

So your function should be:

function Dist3D(x1,y1,z1,x2,y2,z2)
xd = x1 - x2
yd = y1 - y2
zd = z1 - z2
value = sqrt((xd*xd) + (yd*yd) + (zd*zd))
endfunction value
Posted: 2nd Dec 2002 14:11
Is someone going to do this as a plug-in ?
Posted: 2nd Dec 2002 22:52
?
a plugin? for what?
Posted: 3rd Dec 2002 10:21
Easily Confused:
Are you sure you only need one SQRT() function?
If yes... well.. this funtion is getting faster everytime I come back.

Thanks guys
TheCyborg
Posted: 3rd Dec 2002 10:27
But why not put all the calculations on one line, and make it available for real numbers:

function Dist3D(x1,y1,z1,x2,y2,z2)
Distance#=SQRT(((x1-x2)*(x1-x2))+((y1-y2)*(y1-y2))+((z1-z2)*(z1-z2)))
endfunction Distance#
Posted: 3rd Dec 2002 11:18
One thing I've noticed about all of these is that no one is using FLOAT variables. Kinda needed to get accurate distance in 3D.

-Kensupen
Posted: 3rd Dec 2002 15:17
Give me till tonight and i will try and make a DLL with a distance command in it
Posted: 3rd Dec 2002 15:23
That provideing i can find out what the SQRT command is in C++ :S
Posted: 3rd Dec 2002 17:11
Skid:

Save your work and d/l this DLL:

http://mic.ha.bei.t-online.de/Files/Magicdll.zip


CU,
MONOS
Posted: 3rd Dec 2002 17:44
To late, i already finished it i just don't have DB at college to test it. I only made the dll so it has the one easy to use command in it, so if it works it this command should be valid: return = distance(x1,x2,y1,y2,z1,z2) if it works i'll upload it
Posted: 4th Dec 2002 3:36
TheCyborg:
Yep It's correct, I typed "3D math" into google (in quotes) and I found several examples there.

As for placing your calculations on one line, your way is slightly slower because your function would be calculating things like x1-x2 twice, which, if you need this for gaming where speed is paramount, is small waste of clock cycles.

Consider this test:

+ Code Snippet
sync on
sync rate 0

set text opaque

text 0,0,"Easily Confused's function:"
text 0,48,"TheCyborg's function:"
sync

repeat

  rem --- Easily Confused's Test
  count = 0 : ti = timer()
  repeat
    d#=Dist3DTest1(100,100,100,500,500,500)
    inc count,1
  until (timer() - ti) >= 1000

  text 16,16,str$(count)+" calls per sec.  "
  sync

  rem --- TheCyborg's Test
  count = 0 : ti = timer()
  repeat
    d#=Dist3DTest2(100,100,100,500,500,500)
    inc count,1
  until (timer() - ti) >= 1000

  text 16,64,str$(count)+" calls per sec.  "
  sync

until spacekey()

end

function Dist3DTest1(x1#,y1#,z1#,x2#,y2#,z2#)
  xd# = x1# - x2#
  yd# = y1# - y2#
  zd# = z1# - z2#
  Distance# = sqrt((xd#*xd#) + (yd#*yd#) + (zd#*zd#))
endfunction Distance#

function Dist3DTest2(x1#,y1#,z1#,x2#,y2#,z2#)
  Distance#=SQRT(((x1#-x2#)*(x1#-x2#))+((y1#-y2#)*(y1#-y2#))+((z1#-z2#)*(z1#-z2#)))
endfunction Distance#


On my somewhat pathetic AMD 650, My function gets about 123000 calls per second, and yours about 121000. A small difference I know, but noticable.

I win, where's my prize!
Posted: 4th Dec 2002 7:30
...that's strange, I just ran the test again, and now they are about equal at 127000 calls a second. Must have had something to to with what background tasks I have running.

Maybe I should'nt claim my prize after all.
Posted: 4th Dec 2002 11:01
Right, i've made the plugin, it works but theres a math error with im fixing today, when its finished it will work as a user plugin on DBPro, and with a dll call function
Posted: 8th Dec 2002 13:10
If you put the code into a c++ dll, you should find that the optimiser gets rid of the duplicate calculations by caching the results and reusing them later.

If you are coding in DBPro, then you would need to do this yourself with temporary variables - but the difference will only be a couple of clock cycles.

Only something to worry about if you are doing a tens of thousands comparisons a second