def step_impl(context): expected = Matrix(4, 4) for e_row in range(4): for e_col in range(4): expected.matrix[e_row][e_col] = float(context.table[e_row][e_col]) result = context.B assert expected == result, 'The expected matrix does not match what was given.'
def step_impl(context, row, column, rows, columns): expected = Matrix(rows, columns) for e_row in range(rows): for e_col in range(columns): expected.matrix[e_row][e_col] = float(context.table[e_row][e_col]) result = context.M.submatrix(row, column) assert expected == result, 'The expected submatrix was not found with the calculated result.'
def step_impl(context): expected = Matrix(4, 4) for row in range(4): for column in range(4): expected.matrix[row][column] = float(context.table[row][column]) result = context.A.transpose() assert expected == result, 'The transpose of Matrix A does not match the expected result.'
def step_impl(context): expected = Matrix(4, 4) for row in range(4): for column in range(4): expected.matrix[row][column] = float(context.table[row][column]) result = context.A * context.B assert expected == result, 'The multiplication of A * B does not match the expected result.'
def step_impl(context): expected = Matrix(4, 4) for e_row in range(4): for e_col in range(4): expected.matrix[e_row][e_col] = float(context.table[e_row][e_col]) result = context.M.inverse() assert expected == result, 'The expected matrix is does not match the given inverse.'
def hexagon_edge(): edge = Cylinder() edge.minimum = 0 edge.maximum = 1 edge.transform = Matrix.translation(0, 0, -1) * \ Matrix.rotation_y(-30) * \ Matrix.rotation_z(-90) * \ Matrix.scaling(0.25, 1, 0.25) return edge
def step_impl(context, col, row): expected = Matrix(col, row) i = j = 0 for row in context.table: for col in row: expected._matrix[i][j] = float(col) j += 1 i += 1 j = 0 assert expected == context.t, f't != {expected._matrix}'
def question_one(): print('1. What happens when you invert the identity matrix?') print('You get this:') m = Matrix.identity_matrix().submatrix(3, 3) m = m.inverse() for row in m.matrix: print(row) print('The Identity matrix again :)\n')
def hexagon(): hex = Group() for n in range(6): side = hexagon_side() side.transform = Matrix.rotation_y(n * 60) hex.add_child(side) return hex
def question_two(): print('2. What do you get when you multiply a matrix by its inverse?') m = Matrix(3, 3) m._matrix = [[1, 2, 3], [20, 5, 6], [7, 8, 11]] print('We have the following matrix:') for row in m.matrix: print(row) print('\nThe inverse matrix is the following:') i = m.inverse() for row in i.matrix: print(row) print('\nThe product of the matrix with it\'s inverse is the following:') p = i * m for row in p.matrix: print(row)
def default_world(): world = World() world.light = PointLight(point(-10, 10, -10), Color(1, 1, 1)) s1 = Sphere() s1.material.color = Color(0.8, 1.0, 0.6) s1.material.diffuse = 0.7 s1.material.specular = 0.2 world.objects.append(s1) s2 = Sphere() s2.transform = Matrix.scaling(0.5, 0.5, 0.5) world.objects.append(s2) return world
def ch9(): # Step 1 floor = Plane() floor.transform = Matrix.scaling(10, 0.01, 10) floor.material = Material() floor.material.color = Color(1, 0.9, 0.9) floor.material.specular = 0 floor.material.pattern = StripePattern(Color(1, 0, 0), Color(0, 0, 1)) # Middle biggest sphere middle = Sphere() middle.transform = Matrix.translation(-0.5, 1, 0.5) middle.material = Material() middle.material.color = Color(0.1, 1, 0.5) middle.material.diffuse = 0.7 middle.material.specular = 0.3 middle.material.pattern = RingPattern(Color(1, 0, 1), Color(1, 1, 1)) middle.material.pattern.transform = Matrix.scaling(0.25, 0.5, 0.25) # Smaller right sphere right = Sphere() right.transform = Matrix.translation(1.5, 0.5, -0.5) * Matrix.scaling(0.5, 0.5, 0.5) right.material = Material() right.material.color = Color(0.5, 1, 0.1) right.material.diffuse = 0.7 right.material.specular = 0.3 right.material.reflective = 1.0 # Left yellow sphere left = Sphere() left.transform = Matrix.translation(-1.5, 0.33, -0.75) * Matrix.scaling(0.33, 0.33, 0.33) left.material = Material() left.material.color = Color(1, 0.8, 0.1) left.material.diffuse = 0.7 left.material.specular = 0.3 world = World() world.light = PointLight(point(-10, 10, -10), Color(1, 1, 1)) world.objects.extend([floor, middle, right, left]) camera = Camera(100, 50, 60) # camera = Camera(500, 250, 60) camera.transform = view_transform(point(0, 1.5, -5), point(0, 1, 0), vector(0, 1, 0)) canvas = camera.render(world) with open('ch9.ppm', 'w') as fp: fp.write(canvas.to_ppm())
def __init__(self, hsize, vsize, field_of_view): self.hsize = hsize self.vsize = vsize self.field_of_view = field_of_view self.transform = Matrix.identity_matrix() # Calculate pixel size, pixel width, pixel height self.fov_radians = math.radians(field_of_view) half_view = math.tan(self.fov_radians / 2) aspect = hsize / vsize if aspect >= 1: self.half_width = half_view self.half_height = half_view / aspect else: self.half_width = half_view * aspect self.half_height = half_view self.pixel_size = (self.half_width * 2) / self.hsize
def step_impl(context, x, y, z): context.B = Matrix.scaling(x, y, z)
def step_impl(context, x, y, z): context.C = Matrix.translation(x, y, z)
def step_impl(context, xy, xz, yx, yz, zx, zy): context.transform = Matrix.shearing(xy, xz, yx, yz, zx, zy)
def step_impl(context, degrees): context.A = Matrix.rotation_x(degrees)
def step_impl(context, degrees): context.half_quarter = Matrix.rotation_y(degrees)
def step_impl(context, degrees, x, y, z): context.c.transform = Matrix.rotation_y(degrees) * Matrix.translation( x, y, z)
def ch7(): # Step 1 floor = Sphere() floor.transform = Matrix.scaling(10, 0.01, 10) floor.material = Material() floor.material.color = Color(1, 0.9, 0.9) floor.material.specular = 0 # Step 2 left_wall = Sphere() left_wall.transform = Matrix.translation(0, 0, 5) * Matrix.rotation_y(-45) * \ Matrix.rotation_x(90) * Matrix.scaling(10, 0.01, 10) left_wall.material = floor.material # Step 3 right_wall = Sphere() right_wall.transform = Matrix.translation(0, 0, 5) * Matrix.rotation_y(45) * \ Matrix.rotation_x(90) * Matrix.scaling(10, 0.01, 10) right_wall.material = floor.material # Step 4 middle = Sphere() middle.transform = Matrix.translation(-0.5, 1, 0.5) middle.material = Material() middle.material.color = Color(0.1, 1, 0.5) middle.material.diffuse = 0.7 middle.material.specular = 0.3 # Step 5 right = Sphere() right.transform = Matrix.translation(1.5, 0.5, -0.5) * Matrix.scaling( 0.5, 0.5, 0.5) right.material = Material() right.material.color = Color(0.5, 1, 0.1) right.material.diffuse = 0.7 right.material.specular = 0.3 # Step 6 left = Sphere() left.transform = Matrix.translation(-1.5, 0.33, -0.75) * Matrix.scaling( 0.33, 0.33, 0.33) left.material = Material() left.material.color = Color(1, 0.8, 0.1) left.material.diffuse = 0.7 left.material.specular = 0.3 world = World() world.light = PointLight(point(-10, 10, -10), Color(1, 1, 1)) world.objects.extend([floor, left_wall, right_wall, middle, right, left]) camera = Camera(100, 50, 60) # camera = Camera(500, 250, 60) camera.transform = view_transform(point(0, 1.5, -5), point(0, 1, 0), vector(0, 1, 0)) canvas = camera.render(world) with open('ch8.ppm', 'w') as fp: fp.write(canvas.to_ppm())
def step_impl(context, x, y, z): context.transform = Matrix.scaling(x, y, z)
def step_impl(context, x, y, z): context.pattern.transform = Matrix.translation(x, y, z)
def step_impl(context, x, y, z): expected = Matrix.translation(x, y, z) result = context.pattern.transform assert expected == result, f'pattern.transform != {expected}'
def step_impl(context): assert context.t == Matrix.identity_matrix(), 't != identity_matrix'
def hexagon_corner(): corner = Sphere() corner.transform = Matrix.translation(0, 0, -1) * \ Matrix.scaling(0.25, 0.25, 0.25) return corner
def step_impl(context, degrees): context.full_quarter = Matrix.rotation_z(degrees)
def step_impl(context, x, y, z): expected = Matrix.scaling(x, y, z) assert expected == context.t, f't != {expected}'
# Can probably have this done internally in the Canvas class, but left # it here for simplicity and it doesn't hide how the conversion is done. def convert_position_to_canvas(canvas: Canvas, world_position: Vec3): """Converts the position from world to canvas. This is done by subtracting the z world position from the canvas height, the other positions are left alone.""" return point( round(world_position.x + (canvas.width / 2)), round(world_position.y), round((canvas.height - (canvas.height / 2) - world_position.z))) if __name__ == '__main__': width = 400 height = 400 canvas = Canvas(width, height) hour_rotation = 360 / 12 hour_rotation_matrix = Matrix.rotation_y(hour_rotation) radius = (3 / 8) * canvas.width print(f'Radius: {radius}') position = point(0, 0, 1) * radius for i in range(12): canvas_point = convert_position_to_canvas(canvas, position) print(f'Position:{position}\nCanvas:{canvas_point}') canvas.write_pixel(canvas_point.x, canvas_point.z, Color(1, 1, 1)) position = hour_rotation_matrix * position with open('clock2.ppm', 'w') as fp: fp.write(canvas.to_ppm())
def __init__(self, parent=None): # Converts itself from shape -> world space self.transform = Matrix.identity_matrix() self.material = Material() self.parent = parent self.id = id(self)
def step_impl(context, x, y, z): expected = Matrix.translation(x, y, z) assert expected == context.t, f't != {expected}'