home  forum  showcase  royalty-free  sign in  register   
 
   Forum forum >> BlitzCoder >> Distances

Recent discussions

Borderlands Tweaks by gosse on Tue 27 Oct 2009 at 21:24:25
Some upcoming game titles I'm waiting for by heirauqs on Sat 22 Aug 2009 at 18:23:29
WrapText: a new text function for Blitz by gosse on Sat 9 Aug 2008 at 20:18:57
3D lines for Blitz3D by gosse on Sat 9 Aug 2008 at 20:18:21
PointTowardEntity(+Normalized) by gosse on Sat 9 Aug 2008 at 20:17:50
Faked Object-Oriented Programming by gosse on Sat 9 Aug 2008 at 20:16:27
Distances by gosse on Sat 9 Aug 2008 at 20:15:52
indieground.com is being worked! by gosse on Tue 25 Mar 2008 at 23:30:35
Still alive by gosse on Thu 7 Feb 2008 at 00:38:48
Blitzcoder is down? by gosse on Sun 7 Oct 2007 at 15:52:05

Back to BlitzCoderPage 1

 Distances on Sat 9 Aug 2008 at 20:15:52
 

gosse
  Administrator
indieground.com
Posts: 86



Joined: Apr 2006
Location: Montreal, QC, CA

 

(reposted from Nuloen forum - May 10, 2004)
I have been toying around with distances between entities or 3D coordinates.
I've come up with a couple tests:
Code


Graphics3D 640, 480
SetBuffer BackBuffer()
tmrFPS = CreateTimer(40)
SeedRnd MilliSecs()

pvt1 = CreatePivot()
pvt2 = CreatePivot()
PositionEntity pvt1, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500
PositionEntity pvt2, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500

Cls
tmr = MilliSecs() + 1000
i = 0
While tmr > MilliSecs()
    If EntityDistance(pvt1, pvt2) < 1000 Then
    End If
    i = i + 1
Wend
Print "Checks with EntityDistance: " + i
tmr = MilliSecs() + 1000
i = 0
While tmr > MilliSecs()
    If EntityRange(pvt1, pvt2, 1000) Then
    End If
    i = i + 1
Wend
Print "Checks with sqr'ed distance and range: " + i
While Not KeyDown(1)
    WaitTimer tmrFPS
Wend

While Not KeyDown(1)

    WaitTimer tmrFPS

    Cls
    
    RenderWorld
    
    Flip
    
Wend

End

Function EntityRange(entity1, entity2, iRange)
    Return CheckRange(EntityX(entity1), EntityY(entity1), EntityZ(entity1), EntityX(entity2), EntityY(entity2), EntityZ(entity2), iRange)
End Function

Function CheckRange(x1#, y1#, z1#, x2#, y2#, z2#, iRange)
    width# = x1# - x2#
    height# = y1# - y2#
    depth# = z1# - z2#
    Return ((witdh * width + depth * depth + height * height) < iRange * iRange)
End Function


This compares using either EntityDistance or getting the EntityXYZ coords and checking with a squared range (so no performance is lost due to a square root).

What I've found out with those tests is that EntityDistance is faster because calling EntityXYZs costs a lot of process time.

But if you use predefined values (variables) for the position, it will be a lot faster.

This led me to try something else:
Code


Graphics3D 640, 480
SetBuffer BackBuffer()
tmrFPS = CreateTimer(40)
SeedRnd MilliSecs()

Function PointDistance1#(x1#, y1#, z1#, x2#, y2#, z2#)
    width# = x1# - x2#
    height# = y1# - y2#
    depth# = z1# - z2#
    Return Sqr#(witdh * width + depth * depth + height * height)
End Function

Function PointDistance2#(x1#, y1#, z1#, x2#, y2#, z2#)
    pvt1 = CreatePivot()
    pvt2 = CreatePivot()
    PositionEntity pvt1, x1, y1, z1
    PositionEntity pvt2, x2, y2, z2
    dist# = EntityDistance(pvt1, pvt2)
    FreeEntity pvt1
    FreeEntity pvt2
    Return dist#
End Function

Global opvt1 = CreatePivot()
Global opvt2 = CreatePivot()
Function PointDistance3#(x1#, y1#, z1#, x2#, y2#, z2#)
    PositionEntity opvt1, x1, y1, z1
    PositionEntity opvt2, x2, y2, z2
    Return EntityDistance(opvt1, opvt2)
End Function

Function PointDistanceSqr#(x1#, y1#, z1#, x2#, y2#, z2#)
    width# = x1# - x2#
    height# = y1# - y2#
    depth# = z1# - z2#
    Return (witdh * width + depth * depth + height * height)
End Function


pvt1 = CreatePivot()
pvt2 = CreatePivot()
PositionEntity pvt1, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500
PositionEntity pvt2, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500

Cls
tmr = MilliSecs() + 1000
i = 0
While tmr > MilliSecs()
    If pointdistance1(Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500) Then
    End If
    i = i + 1
Wend
Print "calculations: " + i
tmr = MilliSecs() + 1000
i = 0
While tmr > MilliSecs()
    If pointdistance2(Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500) Then
    End If
    i = i + 1
Wend
Print "create & free pivots + entitydistance: " + i
tmr = MilliSecs() + 1000
i = 0
While tmr > MilliSecs()
    If pointdistance3(Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500) Then
    End If
    i = i + 1
Wend
Print "use global pivots and entitydistance: " + i
tmr = MilliSecs() + 1000
i = 0
While tmr > MilliSecs()
    If pointdistancesqr(Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500, Rnd(0, 1000) - 500) Then
    End If
    i = i + 1
Wend
Print "pointdistance squared: " + i
While Not KeyDown(1)
    WaitTimer tmrFPS
Wend

While Not KeyDown(1)

    WaitTimer tmrFPS

    Cls
    
    RenderWorld
    
    Flip
    
Wend

End


This compares 4 things:
Using pythogorean calculations, creating pivots and using entitydistance, using global pivots with entitydistance and using calculations but return the square value of the distance, not losing CPU time making the square root as they are costly.

Obviously, creating pivots and using entitydistance was awfully slow and really not a viable method.
However, I was about certain that using global pivots would be d**n quick, but I was proved wrong. It was quick, but using the calculations was faster.
And also, using calculations without the square root was even faster.

Conclusions
If you need to compare the distance of 2 Blitz entities you are better off using EntityDistance.
However, if their coordinates are already stored into memory (so you don't have to call entityXYZ, or they are already called anyways), you are gaining speed by using a custom PointDistance function.
If you only need to check with a simple range, you can gain another bit of speed by using a PointDistanceSquared function and checking with the squared range (Range*Range).


Last edited on Tue 16 Jun 2009 at 01:31:12 by gosse.

-gosse

Back to BlitzCoderPage 1

5 guests online. 32 visitors in the last 24 hours.