def local_normal_at(self, local_point, hit=None): if self.smoothed: return add( multiply(self.n2, hit.u), add(multiply(self.n3, hit.v), multiply(self.n1, (1 - hit.u - hit.v)))) return self.normal
def __init__(self, corner, full_uvec, usteps, full_vvec, vsteps, intensity): self.corner = corner self.uvec = multiply(full_uvec, 1 / usteps) self.usteps = usteps self.vvec = multiply(full_vvec, 1 / vsteps) self.vsteps = vsteps self.samples = usteps * vsteps self.position = add(add(corner, multiply(full_uvec, 1 / 2)), multiply(full_vvec, 1 / 2)) self.intensity = intensity self.jitter_by = DeterministicSequence([0.5])
def reflected_color(self, hit, remaining=5): if remaining <= 0: return color(0, 0, 0) if hit.object.material.reflective == 0.0: return color(0, 0, 0) reflect_ray = Ray(hit.over_point, hit.reflectv) reflect_color = self.color_at(reflect_ray, remaining - 1) return multiply(reflect_color, hit.object.material.reflective)
def shade_hit(self, hit, remaining=5): surface = color(0, 0, 0) for light in self.lights: light_intensity = light.intensity_at(hit.over_point, self) surface = add( surface, lighting(hit.object.material, hit.object, light, hit.point, hit.eyev, hit.normalv, light_intensity)) reflected = self.reflected_color(hit, remaining) refracted = self.refracted_color(hit, remaining) material = hit.object.material if material.reflective > 0 and material.transparency > 0: reflectance = hit.schlick() return add(add(surface, multiply(reflected, reflectance)), multiply(refracted, (1 - reflectance))) return add(add(surface, reflected), refracted)
def refracted_color(self, hit, remaining=5): if remaining <= 0: return color(0, 0, 0) if hit.object.material.transparency == 0.0: return color(0, 0, 0) n_ratio = hit.n1 / hit.n2 cos_i = dot(hit.eyev, hit.normalv) sin2_t = n_ratio**2 * (1 - cos_i**2) if sin2_t > 1.0: return color(0, 0, 0) cos_t = sqrt(1.0 - sin2_t) direction = subtract(multiply(hit.normalv, (n_ratio * cos_i - cos_t)), multiply(hit.eyev, n_ratio)) refract_ray = Ray(hit.under_point, direction) return multiply(self.color_at(refract_ray, remaining - 1), hit.object.material.transparency)
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 step_impl(context): assert multiply(context.c, 2) == color(0.4, 0.6, 0.8)
def point_on_light(self, u, v): return add(self.corner, \ add(multiply(self.uvec, (u + self.jitter_by.next())), \ multiply(self.vvec, (v + self.jitter_by.next()))))
def pattern_at(self, point): distance = subtract(self.color_b, self.color_a) fraction = point[0] - floor(point[0]) return add(self.color_a, multiply(distance, fraction))