Skip to content

Instantly share code, notes, and snippets.

@nst
Created September 16, 2021 19:58
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 nst/52d91310e87fb95934cc1d842b4d4b63 to your computer and use it in GitHub Desktop.
Save nst/52d91310e87fb95934cc1d842b4d4b63 to your computer and use it in GitHub Desktop.
# Nicolas Seriot
# 2021-09-16
# Isometric Towers
# Reimplementation of @bendotk art
# https://twitter.com/nst021/status/1437889678947110912
# Typical output: https://seriot.ch/visualization/iso.png
import cairo
import random
MARGIN = 100
W, H = 10, 40 # grid size
DW, DH = 60, 30 # diamond size
DW2, DH2 = int(DW/2), int(DH/2)
Z_MAX = 2
N = 300
def draw_surface(c, points, color):
c.save()
c.set_source_rgb(*color)
c.set_line_width(1)
[c.line_to(*p) for p in points]
c.close_path()
c.fill_preserve()
c.set_source_rgb(0,0,0)
c.set_line_join(cairo.LINE_CAP_SQUARE)
c.stroke()
c.restore()
def draw_grid(c):
for x in range(W):
for y in range(H):
draw_tower(c, x, y, 0)
def diamond_coords(x, y):
x_offset = DW2 if y % 2 != 0 else 0
return (x * DW + x_offset, y * DH2)
def draw_tower(c, x, y, h):
x, y = diamond_coords(x, y)
c.save()
c.translate(x, y)
"""
5
2 6
3 - DH
1 7
4
| DW2
"""
p1 = (0, DH2)
p2 = (0, DH2 + DH*h)
p3 = (DW2, DH*h)
p4 = (DW2, 0)
p5 = (DW2, DH*h + DH)
p6 = (DW, DH2 + DH*h)
p7 = (DW, DH2)
COLOR_RIGHT = (0.5,0.5,0.5)
COLOR_TOP = (1,1,1)
COLOR_LEFT = (0,0,0)
draw_surface(c, [p2, p5, p6, p3], COLOR_TOP)
draw_surface(c, [p1, p2, p3, p4], COLOR_LEFT)
draw_surface(c, [p3, p6, p7, p4], COLOR_RIGHT)
c.restore()
def draw_model(c, m):
for y in range(len(m))[::-1]:
for x in range(len(m[y])):
z = m[y][x]
if z > 0:
draw_tower(c, x, y, z)
def main():
# model is a 2D grid storing the height of towers
m = [[0]*W for _ in range(H)]
for _ in range(N):
x = random.randint(0, W-1)
y = random.randint(0, H-1)
z = random.randint(0, Z_MAX)
m[y][x] = z
surface = cairo.ImageSurface(cairo.FORMAT_ARGB32,
DW2+(W*DW) + MARGIN*2,
int(H/2)*DH + MARGIN*3)
c = cairo.Context(surface)
cm = cairo.Matrix(yy=-1, y0=surface.get_height())
c.transform(cm)
c.translate(MARGIN, MARGIN)
#c.set_antialias(cairo.ANTIALIAS_NONE)
c.set_source_rgb(1,1,1)
c.paint()
c.set_source_rgb(0,0,0)
c.set_line_width(1)
#draw_grid(c)
draw_model(c, m)
#draw_tower(c, 1, 1, 0)
#draw_tower(c, 1, 0, 1)
surface.write_to_png("iso.png")
if __name__ == "__main__":
main()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment