def renderer(): aspect_ratio = 16 / 9 image_width = 720 image_height = int(image_width / aspect_ratio) num_samples = 50 viewport_height = 2.0 viewport_width = aspect_ratio * viewport_height focal_length = 1.0 origin = vec3(0, 0, 0) horizontal = vec3(viewport_width, 0, 0) vertical = vec3(0, viewport_height, 0) lower_left_corner = origin - horizontal / 2 - vertical / 2 - vec3( 0, 0, focal_length) object_list = [ sphere(vec3(-0.5, -0.5, -1.5), 0.5, lambertian(vec3(1.0, 0.8, 1.0))), sphere(vec3(0.5, -0.5, -1.5), 0.5, metal(vec3(1.0, 1.0, 1.0), 0.0)), sphere(vec3(0.5, 0.5, -1.5), 0.5, lambertian(vec3(0.8, 1.0, 1.0))), sphere(vec3(-0.5, 0.5, -1.5), 0.5, metal(vec3(1.0, 1.0, 1.0), 0.3)) ] file = open('output.ppm', 'w') file.write("P3\n{0:d} {1:d}\n255\n".format(image_width, image_height)) pbar = tqdm(desc="Pixels rendered: ", total=image_height * image_width) for y in range(image_height - 1, -1, -1): for x in range(image_width): color = vec3(0.0, 0.0, 0.0) for s in range(num_samples): u = (x + random()) / float(image_width) v = (y + random()) / float(image_height) r = ray( origin, lower_left_corner + u * horizontal + v * vertical - origin) color = color + shoot_ray(r, object_list) color = color / float(num_samples) util.color.write_color(file, color) pbar.update(1) file.close() pbar.close()
def __init__(self, n, r=0.15, rho=None, pfile=None, p_steps=10000): self.num_spheres = n if rho: self.rad_spheres = (float(rho) / (float(n) * pi))**(0.5) else: self.rad_spheres = r self.num_dims = 2 self.box_width = (2 * self.rad_spheres) + 0.001 self.num_boxes = int(1.0 / self.box_width) if 1.0 % (self.box_width) != 0: self.num_boxes += 1 self.spheres = [] self.sphere_locations = {} self.timesteps = 0 self.pfile = pfile self.p_steps = int(p_steps) self.not_quiet = True self.display = True self.d_steps = 1000 self.slide_dist_org = 0.5 self.slide_dist = 0.5 self.debug = False self.CIRCLES = None i = 0 x_i = 0.0 for x in range(self.num_boxes): self.spheres.append([]) x_i = (x + 0.5) * self.box_width y_i = 0.5 * self.box_width for y in range(self.num_boxes): if y_i < 1 - self.rad_spheres and x_i < 1 - self.rad_spheres and i < self.num_spheres: self.spheres[x].append( [sphere(self.rad_spheres, [x_i, y_i], str(i))]) self.sphere_locations[str(i)] = (x, y) i += 1 else: self.spheres[x].append([]) y_i += self.box_width if i < self.num_spheres: print "\nWARNING: Not all disks are in the box, only " + str( i) + " disks\n" self.rho = self.num_spheres * self.spheres[0][0][0].vol()
def random_scene(): hlist = [] hlist.append(sphere(vec3(0,-1000,0), 1000, lambertian(vec3(0.5, 0.5, 0.5)))) for a in range(-11, 11): for b in range(-11, 11): choose_mat = random.random() center = vec3(a+0.9*random.random(), 0.2, b+0.9*random.random()) if (center - vec3(4, 0.2, 0)).length() > 0.9: if choose_mat < 0.8: hlist.append(sphere(center, 0.2, lambertian(vec3(random.random(), random.random(), random.random())))) elif choose_mat < 0.95: hlist.append(sphere(center, 0.2, metal(vec3(0.5*(1+random.random()), 0.5*(1+random.random()), 0.5*(1+random.random())), 0.5*random.random()))) else: hlist.append(sphere(center, 0.2, dielectric(1.5))) hlist.append(sphere(vec3(0, 1, 0), 1.0, dielectric(1.5))) hlist.append(sphere(vec3(-4, 1, 0), 1.0, lambertian(vec3(0.4, 0.2, 0.1)))) hlist.append(sphere(vec3(4, 1, 0), 1.0, metal(vec3(0.7, 0.6, 0.5), 0.0))) return hittable_list(hlist)
def mix(self, t=1000): if self.display and self.not_quiet: fig = plt.figure(1) plt.axis([0, 1, 0, 1]) ax = fig.add_subplot(1, 1, 1) ax.set_aspect('equal') CIRCLES = [None] * self.num_spheres * 9 L = (-1, 0, 1) for s in self: i = 0 for x in L: for y in L: temp_c = plt.Circle([s.coords[0] + x, s.coords[1] + y], radius=s.radius, color='g', fill=True) CIRCLES[int(s.label) * 9 + i] = temp_c ax.add_patch(temp_c) i += 1 plt.show(block=False) t0 = 0 box_buffer = 1 #- 2 * self.rad_spheres while t0 < t: x_i = randint(0, self.num_boxes - 1) y_i = randint(0, self.num_boxes - 1) while not self.spheres[x_i][y_i]: x_i = randint(0, self.num_boxes - 1) y_i = randint(0, self.num_boxes - 1) z_i = randint(0, len(self.spheres[x_i][y_i]) - 1) temp_s = self.spheres[x_i][y_i][z_i] del (self.spheres[x_i][y_i][z_i]) r_coords = [] for r in range(self.num_dims): r_coords.append(box_buffer * random()) #+ self.rad_spheres) valid, x_new, y_new = self.is_valid_move(r_coords) if valid: self.spheres[x_new][y_new].append( sphere(self.rad_spheres, r_coords, temp_s.label)) if self.display: circ_index = int(temp_s.label) i = 0 for x in L: for y in L: CIRCLES[circ_index * 9 + i].center = [ r_coords[0] + x, r_coords[1] + y ] i += 1 else: self.spheres[x_i][y_i].append( sphere(self.rad_spheres, temp_s.coords, temp_s.label)) del (temp_s) self.timesteps += 1 t0 += 1 if self.display and self.not_quiet and self.timesteps % self.d_steps == 0: plt.draw() if self.pfile and self.timesteps % self.p_steps == 0: dump(self, open(self.pfile, "wb")) if self.not_quiet: print "SAVED at timestep:", self.timesteps