def main(): p = dict(position=point(0, 1, 0), velocity=normalize(vector(1, 1, 0))) e = dict(gravity=vector(0, -0.1, 0), wind=vector(-0.01, 0, 0)) while p['position'][1] > 0.0: print( f"position {p['position'][0]}, {p['position'][1]}, {p['position'][2]}" ) p = tick(e, p)
def local_normal_at(self, local_point, hit=None): # compute the square of the distance from the y axis dist = local_point[0]**2 + local_point[2]**2 if dist < 1 and local_point[1] >= self.maximum - self.EPSILON: return vector(0, 1, 0) if dist < 1 and local_point[1] <= self.minimum + self.EPSILON: return vector(0, -1, 0) return vector(local_point[0], 0, local_point[2])
def local_normal_at(self, local_point, hit=None): maxc = max(abs(local_point[0]), abs(local_point[1]), abs(local_point[2])) if maxc == abs(local_point[0]): return vector(local_point[0], 0, 0) if maxc == abs(local_point[1]): return vector(0, local_point[1], 0) return vector(0, 0, local_point[2])
def main(): p = dict(position=point(0, 1, 0), velocity=multiply(normalize(vector(1, 1.8, 0)), 11.25)) e = dict(gravity=vector(0, -0.1, 0), wind=vector(-0.01, 0, 0)) c = Canvas(900, 550) while p['position'][1] > 0.0: print( f"position {p['position'][0]}, {p['position'][1]}, {p['position'][2]}" ) c.set_pixel(round(p['position'][0]), c.height - round(p['position'][1]), color(0.0, 1.0, 0.0)) p = tick(e, p) with open('cannon.ppm', 'w') as out_file: out_file.write(c.to_ppm())
def from_yaml(cls, data): values = data['corner'] corner = point(values[0], values[1], values[2]) values = data['uvec'] uvec = vector(values[0], values[1], values[2]) usteps = data['usteps'] values = data['vvec'] vvec = vector(values[0], values[1], values[2]) vsteps = data['vsteps'] values = data['intensity'] intensity = color(values[0], values[1], values[2]) light = cls(corner, uvec, usteps, vvec, vsteps, intensity) if 'jitter' in data and data['jitter']: light.jitter_by = RandomSequence() return light
def from_yaml(cls, data): camera = cls(data['width'], data['height'], data['field-of-view']) values = data['from'] from_pos = point(values[0], values[1], values[2]) values = data['to'] to_pos = point(values[0], values[1], values[2]) values = data['up'] up_vector = vector(values[0], values[1], values[2]) camera.set_transform(view_transform(from_pos, to_pos, up_vector)) return camera
def parse_obj_file(content, material=Material()): obj_file = ObjFile() current_group = obj_file.groups["default"] for line in content: parts = line.split() if len(parts) < 1: obj_file.ignored += 1 continue if parts[0] == "v": obj_file.vertices.append( point(float(parts[1]), float(parts[2]), float(parts[3]))) elif parts[0] == "vn": obj_file.normals.append( vector(float(parts[1]), float(parts[2]), float(parts[3]))) elif parts[0] == "g": current_group = Group() obj_file.groups[parts[1]] = current_group elif parts[0] == "f": vertices = [None] normals = [None] for index in range(1, len(parts)): v, vt, vn = to_ints(parts[index]) vertices.append(obj_file.vertices[v]) if vn: normals.append(obj_file.normals[vn]) triangles = fan_triangulation(vertices, normals, material) for triangle in triangles: current_group.add_child(triangle) else: obj_file.ignored += 1 return obj_file
def step_assert_normal_of_triangle(context): assert_tuple(context.t.normal, vector(0, 0, -1))
def step_create_vector_direction(context, x, y, z): context.direction = vector(x, y, z)
def step_assert_e1_of_triangle(context): assert_tuple(context.t.e1, vector(-1, -1, 0))
def step_assert_e2_of_triangle(context): assert_tuple(context.t.e2, vector(1, -1, 0))
def step_assert_saved_ray_direction_equals_vector(context, x, y, z): assert_tuple(context.s.saved_ray.direction, vector(x, y, z))
def local_normal_at(self, local_point, hit=None): return vector(local_point[0], local_point[1], local_point[2])
def step_create_normal_vector_n2(context): context.n2 = vector(-1, 0, 0)
def step_create_ray_with_point_and_specific_direction(context, ox, oy, oz): context.r = Ray(point(ox, oy, oz), vector(0, -sqrt(2) / 2, sqrt(2) / 2))
def local_normal_at(self, local_point, hit=None): return vector(0, 1, 0)
def step_create_normal_vector_n1(context): context.n1 = vector(0, 1, 0)
def step_assert_direction_of_r2_is_certain_vector(context): actual = context.r2.direction expected = vector(sqrt(2) / 2, 0, -sqrt(2) / 2) assert_tuple(actual, expected)
def step_impl(context, x, y, z): actual = context.r2.direction expected = vector(x, y, z) assert_tuple(actual, expected)
def step_create_ray_with_specific_point_and_direction(context, dx, dy, dz): context.r = Ray(point(0, 0, sqrt(2) / 2), vector(dx, dy, dz))
def step_assert_light_uvec_equals_vector(context, x, y, z): assert_tuple(context.light.uvec, vector(x, y, z))
def step_create_normal_vector_v2_from_point(context): context.v2 = vector(context.p[0], context.p[1], context.p[2])
def step_assert_normal_equals_vector(context): assert_tuple(context.normal, vector(1, -sqrt(2), 1))
def step_create_ray_with_point_and_direction(context, ox, oy, oz, dx, dy, dz): context.r = Ray(point(ox, oy, oz), vector(dx, dy, dz))
def step_create_normal_vector_n3(context): context.n3 = vector(1, 0, 0)
def step_create_vector_v1_reflection(context): context.v1 = vector(0, -sqrt(2) / 2, -sqrt(2) / 2)
def step_impl(context, x, y, z): actual = multiply_tuple(context.transform, context.v) expected = vector(x, y, z) assert actual == expected, "%r is not %r" % (actual, expected)
def step_assert_n_equals_certain_vector(context): xyz = sqrt(3) / 3 assert_tuple(context.n, vector(xyz, xyz, xyz))
def step_assert_n3_equals_vector(context, x, y, z): assert_tuple(context.n3, vector(x, y, z))
def step_assign_normal_to_world_of_vector_to_p(context): xyz = sqrt(3) / 3 context.n = context.s.normal_to_world(vector(xyz, xyz, xyz))