def handle_transform(mob: VMobject, matrix: se.Matrix) -> VMobject: mat = np.array([[matrix.a, matrix.c], [matrix.b, matrix.d]]) vec = np.array([matrix.e, matrix.f, 0.0]) mob.apply_matrix(mat) mob.shift(vec) return mob
def update_shadow(self): point = self.get_source_point() projected_screen_points = [] if not self.has_screen(): return for point in self.screen.get_anchors(): projected_screen_points.append(self.spotlight.project(point)) projected_source = project_along_vector( self.get_source_point(), self.spotlight.projection_direction()) projected_point_cloud_3d = np.append(projected_screen_points, np.reshape( projected_source, (1, 3)), axis=0) # z_to_vector(self.spotlight.projection_direction()) rotation_matrix = self.rotation_matrix() back_rotation_matrix = rotation_matrix.T # i. e. its inverse rotated_point_cloud_3d = np.dot(projected_point_cloud_3d, back_rotation_matrix.T) # these points now should all have z = 0 point_cloud_2d = rotated_point_cloud_3d[:, :2] # now we can compute the convex hull hull_2d = ConvexHull(point_cloud_2d) # guaranteed to run ccw hull = [] # we also need the projected source point source_point_2d = np.dot( self.spotlight.project(self.get_source_point()), back_rotation_matrix.T)[:2] index = 0 for point in point_cloud_2d[hull_2d.vertices]: if np.all(np.abs(point - source_point_2d) < 1.0e-6): source_index = index index += 1 continue point_3d = np.array([point[0], point[1], 0]) hull.append(point_3d) index += 1 hull_mobject = VMobject() hull_mobject.set_points_as_corners(hull) hull_mobject.apply_matrix(rotation_matrix) anchors = hull_mobject.get_anchors() # add two control points for the outer cone if np.size(anchors) == 0: self.shadow.points = [] return ray1 = anchors[source_index - 1] - projected_source ray1 = ray1 / get_norm(ray1) * 100 ray2 = anchors[source_index] - projected_source ray2 = ray2 / get_norm(ray2) * 100 outpoint1 = anchors[source_index - 1] + ray1 outpoint2 = anchors[source_index] + ray2 new_anchors = anchors[:source_index] new_anchors = np.append(new_anchors, np.array([outpoint1, outpoint2]), axis=0) new_anchors = np.append(new_anchors, anchors[source_index:], axis=0) self.shadow.set_points_as_corners(new_anchors) # shift it closer to the camera so it is in front of the spotlight self.shadow.mark_paths_closed = True
def update_shadow(self): point = self.get_source_point() projected_screen_points = [] if not self.has_screen(): return for point in self.screen.get_anchors(): projected_screen_points.append(self.spotlight.project(point)) projected_source = project_along_vector( self.get_source_point(), self.spotlight.projection_direction()) projected_point_cloud_3d = np.append( projected_screen_points, np.reshape(projected_source, (1, 3)), axis=0 ) # z_to_vector(self.spotlight.projection_direction()) rotation_matrix = self.rotation_matrix() back_rotation_matrix = rotation_matrix.T # i. e. its inverse rotated_point_cloud_3d = np.dot( projected_point_cloud_3d, back_rotation_matrix.T) # these points now should all have z = 0 point_cloud_2d = rotated_point_cloud_3d[:, :2] # now we can compute the convex hull hull_2d = ConvexHull(point_cloud_2d) # guaranteed to run ccw hull = [] # we also need the projected source point source_point_2d = np.dot(self.spotlight.project( self.get_source_point()), back_rotation_matrix.T)[:2] index = 0 for point in point_cloud_2d[hull_2d.vertices]: if np.all(np.abs(point - source_point_2d) < 1.0e-6): source_index = index index += 1 continue point_3d = np.array([point[0], point[1], 0]) hull.append(point_3d) index += 1 hull_mobject = VMobject() hull_mobject.set_points_as_corners(hull) hull_mobject.apply_matrix(rotation_matrix) anchors = hull_mobject.get_anchors() # add two control points for the outer cone if np.size(anchors) == 0: self.shadow.points = [] return ray1 = anchors[source_index - 1] - projected_source ray1 = ray1 / get_norm(ray1) * 100 ray2 = anchors[source_index] - projected_source ray2 = ray2 / get_norm(ray2) * 100 outpoint1 = anchors[source_index - 1] + ray1 outpoint2 = anchors[source_index] + ray2 new_anchors = anchors[:source_index] new_anchors = np.append(new_anchors, np.array( [outpoint1, outpoint2]), axis=0) new_anchors = np.append(new_anchors, anchors[source_index:], axis=0) self.shadow.set_points_as_corners(new_anchors) # shift it closer to the camera so it is in front of the spotlight self.shadow.mark_paths_closed = True