1. Ian George
  2. sketchbook

Source

sketchbook / demo / matrix.py

from __future__ import division
import math
from array import array

class Transform(object):
    def __init__(self, grid):
        self.original_grid = grid
        self.h,self.w = len(grid),len(grid[0])    

    def apply_matrix_wrap(self, transformation, cycle):
        #get a new grid to map on to
        new_grid = get_2d_array(self.w, self.h)
        w = self.w
        h = self.h
        m1,m2,m3 = transformation[0]
        m4,m5,m6 = transformation[1]
        colour_index = (cycle*4) # 0-254

        m3 = int(m3)
        m6 = int(m6)

        #map the x,y values to the new ones with a matrix multiplication
        for y, row in enumerate(self.original_grid):
            m2y = int(m2*y) + m3
            m5y = int(m5*y) + m6
            for x, val in enumerate(row):
                nx = (int(m1*x) + m2y) % w
                ny = (int(m4*x) + m5y) % h
                new_grid[ny][nx] = (colour_index + val)%255 #map old val to new point, incrementing the colour index if it's > 0
                
        return new_grid

    def apply_matrix_clip(self, transformation, cycle):
         #get a new grid to map on to
         new_grid = get_2d_array(self.w, self.h)
         o_grid = self.original_grid
         w = self.w
         h = self.h
         m1,m2,m3 = transformation[0]
         m4,m5,m6 = transformation[1]
         colour_index = cycle*4
         
         m3 = int(m3)
         m6 = int(m6)

         for y, row in enumerate(o_grid):
             m2y = int(m2*y) + m3
             m5y = int(m5*y) + m6
             for x, val in enumerate(row):
                 #map the x,y values to the new ones with a matrix multiplication
                 nx = int(m1*x) + m2y
                 ny = int(m4*x) + m5y

                 if (nx > -1 and nx < w) and (ny > -1 and ny < h):
                    new_grid[ny][nx] = (val + colour_index) % 255 #map old val to new point, incrementing the colour index if it's > 0

         return new_grid

def get_2d_array(w, h):
    return [[0] * w for i in xrange(h)]

def translate_shear_matrix(tx, ty, shearx, sheary):
    M = (
        (1, shearx, tx),
        (sheary, 1, ty),
        (0, 0, 1)
        )
    return M

def scale_matrix(scalex, scaley):
    M = (
        (scalex,0,-scalex/2),
        (0,scaley,-scaley/2),
        (0,0,1)
        )
    return M

def rotation_matrix(angle, centre_x, centre_y, scale_by):
    angle = angle / (180/math.pi)
    scale = scale_by
    M = (
        (math.cos(angle),           -math.sin(angle)*scale_by, centre_x - math.cos(angle) * centre_x + math.sin(angle) * centre_y ),
        (math.sin(angle)*scale_by,  math.cos(angle),           centre_y - math.sin(angle) * centre_x - math.cos(angle) * centre_y ),
        (0,                       0,                       1                                                                )
        )
    return M