1. Geoff Gerrietts
  2. pnad

Commits

Geoff Gerrietts  committed 1042db5 Draft

a rough pass at hex grid math

  • Participants
  • Parent commits c8b08cd
  • Branches default

Comments (0)

Files changed (1)

File pnad/grid.py

View file
  • Ignore whitespace
+
+
+# side = .5 wide width
+# hexagon_narrow_width = 1.5 * side
+# hexagon_wide_width = 2 * side = (side + (2 * .5 * side))
+# hexagon_height = 2 * (cos(30) = .866) * side = 1.732 * side
+
+ # | /    \      /    \      /    \
+ # |/ m=0  \____/   2  \____/   4  \
+ # |\ n=0  /    \  -1  /    \  -2  /
+ # | \____/   1  \____/   3  \____/
+ # | /    \   0  /    \  -1  /    \
+ # |/   0  \____/   2  \____/   4  \
+ # |\   1  /    \   0  /    \  -1  /
+ # | \____/   1  \____/   3  \____/
+ # | /    \   1  /    \   0  /    \
+ # |/   0  \____/   2  \____/   4  \
+ # |\   2  /    \   1  /    \   0  /
+ # | \____/   1  \____/   3  \____/
+ # | /    \   2  /    \   1  /    \
+ # |/   0  \____/   2  \____/   4  \
+ # |\   3  /    \   2  /    \   0  /
+ # | \____/   1  \____/   3  \____/
+ # | /    \   3  /    \   2  /    \
+ # |/   0  \____/   2  \____/   4  \
+ # |\   4  /    \   3  /    \   2  /
+ # | \____/      \____/      \____/
+
+class HexGrid(object):
+    """ Implements some math for a hex-based grid.
+
+        This grid assumes 0,0 in upper left, with rows growing positive
+        to the right and rows growing negative to the left.
+    """
+
+    def __init__(self, width, cols, rows):
+        self.cols = cols
+        self.rows = rows
+        self.width = width
+        self.side = round(width * .5)
+        self.height = round(width * .866)
+        self.points = None
+        # XXX: point of reflection
+        t = divmod(rows,2)
+        self.rowbounds = (-t[0], t[0]+t[1]-1)
+
+    def mapsize(self):
+        narrow, extra = divmod(self.cols,2)
+        wide = narrow + extra
+        width = wide * self.width + narrow * 1.5 * side
+        height = self.rows * self.height + self.cols * .5 * self.height
+
+    def relative_vertices(self):
+        if self.points is not None:
+            return self.points
+        left = round(self.side / 2)
+        right = left + self.side
+        middle = round(self.height / 2)
+        self.points = [
+            (left, 0),   # top left
+            (right, 0),  # top right
+            (width, middle), # right point
+            (right, height), # bottom right
+            (left, height), # bottom left
+            (0, middle), # left point
+        ]
+
+    def lines(self):
+
+
+    def coords_to_corner(self, m, n):
+        """ Take m, n hex coordinates and return an x,y upper-left of bounding box.
+        """
+        x = m * self.side * 1.5
+        y = self.height * (m * .5 + n)
+        return (x, y)
+
+    def coords_to_points(self, m, n):
+        """ Take m, n hex coordinates and return an iterator of x, y vertex points.
+        """
+        ox, oy = self.coords_to_corner(m, n)
+        verts = self.relative_vertices()
+        return ((x + ox, y + oy) for (x,y) in verts)
+
+    def neighborhood(self, m, n):
+        """ returns the cell + the neighboring cells in m,n.
+        """
+        s = ((m, n),
+             (m, n+1),
+             (m+1, n),
+             (m+1, n-1),
+             (m, n-1),
+             (m-1, n),
+             (m-1, n+1))
+        rb = self.rowbounds
+        return ((m,n) for (m,n) in s if 
+                    (0 <= m < self.cols) and 
+                    (rb[0] <= n < rb[1]))
+
+    def points_to_coords(self, x, y):
+        # adjust so centers are on 0,0
+        x = x - (self.width * .5)
+        y = y - (self.height * .5)
+
+        # now we can use the corners
+        cm = x  / (self.side * 1.5)
+        cn = y / self.height - cm * .5
+
+        corners = ((self.coords_to_points(m,n), (m,n) for (m,n) in self.neighborhood(cm,cn))
+        deltas = ((cx - x, cy - y) for (x, y) in corners)
+        dsquare = (x * x + y * y)
+
+