Skip to content

Instantly share code, notes, and snippets.

@sr8e
Last active December 13, 2023 15:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sr8e/12ed1dfd19abe68f01f4bf8628a72c59 to your computer and use it in GitHub Desktop.
Save sr8e/12ed1dfd19abe68f01f4bf8628a72c59 to your computer and use it in GitHub Desktop.
Hexmap (Tsukuba) distance
import math
from collections import deque
from typing import NamedTuple
import matplotlib.pyplot as plt
class ObliqueVector(NamedTuple):
xi: int
eta: int
def __mul__(self, other) -> float:
if isinstance(other, self.__class__):
return sum((a * b for a, b in zip(self.to_ortho(), other.to_ortho())))
def __add__(self, other):
if isinstance(other, self.__class__):
return self.__class__(*(a + b for a, b in zip(self, other)))
def __str__(self):
return (tuple(self)).__str__()
def to_ortho(self) -> tuple[float]:
return (self.xi + self.eta / 2, self.eta * math.sqrt(3) / 2)
@property
def modtype(self) -> int:
return (self.xi - self.eta) % 3
def get_dist_points(dist):
moves = {
0: [ObliqueVector(*v) for v in [(0, 1), (1, -1), (-1, 0)]],
2: [ObliqueVector(*v) for v in [(1, 0), (-1, 1), (0, -1)]],
}
dists = {}
deq = deque()
deq.append((ObliqueVector(0, 0), 0))
while len(deq) > 0:
p = deq.popleft()
if p[0] in dists and dists[p[0]] <= p[1]:
continue
dists[p[0]] = p[1]
if p[1] == dist:
continue
for ds in moves[p[0].modtype]:
if p[0] * ds < 0:
continue
deq.append((p[0] + ds, p[1] + 1))
return [p for p in dists.keys() if dists[p] == dist]
ps = get_dist_points(31)
# visualize
plt.axes().set_aspect("equal")
plt.scatter(*zip(*[ov.to_ortho() for ov in ps]))
plt.show()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment