Exemplo n.º 1
0
 def hit(self, ray, tmin, tmax, hit_rec):
     radius = self.radius
     center = self.center
     material = self.material
     direction = ray.direction
     oc = ray.origin - center
     a = Vec.dot(direction, direction)
     b = Vec.dot(oc, direction)
     c = Vec.dot(oc, oc) - radius*radius
     discriminant = b*b - a*c
     if discriminant > 0:
         temp = (-b - sqrt(b*b-a*c))/a
         if temp < tmax and temp > tmin:
             hit_rec.t = temp
             hit_rec.p = ray.point_at_paramater(hit_rec.t)
             hit_rec.n = (hit_rec.p - center) / radius
             hit_rec.mat = material
             return True
         temp = (-b + sqrt(b * b - a * c)) / a
         if temp < tmax and temp > tmin:
             hit_rec.t = temp
             hit_rec.p = ray.point_at_paramater(hit_rec.t)
             hit_rec.n = (hit_rec.p - center) / radius
             hit_rec.mat = material
             return True
     return False
Exemplo n.º 2
0
 def scatter(self, r_in, hit_rec, attenuation, r_scattered):
     r_in_dir = r_in.direction
     reflected = Vec.reflect(r_in_dir, hit_rec.n)
     attenuation.set(1, 1, 1)
     refracted = Vec()
     if Vec.dot(r_in_dir, hit_rec.n) > 0:
         outward_normal = -hit_rec.n
         ior = self.ref_idx
         cosine = ior * Vec.dot(r_in_dir, hit_rec.n) / r_in_dir.length()
     else:
         outward_normal = hit_rec.n
         ior = 1.0 / self.ref_idx
         cosine = -Vec.dot(r_in_dir, hit_rec.n) / r_in_dir.length()
     if Dialectric.refract(r_in_dir, outward_normal, ior, refracted):
         reflect_prob = Dialectric.schlick(cosine, self.ref_idx)
     else:
         r_scattered.A = hit_rec.p
         r_scattered.B = reflected
         reflect_prob = 1.0
     if random() < reflect_prob:
         r_scattered.A = hit_rec.p
         r_scattered.B = reflected
     else:
         r_scattered.A = hit_rec.p
         r_scattered.B = refracted
     return True
Exemplo n.º 3
0
def random_in_unit_disk():
    p = Vec()
    while True:
        p.x = 2 * random()
        p.y = 2 * random()
        if Vec.dot(p, p) >= 1:
            break
    return p
Exemplo n.º 4
0
 def scatter(self, r_in, rec, attenuation, scattered):
     reflected = r_in.direction.unit_vector().reflect(rec.normal)
     scattered.origin = rec.p
     scattered.direction = reflected
     attenuation.x = self.albedo.r
     attenuation.y = self.albedo.g
     attenuation.z = self.albedo.b
     return (Vec.dot(scattered.direction, rec.normal) > 0)
Exemplo n.º 5
0
 def scatter(self, r_in, hit_rec, attenuation, r_scattered):
     reflected = Vec.reflect_mv(Vec.unit_vector(r_in.direction), hit_rec.n)
     r_scattered.A = hit_rec.p
     r_scattered.B = Sphere.random_in_unit_sphere().mul(
         self.fuzz).add(reflected)
     attenuation.x = self.albedo.x
     attenuation.y = self.albedo.y
     attenuation.z = self.albedo.z
     return Vec.dot(r_scattered.direction, hit_rec.n) > 0
Exemplo n.º 6
0
 def refract(v, n, ior, refracted):
     uv = Vec.unit_vector(v)
     dt = Vec.dot(uv, n)
     disc = 1 - ior * ior * (1 - dt * dt)
     if disc > 0:
         sqrt_disc = sqrt(disc)
         refracted.x = ior * (uv.x - n.x * dt) - n.x * sqrt_disc
         refracted.y = ior * (uv.y - n.y * dt) - n.y * sqrt_disc
         refracted.z = ior * (uv.z - n.z * dt) - n.z * sqrt_disc
         return True
     else:
         return False
Exemplo n.º 7
0
    def hit(self, r, t_min, t_max, rec):
        oc = r.origin - self.center
        a = r.direction.length_squared()
        half_b = Vec.dot(oc, r.direction)
        c = oc.length_squared() - self.radius * self.radius
        discriminant = half_b * half_b - a * c
        if (discriminant < 0):
            return False
        sqrtd = math.sqrt(discriminant)

        # find the nearest root that lies in the acceptable range
        root = (-half_b - sqrtd) / a
        if (root < t_min or t_max < root):
            root = (-half_b + sqrtd) / a
            if (root < t_min or t_max < root):
                return False
        rec.t = root
        rec.p = r.at(rec.t)
        outward_normal = (rec.p - self.center) / self.radius
        rec.set_face_normal(r, outward_normal)
        rec.material = self.material
        return True
Exemplo n.º 8
0
 def set_face_normal(self, r, outward_normal):
     self.front_face = Vec.dot(r.direction, outward_normal) < 0
     if self.front_face:
         self.normal = outward_normal
     else:
         self.normal = -outward_normal