def hit(self, r: Ray, t_min: float, t_max: float) -> Optional[HitRecord]: rec1 = self.boundary.hit(r, -np.inf, np.inf) if rec1 is None: return None rec2 = self.boundary.hit(r, rec1.t + 0.0001, np.inf) if rec2 is None: return None if rec1.t < t_min: rec1.t = t_min if rec1.t < 0: rec1.t = 0 if rec2.t > t_max: rec2.t = t_max if rec1.t >= rec2.t: return None ray_length = r.direction().length() distance_inside_boundary = (rec2.t - rec1.t) * ray_length hit_distance = self.neg_inv_density * np.log(random_float()) if hit_distance > distance_inside_boundary: return None t = rec1.t + hit_distance / ray_length p = r.at(t) rec = HitRecord(p, t, self.phase_function) rec.normal = Vec3(1, 0, 0) rec.front_face = True return rec
def hit(self, r: Ray, t_min: float, t_max: float) -> Optional[HitRecord]: oc: Vec3 = r.origin() - self.center a: float = r.direction().length_squared() half_b: float = oc @ r.direction() c: float = oc.length_squared() - self.radius**2 discriminant: float = half_b**2 - a * c if discriminant > 0: root: float = np.sqrt(discriminant) t_0: float = (-half_b - root) / a t_1: float = (-half_b + root) / a if t_min < t_0 < t_max: t = t_0 elif t_min < t_1 < t_max: t = t_1 else: return None point: Point3 = r.at(t) outward_normal: Vec3 = (point - self.center) / self.radius rec = HitRecord(point, t, self.material) rec.set_face_normal(r, outward_normal) return rec return None
def hit(self, r: Ray, t_min: float, t_max: float) -> Optional[HitRecord]: t = (self.k - r.origin().x()) / r.direction().x() if t < t_min or t > t_max: return None y = r.origin().y() + t*r.direction().y() z = r.origin().z() + t*r.direction().z() if (y < self.y0) or (y > self.y1) or (z < self.z0) or (z > self.z1): return None rec = HitRecord(r.at(t), t, self.material) rec.set_face_normal(r, Vec3(1, 0, 0)) rec.u = (y - self.y0) / (self.y1 - self.y0) rec.v = (z - self.z0) / (self.z1 - self.z0) return rec