# heightfield / heightfield / surface.py

 ``` 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74``` ```import math from numpy import zeros from PIL import Image from pkg_resources import resource_stream colours = Image.open(resource_stream(__name__, 'data/heightmap.png')) class Surface(object): def __init__(self, size): self.surface = zeros((size, size)) self.size = size self.dirty = True def __getitem__(self, pos): return self.surface[pos] def __setitem__(self, pos, value): self.surface[pos] = value self.dirty = False def __repr__(self): s = [] for y in xrange(self.size): for x in xrange(self.size): h = self[x, y] s.append("%5.2f " % h) s.append('\n') return ''.join(s) @staticmethod def make_cone(size, height): """Create a surface of size x size representing a cone of height""" s = Surface(size) w = float(size - 1) for x in range(size): for y in range(size): dx = 2.0 * x / w - 1.0 dy = 2.0 * y / w - 1.0 h = max(0, 1.0 - math.sqrt(dx ** 2 + dy ** 2)) s[x, y] = h * height return s def blit(self, img, x, y): """Add the heights in img to this surface at (x, y)""" if x < 0: sx = -x dx = 0 else: sx = 0 dx = x if y < 0: sy = -y dy = 0 else: sy = 0 dy = y w = img.size - sx h = img.size - sy dx2 = min(dx + w, self.size) dy2 = min(dy + h, self.size) sw, sh = self.surface[dx:dx2, dy:dy2].shape self.surface[dx:dx2, dy:dy2] += img.surface[sx:sx + sw, sy:sy + sh] self.dirty = True def to_pil(self): im = Image.new(colours.mode, (self.size, self.size)) for y in xrange(self.size): for x in xrange(self.size): h = self[x, y] val = max(0, min(1.0, h * 0.1) * 255) col = colours.getpixel((int(val), 0)) im.putpixel((x, y), col) return im ```