예제 #1
0
파일: camera.py 프로젝트: nlintz/Raytracer
    def rotate(self, theta, direction, point=None):
        if point is None:
            point = self.origin
        RM = vl.rotation_matrix(theta, direction, point)

        self.origin = vl.transform(RM, self.origin)
        self.screen = vl.transform(RM, self.screen)
예제 #2
0
 def translate(self, T):
     TM = vl.translation_matrix(T)
     for P in self.P:
         new_vertices = [
             vl.transform(TM, P.vertices[:, i:i + 1])
             for i in range(P.vertices.shape[1])
         ]
         P.vertices = np.concatenate(new_vertices, axis=1)
예제 #3
0
 def scale(self, S):
     # TODO - SCALE AROUND CENTER
     SM = vl.scale_matrix(S)
     for P in self.P:
         new_vertices = [
             vl.transform(SM, P.vertices[:, i:i + 1])
             for i in range(P.vertices.shape[1])
         ]
         P.vertices = np.concatenate(new_vertices, axis=1)
         P.normal = P.get_normal()
예제 #4
0
 def rotate(self, theta, direction, point=None):
     # TODO - SCALE AROUND CENTER
     RM = vl.rotation_matrix(theta, direction, point)
     for P in self.P:
         new_vertices = [
             vl.transform(RM, P.vertices[:, i:i + 1])
             for i in range(P.vertices.shape[1])
         ]
         P.vertices = np.concatenate(new_vertices, axis=1)
         P.normal = P.get_normal()
예제 #5
0
파일: plane.py 프로젝트: nlintz/Raytracer
    def intersection(self, O, D):
        O_hat = vl.inverse_transform(self.T, O)
        D_hat = D
        t = vl.vdot(self.normal, -O_hat) / (vl.vdot(self.normal, D_hat))
        pred = (t > 0.)
        t_out = np.where(pred, t, global_config.MAX_DISTANCE)

        M = (O_hat + D_hat * t_out)
        M_out = vl.transform(self.T, M)
        N_out = np.ones_like(M_out) * self.normal

        return t_out, M_out, N_out
예제 #6
0
파일: sphere.py 프로젝트: nlintz/Raytracer
    def intersection(self, O, D):
        O_hat = vl.inverse_transform(
            self.S,
            vl.inverse_transform(self.R, vl.inverse_transform(self.T, O)))
        D_hat = vl.inverse_transform(self.S, vl.inverse_transform(self.R, D))
        a = vl.vdot(D_hat, D_hat)
        b = 2 * vl.vdot(O_hat, D_hat)
        c = vl.vdot(O_hat, O_hat) - 1
        disc = (b**2) - (4 * a * c)

        t0 = (-b - np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t1 = (-b + np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t = np.where((t0 > 0) & (t0 < t1), t0, t1)

        pred = (disc > 0.) & (t > 0.)
        t_out = np.where(pred, t, global_config.MAX_DISTANCE)
        M = (O_hat + D_hat * t_out)
        M_out = vl.transform(self.T,
                             vl.transform(self.R, vl.transform(self.S, M)))
        N_out = vl.vnorm(vl.transform(self.R, vl.inverse_transform(self.S, M)))

        return t_out, M_out, N_out
예제 #7
0
    def intersection(self, O, D):
        O_hat = vl.inverse_transform(
            self.S,
            vl.inverse_transform(self.R, vl.inverse_transform(self.T, O)))
        D_hat = vl.inverse_transform(self.S, vl.inverse_transform(self.R, D))

        xy_mask = np.array([1., 1., 0.]).reshape(-1, 1)
        O_xy = O_hat * xy_mask
        D_xy = D_hat * xy_mask

        a = vl.vdot(D_xy, D_xy)
        b = 2 * vl.vdot(D_xy, O_xy)
        c = vl.vdot(O_xy, O_xy) - 1

        disc = (b**2) - (4 * a * c)
        t0 = (-b - np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t1 = (-b + np.sqrt(np.maximum(disc, 0.))) / (2 * a)

        zo = O_hat[2:3]
        zd = D_hat[2:3]
        z0 = (zo + zd * t0)
        z1 = (zo + zd * t1)

        z0_mask = (t0 > 0) & (z0 <= self.z_max) & (z0 >= self.z_min) & (disc >
                                                                        0.)
        z1_mask = (t1 > 0) & (z1 <= self.z_max) & (z1 >= self.z_min) & (disc >
                                                                        0.)

        # # Compute Cylinder Intersections
        t_cand0 = np.where(z0_mask, t0, global_config.MAX_DISTANCE)
        t_cand1 = np.where(z1_mask, t1, global_config.MAX_DISTANCE)
        t_cand_cyl = np.min(np.array([t_cand0, t_cand1]), axis=0)

        # # Compute Endcap Cylinder Intersections
        if self.closed is True:
            t3 = (self.z_min - zo) / zd
            t4 = (self.z_max - zo) / zd

            P_front = (O_xy + D_xy * t3)
            P_back = (O_xy + D_xy * t4)

            front_cap_hit_mask = (vl.vdot(P_front, P_front) <= 1.)
            back_cap_hit_mask = (vl.vdot(P_back, P_back) <= 1.)

            hit_mask = (z0_mask | z1_mask)

            t_front_cap = front_cap_hit_mask * t3
            t_back_cap = back_cap_hit_mask * t4
            t_side = t_cand_cyl

            t_front_cap[t_front_cap <= 0.] = global_config.MAX_DISTANCE
            t_back_cap[t_back_cap <= 0.] = global_config.MAX_DISTANCE
            t_side[t_side <= 0.] = global_config.MAX_DISTANCE

            t_out = np.min([t_side, t_front_cap, t_back_cap], axis=0)
            t_arg_out = np.argmin([t_side, t_front_cap, t_back_cap], axis=0)

            M_out = O_hat + D_hat * t_out

            normal_cyl = hit_mask * (M_out * xy_mask)
            normal_front_cap = front_cap_hit_mask * np.array(
                [0, 0, -1]).reshape(-1, 1)
            normal_back_cap = back_cap_hit_mask * np.array([0, 0, 1]).reshape(
                -1, 1)
            normals = np.sum([
                normal_cyl * (t_arg_out == 0), normal_front_cap *
                (t_arg_out == 1), normal_back_cap * (t_arg_out == 2)
            ],
                             axis=0)

            M_out = vl.transform(
                self.T, vl.transform(self.R, vl.transform(self.S, M_out)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S, normals)))
            return t_out, M_out, N_out

        else:
            t_out = t_cand_cyl
            M = (O_hat + D_hat * t_out)
            M_out = vl.transform(self.T,
                                 vl.transform(self.R, vl.transform(self.S, M)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S,
                                                          M * xy_mask)))

            return t_out, M_out, N_out
예제 #8
0
파일: camera.py 프로젝트: nlintz/Raytracer
 def translate(self, T):
     TM = vl.translation_matrix(T)
     self.origin = vl.transform(TM, self.origin)
     self.screen = vl.transform(TM, self.screen)
예제 #9
0
    def __init__(self, center, divs, radius=1.):
        num_vertices = (divs - 1) * divs + 2
        u = -np.pi / 2
        v = -np.pi
        du = np.pi / divs
        dv = 2 * np.pi / divs
        st = []
        P = [[0., -radius, 0.]]
        N = [[0., -radius, 0.]]
        for i in range(divs - 1):
            u += du
            v = -np.pi
            for j in range(divs):
                x = radius * np.cos(u) * np.cos(v)
                y = radius * np.sin(u)
                z = radius * np.cos(u) * np.sin(v)
                P.append([x, y, z])
                N.append([x, y, z])
                st.append([u / np.pi + 0.5, v * 0.5 / np.pi + 0.5])
                v += dv
        P.append([0., radius, 0.])
        N.append([0., radius, 0.])
        npolys = divs * divs

        face_index = []
        verts_index = [0 for _ in range((6 + (divs - 1) * 4) * divs)]
        vid = 1
        l = 0
        num_v = 0
        for i in range(divs):
            for j in range(divs):
                if i == 0:
                    face_index.append(3)
                    verts_index[l] = (0)
                    verts_index[l + 1] = (j + vid)
                    if j == (divs - 1):
                        verts_index[l + 2] = vid
                    else:
                        verts_index[l + 2] = (j + vid + 1)
                    l += 3
                elif i == (divs - 1):
                    face_index.append(3)
                    verts_index[l] = (j + vid + 1 - divs)
                    verts_index[l + 1] = (vid + 1)
                    if j == (divs - 1):
                        verts_index[l + 2] = (vid + 1 - divs)
                    else:
                        verts_index[l + 2] = (j + vid + 2 - divs)
                    l += 3
                else:
                    face_index.append(4)
                    verts_index[l] = (j + vid + 1 - divs)
                    verts_index[l + 1] = (j + vid + 1)
                    if j == (divs - 1):
                        verts_index[l + 2] = (vid + 1)
                    else:
                        verts_index[l + 2] = (j + vid + 2)
                    if j == (divs - 1):
                        verts_index[l + 3] = (vid + 1 - divs)
                    else:
                        verts_index[l + 3] = (j + vid + 2 - divs)
                    l += 4
                # print i, j
                num_v += 1
            vid = num_v

        P = np.array(P).T
        P = vl.transform(vl.translation_matrix(center), P)
        super(TriSphere, self).__init__(npolys, face_index, verts_index, P)
예제 #10
0
파일: cone.py 프로젝트: nlintz/Raytracer
    def intersection(self, O, D):
        O_hat = vl.inverse_transform(
            self.S,
            vl.inverse_transform(self.R, vl.inverse_transform(self.T, O)))
        D_hat = vl.inverse_transform(self.S, vl.inverse_transform(self.R, D))

        xy_mask = np.array([1., 1., 0.]).reshape(-1, 1)
        z_mask = np.array([0., 0., 1.]).reshape(-1, 1)
        O_xy = O_hat * xy_mask
        O_z = O_hat * z_mask
        D_xy = D_hat * xy_mask
        D_z = D_hat * z_mask

        a = vl.vdot(D_xy, D_xy) - vl.vdot(D_z, D_z)
        b = (2 * vl.vdot(D_xy, O_xy)) - (2 * vl.vdot(D_z, O_z))
        c = vl.vdot(O_xy, O_xy) - vl.vdot(O_z, O_z)

        disc = (b**2) - (4 * a * c)
        t0 = (-b - np.sqrt(np.maximum(disc, 0.))) / (2 * a)
        t1 = (-b + np.sqrt(np.maximum(disc, 0.))) / (2 * a)

        zo = O_hat[2:3]
        zd = D_hat[2:3]
        z0 = (zo + zd * t0)
        z1 = (zo + zd * t1)
        z0_mask = (t0 > 0) & (z0 <= self.z_max) & (z0 >= self.z_min) & (disc >
                                                                        0.)
        z1_mask = (t1 > 0) & (z1 <= self.z_max) & (z1 >= self.z_min) & (disc >
                                                                        0.)

        # Compute Cone Intersections
        t_cand0 = np.where(z0_mask, t0, global_config.MAX_DISTANCE)
        t_cand1 = np.where(z1_mask, t1, global_config.MAX_DISTANCE)

        t_cand_cone = np.min(np.array([t_cand0, t_cand1]), axis=0)

        # Compute Endcap Cone Intersections
        if self.closed is True:
            t4 = (self.z_max - zo) / zd
            P_back = (O_xy + D_xy * t4)

            back_cap_hit_mask = (vl.vdot(P_back, P_back) <= 1.)
            hit_mask = (z0_mask | z1_mask)

            t_side = t_cand_cone
            t_back_cap = back_cap_hit_mask * t4

            t_back_cap[t_back_cap <= 0.] = global_config.MAX_DISTANCE
            t_side[t_side <= 0.] = global_config.MAX_DISTANCE

            t_out = np.min([t_side, t_back_cap], axis=0)
            t_arg_out = np.argmin([t_side, t_back_cap], axis=0)
            M_out = O_hat + D_hat * t_out

            M_norm = (M_out * xy_mask)
            M_norm[2, :] = -1.
            normal_cone = M_norm
            normal_back_cap = back_cap_hit_mask * np.array([0, 0, 1]).reshape(
                -1, 1)
            normals = np.sum([
                normal_cone * (t_arg_out == 0), normal_back_cap *
                (t_arg_out == 1)
            ],
                             axis=0)

            M_out = vl.transform(
                self.T, vl.transform(self.R, vl.transform(self.S, M_out)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S, normals)))
            return t_out, M_out, N_out

        else:
            t_out = t_cand_cone
            M = (O_hat + D_hat * t_out)
            M_norm = M * xy_mask
            M_norm[2, :] = -1.

            M_out = vl.transform(self.T,
                                 vl.transform(self.R, vl.transform(self.S, M)))
            N_out = vl.vnorm(
                vl.transform(self.R, vl.inverse_transform(self.S, M_norm)))
            return t_out, M_out, N_out