def get_ray(self, u, v): up = vec3.scale(self.vertical, v) right = vec3.scale(self.horizontal, u) direction = vec3.subtract(self.llc, self.origin) direction = vec3.add(direction, up) direction = vec3.add(direction, right) return Ray(self.origin, direction)
def interpolate(self, t): """ Interpolates the position of the object on this path at the specified time. Times outside the range of updates are always clamped to the first or last location update. """ # Standard bounds checks first_update_t, first_update_pos = self[0] if t <= first_update_t: return first_update_pos last_update_t, last_update_pos = self[-1] if t >= last_update_t: return last_update_pos # Otherwise, find the right pair of updates # Start the search on the first element where t >= timestamp to satisfy t >= prev_t start_idx = bisect.bisect_left(self.timestamps(), t) - 1 assert start_idx >= 0 prev_t, prev_pos = self[start_idx] for idx in range(start_idx + 1, len(self)): cur_t, cur_pos = self[idx] if t >= prev_t and t < cur_t: alpha = float(t - prev_t) / float(cur_t - prev_t) return vec3.add(vec3.scale(cur_pos, alpha), vec3.scale(prev_pos, (1.0 - alpha))) prev_t, prev_pos = cur_t, cur_pos print t, self.timestamps(), start_idx
def interpolate(self, t): """ Interpolates the position of the object on this path at the specified time. Times outside the range of updates are always clamped to the first or last location update. """ # Standard bounds checks first_update_t,first_update_pos = self[0] if t <= first_update_t: return first_update_pos last_update_t,last_update_pos = self[-1] if t >= last_update_t: return last_update_pos # Otherwise, find the right pair of updates # Start the search on the first element where t >= timestamp to satisfy t >= prev_t start_idx = bisect.bisect_left(self.timestamps(), t) - 1 assert start_idx >= 0 prev_t,prev_pos = self[start_idx] for idx in range(start_idx+1,len(self)): cur_t,cur_pos = self[idx] if t >= prev_t and t < cur_t: alpha = float(t - prev_t) / float(cur_t - prev_t) return vec3.add(vec3.scale(cur_pos, alpha), vec3.scale(prev_pos, (1.0 - alpha))) prev_t,prev_pos = cur_t,cur_pos print t, self.timestamps(), start_idx
def fromnormals_faster(n1, n2): axis = vec3.normalize(vec3.cross(n1, n2)) half_n = vec3.normalize(vec3.add(n1, n2)) cos_half_angle = vec3.dot(n1, half_n) sin_half_angle = 1.0 - cos_half_angle ** 2 return vec3.mulN(axis, sin_half_angle) + (cos_half_angle,)
def fromnormals_faster(n1,n2): axis= vec3.normalize(vec3.cross(n1, n2)) half_n= vec3.normalize(vec3.add(n1, n2)) cos_half_angle= vec3.dot(n1, half_n) sin_half_angle= 1.0 - cos_half_angle**2 return vec3.mulN(axis, sin_half_angle) + (cos_half_angle,)
def get_pos_at_time(objid, time): # initialize at the bottom, with the object we care about # as the 'parent' and position at the origin pos = (0.0, 0.0, 0.0) par = objid while par != None: next_par, par_mot = get_par_motion_for_time(par, time) pos = vec3.add(pos, par_mot.interpolate(time)) par = next_par return pos
def __init__(self, origin, lookat, up, fov, aspect): theta = fov * math.pi / 180 half_height = math.tan(theta / 2) half_width = aspect * half_height self.origin = origin w = vec3.normalize(vec3.subtract(origin, lookat)) u = vec3.normalize(vec3.cross(up, w)) v = vec3.cross(w, u) self.horizontal = vec3.scale(u, 2 * half_width) self.vertical = vec3.scale(v, 2 * half_height) center = vec3.subtract(origin, w) shift = vec3.scale(vec3.add(self.horizontal, self.vertical), 0.5) self.llc = vec3.subtract(center, shift)
def color(ray, world, depth): record = world.hit(ray, eps, float('inf')) if record: # camera receives color from a ray scattered randomly off surface if (depth < 10): scattered = record.material.scatter(ray, record) if scattered: return vec3.mult(color(scattered, world, depth + 1), record.material.attenuation) unit = vec3.normalize(ray.direction) t = 0.5 * (unit[1] + 1.0) c1 = vec3.scale((1.0, 1.0, 1.0), 1.0 - t) c2 = vec3.scale((0.5, 0.7, 1.0), t) return vec3.add(c1, c2)
def draw(): for j in range(height): for i in range(width): col = (0, 0, 0) for _ in range(n_samples): u = float(i + random.random()) / float(width) v = float(j + random.random()) / float(height) ray = camera.get_ray(u, v) col = vec3.add(col, color(ray, world, 1)) col = vec3.scale(col, 1.0 / n_samples) col = vec3.gamma_correct(col, 2.0) color_pil = tuple(int(255.99 * col[i]) for i in range(3)) color_tk = '#' + "".join("%02x" % c for c in color_pil) cv_tk.create_oval((i, height - j - 1, i + 2, height - j - 1 + 2), fill=color_tk) cv_pil.point((i, height - j - 1), fill=color_pil) root.update() print('drew row ' + str(j))
def scatter(self, ray, record): target = vec3.add(vec3.add(record.p, record.normal), vec3.rand_sphere()) scattered = Ray(record.p, vec3.subtract(target, record.p)) return scattered
def point_at_time(self, t): return vec3.add(self.origin, vec3.scale(self.direction, t))