# Estimating the Pythagorean Theorem

I wrote a function to calculate the distance between two positions:

``````
def distanceBetween(pos1, pos2):
xDiff = pos2.x - pos1.x
yDiff = pos2.y - pos1.y
dist = Math.sqrt(xDiff**2 + yDiff**2)
#    self.say(dist)
return(dist)
``````

However, this seems to tax the system. If I use this function in Summit’s Gate, the Chrome Browser crashes. Even on my powerful desktop system.

I suggest using the following approximation:

``````
def distanceBetween(pos1, pos2):
xDiff = pos2.x - pos1.x
yDiff = pos2.y - pos1.y
if xDiff < 0 :
xDiff = -xDiff
if yDiff < 0 :
yDiff = -yDiff

if xDiff > yDiff :
dist = xDiff + 0.33 *yDiff
else :
dist = yDiff + 0.33 *xDiff
#    self.say(dist)
return(dist)
``````

The answer returned is within 6% of the exact value and avoids the square and square root functions.

(Note: I see an old topic which says that you should be able to call distanceTo on other objects, but that didn’t seem to be working for me. I will re-investigate.)

1 Like

Pretty cool! You should be able to get to our distance function if you have a Vector object, then you can do `pos1.distance(pos2)`. If you have a unit or other visible object which has a `pos`, then you can do `unit1.distanceTo(pos2)`. Note that the first is `distance` and the second is `distanceTo`, unfortunately.

If you just have two plain `{x, y}` objects, you can make one into a Vector to get access to `distance` like this: `Vector(pos1.x, pos1.y).distance(pos2)`.

Also note that if you are just comparing distances and don’t care about the absolute value, you can always use `pos1.distanceSquared(pos2)` which also avoids the square root (the square root is the slow part).

Basically, everything you can do outside of player code will run a lot faster, because player code gets transpiled and error-checked and instrumented and all this stuff, whereas game engine code (even though it does the same things) just runs. CodeCombat’s implementation of Vector `distance`, for example, is pretty straightforward CoffeeScript:

``````  distance: (other, useZ) ->
dx = @x - other.x
dy = @y - other.y
sum = dx * dx + dy * dy
if useZ
dz = @z - other.z
sum += dz * dz
Math.sqrt sum

distanceSquared: (other, useZ) ->
dx = @x - other.x
dy = @y - other.y
sum = dx * dx + dy * dy
if useZ
dz = @z - other.z
sum += dz * dz
sum

``````
3 Likes

So an `{x, y}` object is not a vector by default? Probably that’s why some vector functions do not work with them?

I was trying to get the distance between a shells impact point and the catapult in Summit’s Gate, with varying results:

``````loop:
shell = self.findNearest(self.findEnemyMissiles())
catapult = self.findNearest(self.findByType("catapult"))
if shell and catapult:
self.say(shell +" "+ shell.targetPos.distance(catapult.pos))
``````

This gives a certain value in the first few seconds, then it gives an error: “Cannot read property ‘distance’ of undefined”

I tried to make the first object a vector:

``````        self.say(shell +" "+ Vector(shell.targetPos).distance(catapult.pos))
``````

This gives sometimes a `NaN` result, but if it “catches” a spear, I get a value.

I’m probably confusing things, but the situation is far from clear…

Hmm, I think probably you are finding the shell in the moment after it exploded but before it ceased to exist (while the explosion was ongoing). Maybe ignore shells without a `targetPos`? If `shell.targetPos` is defined, it’s already a Vector.

For reference, here’s the Vector class: https://github.com/codecombat/codecombat/blob/master/app/lib/world/vector.coffee

Thanks for the answer. I’m afraid it exceeds my understanding of code, but I will give it a try