Exemple #1
0
    def hit(self, ray: Ray):
        c = self.origin
        e = ray.origin
        d = ray.dir
        r = self.radius

        # check discriminant
        disc =  (d.dot(e - c))**2 - (d.dot(d)) * ((e - c).dot(e - c) - r**2)

        if disc < 0:
            return (False, None)
        elif disc > 0:
            # two solutions
            t1 = ((d.scale(-1)).dot(e - c) - math.sqrt(disc))/d.dot(d)
            t2 = ((d.scale(-1)).dot(e - c) + math.sqrt(disc))/d.dot(d)
            n1 = self.normal(ray.getPoint(t1))
            n2 = self.normal(ray.getPoint(t2))

            # print(str(t1) + ', ' + str(t2))

            if t2 < 10**(-8):
                return (False, None)
            elif t1 < 10**(-8) and t2 >= 10**(-8):
                return (True, HitRec([t2], [n2]))
            elif t1 >= 10**(-8):
                return (True, HitRec([t1, t2], [n1, n2]))
        else:
            # one solution
            t1 = ((d.scale(-1)).dot(e - c))/d.dot(d)
            n1 = self.normal(ray.getPoint(t1))
            return (True, HitRec([t1], [n1]))
Exemple #2
0
def rayColor(ray: Ray, objects: list, depth: int, obj_ignore: Surface):
    if depth == 5:
        return (0, 0, 0)

    obj_hit, t, n = hit(ray, objects, obj_ignore)

    if (obj_hit):
        lightsource = Vec3(-50, 20, 50)
        lightsource_dir = (lightsource - ray.getPoint(t)).normalize()
        shadow_ray = Ray(ray.getPoint(t), lightsource_dir)
        SHADOWED = False

        # hex_fill = None

        for o in objects:
            res = o.hit(shadow_ray)
            if (res[0]):
                SHADOWED = True
                break
        
        if (not SHADOWED):
            h = ((ray.dir.scale(-1)) + lightsource_dir).normalize()
            reflection_dir = ray.dir - n.scale(2*ray.dir.dot(n))
            reflection = Ray(ray.getPoint(t), reflection_dir)
            rec_ref = rayColor(reflection, objects, depth+1, obj_hit)
            Lr = min(int((0.1 * 4.5 * max(0,  n.dot(lightsource_dir)) + 0.5 * 4.5 * max(0, n.dot(h)**8) + 2*rec_ref[0]/255) * 255), 255)
            Lg = min(int((0.3 * 3 * max(0,  n.dot(lightsource_dir)) + 0.5 * 3 * max(0, n.dot(h)**8) + 2*rec_ref[1]/255) * 255), 255)
            Lb = min(int((0.6 * 0.3 * max(0,  n.dot(lightsource_dir)) + 0.5 * 0.3 * max(0, n.dot(h)**8) + 2*rec_ref[2]/255) * 255), 255)

            return (Lr, Lg, Lb)

        else:
            h = ((ray.dir.scale(-1)) + lightsource_dir).normalize()
            # print(ray.getPoint(t))
            Lr = min(int(0.1 * 4.5 * max(0,  n.dot(lightsource_dir)) * 255), 255)
            Lg = min(int(0.3 * 3 * max(0,  n.dot(lightsource_dir)) * 255) , 255)
            Lb = min(int(0.3 * 0.3 * max(0,  n.dot(lightsource_dir)) * 255) , 255)

            return (Lr, Lg, Lb)

   
    return (0 , 0, 0)
Exemple #3
0
    def hit(self, ray: Ray):
        xa = self.a.x
        ya = self.a.y
        za = self.a.z

        xb = self.b.x
        yb = self.b.y
        zb = self.b.z

        xc = self.c.x
        yc = self.c.y
        zc = self.c.z

        xd = ray.dir.x
        yd = ray.dir.y
        zd = ray.dir.z

        xe = ray.origin.x
        ye = ray.origin.y
        ze = ray.origin.z

        a = xa - xb
        b = ya - yb
        c = za - zb
        d = xa - xc
        e = ya - yc
        f = za - zc

        g = xd
        h = yd 
        i =  zd
        j = xa - xe
        k = ya - ye 
        l = za - ze

        M = a*(e*i - h*f) + b*(g*f - d*i) + c*(d*h - e*g)
        if (-10**(-8) <= M <= 10**(-8)): 
            return (False, None)

        t = -1* (f*(a*k - j*b) + e*(j*c - a*l) + d*(b*l - k*c))/M
        if (t <= 10**(-8)): 
            return (False, None)

        gamma = (i*(a*k - j*b) + h*(j*c - a*l) + g*(b*l - k*c))/M
        if (gamma < 0 or gamma > 1):
            return (False, None)

        beta = (j*(e*i - h*f) + k*(g*f - d*i) + l*(d*h - e*g))/M
        if (beta < 0 or (beta + gamma) > 1 ):
            return (False, None)

        n = self.normal(ray.getPoint(t))

        return (True, HitRec([t], [n]))