Exemplo n.º 1
0
    def hit(self, r: Ray, t_min: float, t_max: float) -> Optional[HitRecord]:
        origin = r.origin().copy()
        direction = r.direction().copy()

        origin[0] = self.cos_theta * r.origin()[0] - self.sin_theta * r.origin(
        )[2]
        origin[2] = self.sin_theta * r.origin()[0] + self.cos_theta * r.origin(
        )[2]
        direction[0] = \
            self.cos_theta*r.direction()[0] - self.sin_theta*r.direction()[2]
        direction[2] = \
            self.sin_theta*r.direction()[0] + self.cos_theta*r.direction()[2]

        rotated_r = Ray(origin, direction, r.time())
        rec = self.obj.hit(rotated_r, t_min, t_max)
        if rec is None:
            return None

        p = rec.p.copy()
        normal = rec.normal.copy()

        p[0] = self.cos_theta * rec.p[0] + self.sin_theta * rec.p[2]
        p[2] = -self.sin_theta * rec.p[0] + self.cos_theta * rec.p[2]
        normal[0] = \
            self.cos_theta*rec.normal[0] + self.sin_theta*rec.normal[2]
        normal[2] = \
            -self.sin_theta*rec.normal[0] + self.cos_theta*rec.normal[2]

        rec.p = p
        rec.set_face_normal(rotated_r, normal)

        return rec
Exemplo n.º 2
0
 def hit_deprecated(self, r: Ray, tmin: float, tmax: float) -> bool:
     for i in range(3):
         t0: float = min((self.min()[i] - r.origin()[i]) / r.direction()[i],
                         (self.max()[i] - r.origin()[i]) / r.direction()[i])
         t1: float = min((self.min()[i] - r.origin()[i]) / r.direction()[i],
                         (self.max()[i] - r.origin()[i]) / r.direction()[i])
         tmin = max(t0, tmin)
         tmax = min(t1, tmax)
         if tmax <= tmin:
             return False
     return True
Exemplo n.º 3
0
    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
Exemplo n.º 4
0
    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
Exemplo n.º 5
0
    def hit(self, r: Ray, t_min: float, t_max: float) -> Optional[HitRecord]:
        # remove the offset to hit the real object
        moved_r = Ray(r.origin() - self.offset, r.direction(), r.time())
        rec = self.obj.hit(moved_r, t_min, t_max)
        if rec is None:
            return None

        # add the offset back to simulate the move
        rec.p += self.offset
        rec.set_face_normal(moved_r, rec.normal)
        return rec
Exemplo n.º 6
0
 def hit(self, r: Ray, tmin: float, tmax: float) -> bool:
     for i in range(3):
         invD: float = 1 / r.direction()[i]
         t0: float = (self.min()[i] - r.origin()[i]) * invD
         t1: float = (self.max()[i] - r.origin()[i]) * invD
         if invD < 0:
             t0, t1 = t1, t0
         tmin = max(t0, tmin)
         tmax = min(t1, tmax)
         if tmax <= tmin:
             return False
     return True