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)
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)
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()
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()
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
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
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
def translate(self, T): TM = vl.translation_matrix(T) self.origin = vl.transform(TM, self.origin) self.screen = vl.transform(TM, self.screen)
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)
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