Math function visualization in a 2D grid

In the same way that we're able to generate a single row of tiles where the color of a tile is determined by the output of a function with a single variable x, we're also able to expand the dimensionality of our program to include a second variable y. In this way, the color of a tile will be given by the multivariate function f(x,y)
In this implementation we will use multiple functions that accept two variables x and y, represented by the positions of the tiles in the grid.



The parameters of the Algorithm

  • RES: int - Size of each tile
  • DIMS: (int,int=1) - Number of columns and rows that make the program
  • SCREEN: (int,int) - Dimensions of the screen given as a width and height in pixels
  • TILE: Tile() - Basic unit of information in the program
  • TILEGRID: [[TILE, ..., n=DIMS[0]], ..., n=DIMS[1]] - 2D array of TILE
# MODULES
import pygame
import math

# DD.

RES = 4
DIMS = (128, 128)
SCREEN = (DIMS[0]*RES, DIMS[1]*RES)
display = pygame.display.set_mode(SCREEN)
RANGE = 15

# DD. TILE
# tile = Tile()
# interp. a tile in a one row system


class Tile:
    def __init__(self, c, r):
        self.c = c
        self.r = r
        self.x = self.c * RES
        self.y = self.r * RES
        self.rect = pygame.Rect(self.x, self.y, RES, RES)
        self.color = "black"

    def draw(self):
        pygame.draw.rect(display, self.color, self.rect)


# DD. TILEGRID
# tileGrid = [[TILE, ..., n=DIMS[0]], ..., n=DIMS[1]]
# interp. a 2D array of tiles
tileGrid = []
for r in range(DIMS[1]):
    tileRow = []
    for c in range(DIMS[0]):
        tile = Tile(c, r)
        tileRow.append(tile)
    tileGrid.append(tileRow)

# TEMPLATE FOR TILEROW
# for tileRow in tileGrid:
#   for tile in tileRow:
#       ... tile

The Algorithm

  • For TILE in TILEGRID:
    • TILE color is f(x,y)

Let's implement this algorithm using Python!
# MODULES
import pygame
import math

# DD.

RES = 4
DIMS = (128, 128)
SCREEN = (DIMS[0]*RES, DIMS[1]*RES)
display = pygame.display.set_mode(SCREEN)
RANGE = 15

# DD. TILE
# tile = Tile()
# interp. a tile in a one row system


class Tile:
    def __init__(self, c, r):
        self.c = c
        self.r = r
        self.x = self.c * RES
        self.y = self.r * RES
        self.rect = pygame.Rect(self.x, self.y, RES, RES)
        self.color = "black"

    def draw(self):
        pygame.draw.rect(display, self.color, self.rect)


# DD. TILEGRID
# tileGrid = [[TILE, ..., n=DIMS[0]], ..., n=DIMS[1]]
# interp. a 2D array of tiles
tileGrid = []
for r in range(DIMS[1]):
    tileRow = []
    for c in range(DIMS[0]):
        tile = Tile(c, r)
        tileRow.append(tile)
    tileGrid.append(tileRow)

# TEMPLATE FOR TILEROW
# for tileRow in tileGrid:
#   for tile in tileRow:
#       ... tile

# CODE

# FD. remap()
# Signature: float, float, float, float, float -> float
# purp. rescale a given value
def remap(value, from1, to1, from2, to2):
    return (value - from1) / (to1 - from1) * (to2 - from2) + from2


def draw():
    display.fill("green")
    for tileRow in tileGrid:
        for tile in tileRow:
            tile.draw()
    pygame.display.flip()


def fn0(x,y):
    return (x % 256 + y % 256)/2

def fn1(x,y):
    xval = math.sin(x)
    yval = math.sin(y)
    return (xval + yval)/2

def mapFromFn(tile,fn):
    x = remap(tile.x,0,SCREEN[0],-RANGE,RANGE)
    y = remap(tile.y,0,SCREEN[1],-RANGE,RANGE)
    value = fn(x,y)
    value = int(remap(value,-1,1,0,255))
    return (value)

def update():
    for event in pygame.event.get():
        if event.type == pygame.QUIT:
            pygame.quit()

    for tileRow in tileGrid:
        for tile in tileRow:
            c = mapFromFn(tile,fn1)
            tile.color = (c,c,c)


while True:
    draw()
    update()