コード例 #1
0
    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
コード例 #2
0
ファイル: sphere.py プロジェクト: SteveHawk/RayTracing-Py
    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
コード例 #3
0
ファイル: aarect.py プロジェクト: SteveHawk/RayTracing-Py
    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