---
title: Distance Measures Redux -- Unifying and Tweaking
tags: geometry
description: Revisiting discrete distance measures and tweaking them
category: math
date: 2016-08-29
modified: 2023-09-20
---

After [talking about distance
calculations](/2016/08/25/different-measures-of-distance.html) the other
day, I was thinking about how we could generalize the measures.

Looking back on the D&D distance calculation, I think it can encompass
civ and Manhattan distances, too.

![The shortest taxi drive](/images/post_2016_08_29/taxi_path.png){width=150 height=150}

First, for simplicity's sake, I'm going to refer to $x_d$ instead of
$|x_1 - x_2|$, and likewise for $y_d$. With that convenience, I'll
contract it to a single line rather than spreading it over
three. Finally, I'm going to discard the floor conversion ($\lfloor
\rfloor$) for the moment.

$$d = \max(x_d, y_d) - \min(x_d, y_d) + 1.5 \times (\min(x_d, y_d))$$

Note that "1.5". I think that's the trick. If we manipulate that, we
should be able to replicate the other, simpler calculations.

Remember that the 1.5 represents the cost of making a diagonal rather
than a cardinal move. Since taxis can only move cardinally, they take
two steps to move diagonally. Let's plug "2" into that and see what
happens:

$$d = \max(x_d, y_d) - \min(x_d, y_d) + 2 \times (\min(x_d, y_d))$$

The $\min$ cancels out a bit:

$$d = \max(x_d, y_d) + 1 \times (\min(x_d, y_d))$$

Which further simplifies:

$$d = x_d + y_d$$

Which is the Manhattan formula. Success!


![The shortest discrete drive](/images/post_2016_08_29/other_path.png){width=150 height=150}

Let's try it for the Civ distance. Where taxis take 2 moves to go
diagonally, civilizations do it in 1:

$$d = \max(x_d, y_d) - \min(x_d, y_d) + 1 \times (\min(x_d, y_d))$$

Those $\min$'s cancel out completely:

$$d = \max(x_d, y_d)$$

... which is, again, exactly how we calculate Civ distance. Excellent,
well done!


That leaves us with the general formula:

$$d = \max(x_d, y_d) - \min(x_d, y_d) + k \times (\min(x_d, y_d))$$

Where $k$ is the diagonal cost.

### Tweaking

[![A D&D distance Voronoi diagram](/images/post_2016_08_25/dandd_voronoi.png "A D&D distance Voronoi diagram"){width=150 height=150}](/images/post_2016_08_25/dandd_voronoi.png)

Remember that the D&D distance ended up being closest to Euclidean. If
$x_d$ and $y_d$ are equal -- that is, if we're going at exactly a
45-degree angle -- the Euclidean distance is $x_d \times
\sqrt(2)$. That $sqrt(2)$ is 1.41421....

Last post, I mused that, since 1.5 was much closer to $sqrt(2)$ than
either 1 (civ) or 2 (taxi), that is why D&D distance was such a good
Euclidean approximation.

But, could it be better? If we plug $k=1.4$ into our general distance
equation, does it come closer?

Well, so I wrote a script to test this. It's [up in the same repo as
last time](https://github.com/jmelesky/voronoi_example).


It generates a set of random points, then calculates the Euclidean
distance from $(0,0)$ to each point. For each of the other measures,
it calculates the same distance, and compares it to the Euclidean,
keeping the difference. At the end, it prints out the total difference
for each measure.

[![A Voronoi diagram witk k=1.4](/images/post_2016_08_29/tweaked_voronoi.png "A Voronoi diagram with k=1.4"){width=150 height=150}](/images/post_2016_08_29/tweaked_voronoi.png)

It looks a bit like this:

~~~ { .bash }
$ ./test_distances.py 
taxi  diff: 12848
civ   diff: 5146
dandd diff: 3851
other diff: 2071
~~~

As you can see, the "other" calculation ($k = 1.4$) has the least
difference from the Euclidean distance, and so is a nice, quite
accurate measure.

1.4 is a tricky number. If you wanted to use it in a game of some
sort, though, you could cost it out differently -- the thing that
matters is the ratio. For example, it might cost 5 action points to
move in a cardinal direction, but 7 action points to move
diagonally. That would be quite true to Euclid, while nicely operating
in our discrete movement world.

Thanks for reading through, and hope it was interesting for you, too.
