diff --git a/manimlib/camera/camera.py b/manimlib/camera/camera.py index 94c111eb23..e859a3a036 100644 --- a/manimlib/camera/camera.py +++ b/manimlib/camera/camera.py @@ -26,6 +26,19 @@ class Camera(object): + """ + Base Camera class. + This is the object which takes care of what exactly is displayed + on screen at any given moment. + + Some important CONFIG values and local variables to note are: + + self.background_image : str, optional + The path to an image that should be the background image. + If not set, the background is filled with `self.background_color` + + self.pixel_height + """ CONFIG = { "background_image": None, "pixel_height": DEFAULT_PIXEL_HEIGHT, @@ -51,6 +64,15 @@ class Camera(object): } def __init__(self, background=None, **kwargs): + """Initialises the Camera. + + Parameters + ---------- + background : optional + What self.background should be, by default None as will be set later. + **kwargs + Any local variables to be set. + """ digest_config(self, kwargs, locals()) self.rgb_max_val = np.iinfo(self.pixel_array_dtype).max self.pixel_array_to_cairo_context = {} @@ -66,6 +88,16 @@ def __deepcopy__(self, memo): return copy.copy(self) def reset_pixel_shape(self, new_height, new_width): + """This method resets the height and width + of a single pixel to the passed new_heigh and new_width. + + Parameters + ---------- + new_height : int, float + The new height of the entire scene in pixels + new_width : int, float + The new width of the entire scene in pixels + """ self.pixel_width = new_width self.pixel_height = new_height self.init_background() @@ -73,27 +105,89 @@ def reset_pixel_shape(self, new_height, new_width): self.reset() def get_pixel_height(self): + """Returns the height of the scene in + pixel at that moment. + + Returns + ------- + int + The height of the scene in pixels. + """ return self.pixel_height def get_pixel_width(self): + """Returns the width of the scene in + pixels at that moment. + + Returns + ------- + int + The width of the scene in pixels. + """ return self.pixel_width def get_frame_height(self): + """Returns the height of the frame + in MUnits. Default is 8.0 + + Returns + ------- + float + The frame height + """ return self.frame_height def get_frame_width(self): + """Returns the width of the frame + in MUnits. + + Returns + ------- + float + The frame width + """ return self.frame_width def get_frame_center(self): + """Returns the absolute center of the frame as Cartesian + Coordinates with the unit MUnits. + + Returns + ------- + np.array + The array of x,y,z coordinates. + """ return self.frame_center def set_frame_height(self, frame_height): + """Sets the frame height to the passed value. + + Parameters + ---------- + frame_height : int, float + The frame_height in MUnits. + """ self.frame_height = frame_height def set_frame_width(self, frame_width): + """Sets the frame width to the passed value. + + Parameters + ---------- + frame_width : int, float + The frame_width in MUnits. + """ self.frame_width = frame_width def set_frame_center(self, frame_center): + """Sets the center of the frame to the passed + cartesian coordinates. + + Parameters + ---------- + frame_center : np.array + The center of the frame. + """ self.frame_center = frame_center def resize_frame_shape(self, fixed_dimension=0): @@ -102,6 +196,12 @@ def resize_frame_shape(self, fixed_dimension=0): of the pixels, where fixed_dimension determines whether frame_height or frame_width remains fixed while the other changes accordingly. + + Parameters + ---------- + fixed_dimension : int + If 0, height is scaled with respect to width + else, width is scaled with respect to height. """ pixel_height = self.get_pixel_height() pixel_width = self.get_pixel_width() @@ -116,6 +216,11 @@ def resize_frame_shape(self, fixed_dimension=0): self.set_frame_width(frame_width) def init_background(self): + """Initialize the background. + If self.background_image is the path of an image + the image is set as background; else, the default + background color fills the background. + """ height = self.get_pixel_height() width = self.get_pixel_width() if self.background_image is not None: @@ -136,6 +241,20 @@ def init_background(self): self.background[:, :] = background_rgba def get_image(self, pixel_array=None): + """Returns an image from the passed + pixel array, or from the current frame + if the passed pixel array is none. + + Parameters + ---------- + pixel_array : np.array, list, tuple, optional + The pixel array from which to get an image, by default None + + Returns + ------- + PIL.Image + The PIL image of the array. + """ if pixel_array is None: pixel_array = self.pixel_array return Image.fromarray( @@ -144,9 +263,32 @@ def get_image(self, pixel_array=None): ) def get_pixel_array(self): + """Returns the pixel array + of the current frame. + + Returns + ------- + np.array + The array of RGB values of each pixel. + """ return self.pixel_array def convert_pixel_array(self, pixel_array, convert_from_floats=False): + """Converts a pixel array from values that have floats in then + to proper RGB values. + + Parameters + ---------- + pixel_array : np.array, list, tuple + Pixel array to convert. + convert_from_floats : bool, optional + Whether or not to convert float values to ints, by default False + + Returns + ------- + np.array + The new, converted pixel array. + """ retval = np.array(pixel_array) if convert_from_floats: retval = np.apply_along_axis( @@ -157,6 +299,15 @@ def convert_pixel_array(self, pixel_array, convert_from_floats=False): return retval def set_pixel_array(self, pixel_array, convert_from_floats=False): + """Sets the pixel array of the camera to the passed pixel array. + + Parameters + ---------- + pixel_array : np.array, list, tuple + The pixel array to convert and then set as the camera's pixel array. + convert_from_floats : bool, optional + Whether or not to convert float values to proper RGB values, by default False + """ converted_array = self.convert_pixel_array( pixel_array, convert_from_floats) if not (hasattr(self, "pixel_array") and self.pixel_array.shape == converted_array.shape): @@ -166,15 +317,35 @@ def set_pixel_array(self, pixel_array, convert_from_floats=False): self.pixel_array[:, :, :] = converted_array[:, :, :] def set_background(self, pixel_array, convert_from_floats=False): + """Sets the background to the passed pixel_array after converting + to valid RGB values. + + Parameters + ---------- + pixel_array : np.array, list, tuple + The pixel array to set the background to. + convert_from_floats : bool, optional + Whether or not to convert floats values to proper RGB valid ones, by default False + """ self.background = self.convert_pixel_array( pixel_array, convert_from_floats) # TODO, this should live in utils, not as a method of Camera def make_background_from_func(self, coords_to_colors_func): """ - Sets background by using coords_to_colors_func to determine each pixel's color. Each input - to coords_to_colors_func is an (x, y) pair in space (in ordinary space coordinates; not + Makes a pixel array for the background by using coords_to_colors_func to determine each pixel's color. Each input + pixel's color. Each input to coords_to_colors_func is an (x, y) pair in space (in ordinary space coordinates; not pixel coordinates), and each output is expected to be an RGBA array of 4 floats. + + Parameters + ---------- + coords_to_colors_func : function + The function whose input is an (x,y) pair of coordinats and + whose return values must be the colors for that point + Returns + ------- + np.array + The pixel array which can then be passed to set_background. """ print("Starting set_background; for reference, the current time is ", time.strftime("%H:%M:%S")) @@ -189,10 +360,29 @@ def make_background_from_func(self, coords_to_colors_func): return self.convert_pixel_array(new_background, convert_from_floats=True) def set_background_from_func(self, coords_to_colors_func): + """ + Sets the background to a pixel array using coords_to_colors_func to determine each pixel's color. Each input + pixel's color. Each input to coords_to_colors_func is an (x, y) pair in space (in ordinary space coordinates; not + pixel coordinates), and each output is expected to be an RGBA array of 4 floats. + + Parameters + ---------- + coords_to_colors_func : function + The function whose input is an (x,y) pair of coordinats and + whose return values must be the colors for that point + """ self.set_background( self.make_background_from_func(coords_to_colors_func)) def reset(self): + """Resets the camera's pixel array + to that of the background + + Returns + ------- + Camera + The camera object after setting the pixel array. + """"" self.set_pixel_array(self.background) return self @@ -203,6 +393,22 @@ def reset(self): def extract_mobject_family_members( self, mobjects, only_those_with_points=False): + """Returns a list of the types of mobjects and + their family members present. + + Parameters + ---------- + mobjects : Mobject + The Mobjects currently in the Scene + only_those_with_points : bool, optional + Whether or not to only do this for + those mobjects that have points. By default False + + Returns + ------- + list + list of the mobjects and family members. + """ if only_those_with_points: method = Mobject.family_members_with_points else: @@ -215,6 +421,23 @@ def get_mobjects_to_display( self, mobjects, include_submobjects=True, excluded_mobjects=None): + """Used to get the list of mobjects to display + with the camera. + + Parameters + ---------- + mobjects : Mobject + The Mobjects + include_submobjects : bool, optional + Whether or not to include the submobjects of mobjects, by default True + excluded_mobjects : list, optional + Any mobjects to exclude, by default None + + Returns + ------- + list + list of mobjects + """ if include_submobjects: mobjects = self.extract_mobject_family_members( mobjects, only_those_with_points=True, @@ -227,6 +450,19 @@ def get_mobjects_to_display( return mobjects def is_in_frame(self, mobject): + """Checks whether the passed mobject is in + frame or not. + + Parameters + ---------- + mobject : Mobject + The mobject for which the checking needs to be done. + + Returns + ------- + bool + True if in frame, False otherwise. + """ fc = self.get_frame_center() fh = self.get_frame_height() fw = self.get_frame_width() @@ -237,10 +473,10 @@ def is_in_frame(self, mobject): mobject.get_top()[1] < fc[1] - fh, ]) - def capture_mobject(self, mobject, **kwargs): + def capture_mobject(self, mobject, **kwargs): #TODO Write better docstrings for this method. return self.capture_mobjects([mobject], **kwargs) - def capture_mobjects(self, mobjects, **kwargs): + def capture_mobjects(self, mobjects, **kwargs): #TODO Write better docstrings for this method. mobjects = self.get_mobjects_to_display(mobjects, **kwargs) # Organize this list into batches of the same type, and @@ -270,15 +506,55 @@ def get_mobject_type(mobject): # Methods associated with svg rendering + # NOTE: None of the methods below have been mentioned outside of their definitions. Their DocStrings are not as + # detailed as possible. + def get_cached_cairo_context(self, pixel_array): + """Returns the cached cairo context of the passed + pixel array if it exists, and None if it doesn't. + + Parameters + ---------- + pixel_array : np.array + The pixel array to check. + + Returns + ------- + Cairo.Context.Context + The cached cairo context. + """ return self.pixel_array_to_cairo_context.get( id(pixel_array), None ) def cache_cairo_context(self, pixel_array, ctx): + """Caches the passed Pixel array into a Cairo Context + + Parameters + ---------- + pixel_array : np.array + The pixel array to cache + ctx : Cairo.Context.Context + The context to cache it into. + """ self.pixel_array_to_cairo_context[id(pixel_array)] = ctx def get_cairo_context(self, pixel_array): + """Returns the cairo context for a pixel array after + caching it to self.pixel_array_to_cairo_context + If that array has already been cached, it returns the + cached version instead. + + Parameters + ---------- + pixel_array : np.array + The Pixel array to get the cairo context of. + + Returns + ------- + cairo.Context + The cairo context of the pixel array. + """ cached_ctx = self.get_cached_cairo_context(pixel_array) if cached_ctx: return cached_ctx @@ -304,6 +580,15 @@ def get_cairo_context(self, pixel_array): return ctx def display_multiple_vectorized_mobjects(self, vmobjects, pixel_array): + """Displays multiple VMobjects in the pixel_array + + Parameters + ---------- + vmobjects : list + list of VMobjects to display + pixel_array : np.array + The pixel array + """ if len(vmobjects) == 0: return batch_file_pairs = batch_by_property( @@ -317,11 +602,35 @@ def display_multiple_vectorized_mobjects(self, vmobjects, pixel_array): self.display_multiple_non_background_colored_vmobjects(batch, pixel_array) def display_multiple_non_background_colored_vmobjects(self, vmobjects, pixel_array): + """Displays multiple VMobjects in the cairo context, as long as they don't have + background colors. + + Parameters + ---------- + vmobjects : list + list of the VMobjects + pixel_array : np.ndarray + The Pixel array to add the VMobjects to. + """ ctx = self.get_cairo_context(pixel_array) for vmobject in vmobjects: self.display_vectorized(vmobject, ctx) def display_vectorized(self, vmobject, ctx): + """Displays a VMobject in the cairo context + + Parameters + ---------- + vmobject : VMobject + The Vectorized Mobject to display + ctx : cairo.Context + The cairo context to use. + + Returns + ------- + Camera + The camera object + """ self.set_cairo_context_path(ctx, vmobject) self.apply_stroke(ctx, vmobject, background=True) self.apply_fill(ctx, vmobject) @@ -329,6 +638,20 @@ def display_vectorized(self, vmobject, ctx): return self def set_cairo_context_path(self, ctx, vmobject): + """Sets a path for the cairo context with the vmobject passed + + Parameters + ---------- + ctx : cairo.Context + The cairo context + vmobject : VMobject + The VMobject + + Returns + ------- + Camera + Camera object after setting cairo_context_path + """ points = self.transform_points_pre_display( vmobject, vmobject.points ) @@ -351,6 +674,22 @@ def set_cairo_context_path(self, ctx, vmobject): return self def set_cairo_context_color(self, ctx, rgbas, vmobject): + """Sets the color of the cairo context + + Parameters + ---------- + ctx : cairo.Context + The cairo context + rgbas : np.ndarray + The RGBA array with which to color the context. + vmobject : VMobject + The VMobject with which to set the color. + + Returns + ------- + Camera + The camera object + """ if len(rgbas) == 1: # Use reversed rgb because cairo surface is # encodes it in reverse order @@ -375,6 +714,20 @@ def set_cairo_context_color(self, ctx, rgbas, vmobject): return self def apply_fill(self, ctx, vmobject): + """Fills the cairo context + + Parameters + ---------- + ctx : cairo.Context + The cairo context + vmobject : VMobject + The VMobject + + Returns + ------- + Camera + The camera object. + """ self.set_cairo_context_color( ctx, self.get_fill_rgbas(vmobject), vmobject ) @@ -382,6 +735,23 @@ def apply_fill(self, ctx, vmobject): return self def apply_stroke(self, ctx, vmobject, background=False): + """Applies a stroke to the VMobject in the cairo context. + + Parameters + ---------- + ctx : cairo.Context + The cairo context + vmobject : VMobject + The VMobject + background : bool, optional + Whether or not to consider the background when applying this + stroke width, by default False + + Returns + ------- + Camera + The camera object with the stroke applied. + """ width = vmobject.get_stroke_width(background) if width == 0: return self @@ -400,12 +770,49 @@ def apply_stroke(self, ctx, vmobject, background=False): return self def get_stroke_rgbas(self, vmobject, background=False): + """Get's the RGBA array for the stroke of the passed + VMobject. + + Parameters + ---------- + vmobject : VMobject + The VMobject + background : bool, optional + Whether or not to consider the background when getting the stroke + RGBAs, by default False + + Returns + ------- + np.ndarray + The RGBA array of the stroke. + """ return vmobject.get_stroke_rgbas(background) def get_fill_rgbas(self, vmobject): + """Returns the RGBA array of the fill of the passed VMobject + + Parameters + ---------- + vmobject : VMobject + The VMobject + + Returns + ------- + np.array + The RGBA Array of the fill of the VMobject + """ return vmobject.get_fill_rgbas() def get_background_colored_vmobject_displayer(self): + """Returns the background_colored_vmobject_displayer + if it exists or makes one and returns it if not. + + Returns + ------- + BackGroundColoredVMobjectDisplayer + Object that displays VMobjects that have the same color + as the background. + """ # Quite wordy to type out a bunch bcvd = "background_colored_vmobject_displayer" if not hasattr(self, bcvd): @@ -413,6 +820,20 @@ def get_background_colored_vmobject_displayer(self): return getattr(self, bcvd) def display_multiple_background_colored_vmobject(self, cvmobjects, pixel_array): + """Displays multiple vmobjects that have the same color as the background. + + Parameters + ---------- + cvmobjects : list + List of Colored VMobjects + pixel_array : np.array + The pixel array. + + Returns + ------- + Camera + The camera object. + """ displayer = self.get_background_colored_vmobject_displayer() cvmobject_pixel_array = displayer.display(*cvmobjects) self.overlay_rgba_array(pixel_array, cvmobject_pixel_array) @@ -420,7 +841,19 @@ def display_multiple_background_colored_vmobject(self, cvmobjects, pixel_array): # Methods for other rendering + # NOTE: Out of the following methods, only `transform_points_pre_display` and `points_to_pixel_coords` have been mentioned outside of their definitions. + # As a result, the other methods do not have as detailed docstrings as would be preferred. + def display_multiple_point_cloud_mobjects(self, pmobjects, pixel_array): + """Displays multiple PMobjects by modifying the passed pixel array. + + Parameters + ---------- + pmobjects : list + List of PMobjects + pixel_array : np.array + The pixel array to modify. + """ for pmobject in pmobjects: self.display_point_cloud( pmobject, @@ -431,6 +864,21 @@ def display_multiple_point_cloud_mobjects(self, pmobjects, pixel_array): ) def display_point_cloud(self, pmobject, points, rgbas, thickness, pixel_array): + """Displays a PMobject by modifying the Pixel array suitably.. + TODO: Write a description for the rgbas argument. + Parameters + ---------- + pmobject : PMobject + Point Cloud Mobject + points : list + The points to display in the point cloud mobject + rgbas : np.array + + thickness : int, float + The thickness of each point of the PMobject + pixel_array : np.array + The pixel array to modify. + """ if len(points) == 0: return pixel_coords = self.points_to_pixel_coords( @@ -463,10 +911,28 @@ def display_point_cloud(self, pmobject, points, rgbas, thickness, pixel_array): pixel_array[:, :] = new_pa.reshape((ph, pw, rgba_len)) def display_multiple_image_mobjects(self, image_mobjects, pixel_array): + """Displays multiple image mobjects by modifiying the passed pixel_array. + + Parameters + ---------- + image_mobjects : list + list of ImageMobjects + pixel_array : np.array + The pixel array to modify. + """ for image_mobject in image_mobjects: self.display_image_mobject(image_mobject, pixel_array) def display_image_mobject(self, image_mobject, pixel_array): + """Displays an ImageMobject by changing the pixel_array suitably. + + Parameters + ---------- + image_mobject : ImageMobject + The imageMobject to display + pixel_array : np.ndarray + The Pixel array to put the imagemobject in. + """ corner_coords = self.points_to_pixel_coords( image_mobject, image_mobject.points ) @@ -517,12 +983,30 @@ def display_image_mobject(self, image_mobject, pixel_array): self.overlay_PIL_image(pixel_array, full_image) def overlay_rgba_array(self, pixel_array, new_array): + """Overlays an RGBA array on top of the given Pixel array. + + Parameters + ---------- + pixel_array : np.array + The original pixel array to modify. + new_array : np.array + The new pixel array to overlay. + """ self.overlay_PIL_image( pixel_array, self.get_image(new_array), ) def overlay_PIL_image(self, pixel_array, image): + """Overlays a PIL image on the passed pixel array. + + Parameters + ---------- + pixel_array : np.ndarray + The Pixel array + image : PIL.Image + The Image to overlay. + """ pixel_array[:, :] = np.array( Image.alpha_composite( self.get_image(pixel_array), @@ -532,6 +1016,19 @@ def overlay_PIL_image(self, pixel_array, image): ) def adjust_out_of_range_points(self, points): + """If any of the points in the passed array are out of + the viable range, they are adjusted suitably. + + Parameters + ---------- + points : np.array + The points to adjust + + Returns + ------- + np.array + The adjusted points. + """ if not np.any(points > self.max_allowable_norm): return points norms = np.apply_along_axis(get_norm, 1, points) @@ -546,7 +1043,9 @@ def adjust_out_of_range_points(self, points): points[violator_indices] = rescaled return points - def transform_points_pre_display(self, mobject, points): + def transform_points_pre_display(self, mobject, points): #TODO: Write more detailed docstrings for this method. + #NOTE: There seems to be an unused argument `mobject`. + # Subclasses (like ThreeDCamera) may want to # adjust points futher before they're shown if not np.all(np.isfinite(points)): @@ -555,7 +1054,7 @@ def transform_points_pre_display(self, mobject, points): points = np.zeros((1, 3)) return points - def points_to_pixel_coords(self, mobject, points): + def points_to_pixel_coords(self, mobject, points): #TODO: Write more detailed docstrings for this method. points = self.transform_points_pre_display( mobject, points ) @@ -578,6 +1077,19 @@ def points_to_pixel_coords(self, mobject, points): return result.astype('int') def on_screen_pixels(self, pixel_coords): + """Returns array of pixels that are on the screen from a given + array of pixel_coordinates + + Parameters + ---------- + pixel_coords : np.array + The pixel coords to check. + + Returns + ------- + np.array + The pixel coords on screen. + """ return reduce(op.and_, [ pixel_coords[:, 0] >= 0, pixel_coords[:, 0] < self.get_pixel_width(), @@ -586,6 +1098,17 @@ def on_screen_pixels(self, pixel_coords): ]) def adjusted_thickness(self, thickness): + """ + + Parameters + ---------- + thickness : int, float + + Returns + ------- + float + + """ # TODO: This seems...unsystematic big_sum = op.add( PRODUCTION_QUALITY_CAMERA_CONFIG["pixel_height"], @@ -599,11 +1122,37 @@ def adjusted_thickness(self, thickness): return 1 + (thickness - 1) / factor def get_thickening_nudges(self, thickness): + """ + + Parameters + ---------- + thickness : int, float + + Returns + ------- + np.array + + """ thickness = int(thickness) _range = list(range(-thickness // 2 + 1, thickness // 2 + 1)) return np.array(list(it.product(_range, _range))) def thickened_coordinates(self, pixel_coords, thickness): + """Returns thickened coordinates for a passed array of pixel coords and + a thickness to thicken by. + + Parameters + ---------- + pixel_coords : np.array + Pixel coordinates + thickness : int, float + Thickness + + Returns + ------- + np.array + Array of thickened pixel coords. + """ nudges = self.get_thickening_nudges(thickness) pixel_coords = np.array([ pixel_coords + nudge @@ -614,6 +1163,13 @@ def thickened_coordinates(self, pixel_coords, thickness): # TODO, reimplement using cairo matrix def get_coords_of_all_pixels(self): + """Returns the cartesian coordinates of each pixel. + + Returns + ------- + np.ndarray + The array of cartesian coordinates. + """ # These are in x, y order, to help me keep things straight full_space_dims = np.array([ self.get_frame_width(), @@ -647,9 +1203,16 @@ def get_coords_of_all_pixels(self): return centered_space_coords - +# NOTE: The methods of the following class have not been mentioned outside of their definitons. +# Their DocStrings are not as detailed as preferred. class BackgroundColoredVMobjectDisplayer(object): def __init__(self, camera): + """ + Parameters + ---------- + camera : Camera + Camera object to use. + """ self.camera = camera self.file_name_to_pixel_array_map = {} self.pixel_array = np.array(camera.get_pixel_array()) @@ -663,17 +1226,61 @@ def resize_background_array( new_width, new_height, mode="RGBA" ): + """Resizes the pixel array represinting the background. + + Parameters + ---------- + background_array : np.array + The pixel + new_width : int, float + The new width of the background + new_height : int, float + The new height of the background + mode : str, optional + The PIL image mode, by default "RGBA" + + Returns + ------- + np.array + The numpy pixel array of the resized background. + """ image = Image.fromarray(background_array) image = image.convert(mode) resized_image = image.resize((new_width, new_height)) return np.array(resized_image) def resize_background_array_to_match(self, background_array, pixel_array): + """Resizes the background array to match the passed pixel array. + + Parameters + ---------- + background_array : np.array + The prospective pixel array. + pixel_array : np.array + The pixel array whose width and height should be matched. + + Returns + ------- + np.array + The resized background array. + """ height, width = pixel_array.shape[:2] mode = "RGBA" if pixel_array.shape[2] == 4 else "RGB" return self.resize_background_array(background_array, width, height, mode) def get_background_array(self, file_name): + """Gets the background array that has the passed file_name. + + Parameters + ---------- + file_name : str + The file_name of the background image. + + Returns + ------- + np.ndarray + The pixel array of the file whose file name is `file_name` + """ if file_name in self.file_name_to_pixel_array_map: return self.file_name_to_pixel_array_map[file_name] full_path = get_full_raster_image_path(file_name) @@ -690,6 +1297,18 @@ def get_background_array(self, file_name): return back_array def display(self, *cvmobjects): + """Displays the colored VMobjects. + + Parameters + ---------- + *cvmobjects : VMobject + The VMobjects + + Returns + ------- + np.array + The pixel array with the `cvmobjects` displayed. + """ batch_image_file_pairs = batch_by_property( cvmobjects, lambda cv: cv.get_background_image_file() ) diff --git a/manimlib/camera/mapping_camera.py b/manimlib/camera/mapping_camera.py index c80c91cfec..87cdf436ce 100644 --- a/manimlib/camera/mapping_camera.py +++ b/manimlib/camera/mapping_camera.py @@ -10,6 +10,9 @@ class MappingCamera(Camera): + """Camera object that allows mapping + between objects. + """ CONFIG = { "mapping_func": lambda p: p, "min_num_curves": 50, diff --git a/manimlib/camera/moving_camera.py b/manimlib/camera/moving_camera.py index c54a1e6b2b..f6417ca576 100644 --- a/manimlib/camera/moving_camera.py +++ b/manimlib/camera/moving_camera.py @@ -48,21 +48,65 @@ def __init__(self, frame=None, **kwargs): # TODO, make these work for a rotated frame def get_frame_height(self): + """Returns the height of the frame. + + Returns + ------- + float + The height of the frame. + """ return self.frame.get_height() def get_frame_width(self): + """Returns the width of the frame + + Returns + ------- + float + The width of the frame. + """ return self.frame.get_width() def get_frame_center(self): + """Returns the centerpoint of the frame in cartesian coordinates. + + Returns + ------- + np.array + The cartesian coordinates of the center of the frame. + """ return self.frame.get_center() def set_frame_height(self, frame_height): + """Sets the height of the frame in MUnits. + + Parameters + ---------- + frame_height : int, float + The new frame_height. + """ self.frame.stretch_to_fit_height(frame_height) def set_frame_width(self, frame_width): + """Sets the width of the frame in MUnits. + + Parameters + ---------- + frame_width : int, float + The new frame_width. + """ self.frame.stretch_to_fit_width(frame_width) def set_frame_center(self, frame_center): + """Sets the centerpoint of the frame. + + Parameters + ---------- + frame_center : np.array, list, tuple, Mobject + The point to which the frame must be moved. + If is of type mobject, the frame will be moved to + the center of that mobject. + """ self.frame.move_to(frame_center) def capture_mobjects(self, mobjects, **kwargs): @@ -74,9 +118,19 @@ def capture_mobjects(self, mobjects, **kwargs): # context used for updating should be regenerated # at each frame. So no caching. def get_cached_cairo_context(self, pixel_array): + """ + Since the frame can be moving around, the cairo + context used for updating should be regenerated + at each frame. So no caching. + """ return None def cache_cairo_context(self, pixel_array, ctx): + """ + Since the frame can be moving around, the cairo + context used for updating should be regenerated + at each frame. So no caching. + """ pass # def reset_frame_center(self): @@ -94,5 +148,9 @@ def get_mobjects_indicating_movement(self): """ Returns all mobjets whose movement implies that the camera should think of all other mobjects on the screen as moving + + Returns + ------- + list """ return [self.frame] diff --git a/manimlib/camera/multi_camera.py b/manimlib/camera/multi_camera.py index 9283b0e79a..504bc8acbf 100644 --- a/manimlib/camera/multi_camera.py +++ b/manimlib/camera/multi_camera.py @@ -3,17 +3,36 @@ class MultiCamera(MovingCamera): + """Camera Object that allows for multiple perspectives. + """ CONFIG = { "allow_cameras_to_capture_their_own_display": False, } def __init__(self, *image_mobjects_from_cameras, **kwargs): + """Initalises the MultiCamera + + Parameters: + ----------- + *image_mobjects_from_cameras : ImageMobject + + **kwargs + Any valid keyword arguments of MovingCamera. + """ self.image_mobjects_from_cameras = [] for imfc in image_mobjects_from_cameras: self.add_image_mobject_from_camera(imfc) MovingCamera.__init__(self, **kwargs) def add_image_mobject_from_camera(self, image_mobject_from_camera): + """Adds an ImageMobject that's been obtained from the camera + into the list `self.image_mobject_from_cameras` + + Parameters + ---------- + image_mobject_from_camera : ImageMobject + The ImageMobject to add to self.image_mobject_from_cameras + """ # A silly method to have right now, but maybe there are things # we want to guarantee about any imfc's added later. imfc = image_mobject_from_camera @@ -34,6 +53,13 @@ def update_sub_cameras(self): ) def reset(self): + """Resets the MultiCamera. + + Returns + ------- + MultiCamera + The reset MultiCamera + """ for imfc in self.image_mobjects_from_cameras: imfc.camera.reset() MovingCamera.reset(self) @@ -51,6 +77,13 @@ def capture_mobjects(self, mobjects, **kwargs): MovingCamera.capture_mobjects(self, mobjects, **kwargs) def get_mobjects_indicating_movement(self): + """Returns all mobjets whose movement implies that the camera + should think of all other mobjects on the screen as moving + + Returns + ------- + list + """ return [self.frame] + [ imfc.camera.frame for imfc in self.image_mobjects_from_cameras diff --git a/manimlib/camera/three_d_camera.py b/manimlib/camera/three_d_camera.py index 5cf4ba0d10..0a61d3cd7d 100644 --- a/manimlib/camera/three_d_camera.py +++ b/manimlib/camera/three_d_camera.py @@ -30,6 +30,15 @@ class ThreeDCamera(Camera): } def __init__(self, *args, **kwargs): + """Initialises the ThreeDCamera + + Parameters + ---------- + *args + Any argument of Camera + *kwargs + Any keyword argument of Camera. + """ Camera.__init__(self, *args, **kwargs) self.phi_tracker = ValueTracker(self.phi) self.theta_tracker = ValueTracker(self.theta) @@ -46,6 +55,13 @@ def capture_mobjects(self, mobjects, **kwargs): Camera.capture_mobjects(self, mobjects, **kwargs) def get_value_trackers(self): + """Returns list of ValueTrackers of phi, theta, distance and gamma + + Returns + ------- + list + list of ValueTracker objects + """ return [ self.phi_tracker, self.theta_tracker, @@ -53,7 +69,7 @@ def get_value_trackers(self): self.gamma_tracker, ] - def modified_rgbas(self, vmobject, rgbas): + def modified_rgbas(self, vmobject, rgbas): # TODO: Write DocStrings for this method. if not self.should_apply_shading: return rgbas if vmobject.shade_in_3d and (vmobject.get_num_points() > 0): @@ -77,17 +93,17 @@ def modified_rgbas(self, vmobject, rgbas): return shaded_rgbas return rgbas - def get_stroke_rgbas(self, vmobject, background=False): + def get_stroke_rgbas(self, vmobject, background=False): #NOTE : DocStrings From parent return self.modified_rgbas( vmobject, vmobject.get_stroke_rgbas(background) ) - def get_fill_rgbas(self, vmobject): + def get_fill_rgbas(self, vmobject): #NOTE : DocStrings From parent return self.modified_rgbas( vmobject, vmobject.get_fill_rgbas() ) - def get_mobjects_to_display(self, *args, **kwargs): + def get_mobjects_to_display(self, *args, **kwargs): #NOTE : DocStrings From parent mobjects = Camera.get_mobjects_to_display( self, *args, **kwargs ) @@ -105,42 +121,130 @@ def z_key(mob): return sorted(mobjects, key=z_key) def get_phi(self): + """Returns the Polar angle (the angle off Z_AXIS) phi. + + Returns + ------- + float + The Polar angle in radians. + """ return self.phi_tracker.get_value() def get_theta(self): + """Returns the Azimuthal i.e the angle that spins the camera around the Z_AXIS. + + Returns + ------- + float + The Azimuthal angle in radians. + """ return self.theta_tracker.get_value() def get_distance(self): + """Returns radial distance from ORIGIN. + + Returns + ------- + float + The radial distance from ORIGIN in MUnits. + """ return self.distance_tracker.get_value() def get_gamma(self): + """Returns the rotation of the camera about the vector from the ORIGIN to the Camera. + + Returns + ------- + float + The angle of rotation of the camera about the vector + from the ORIGIN to the Camera in radians + """ return self.gamma_tracker.get_value() def get_frame_center(self): + """Returns the center of the camera frame in cartesian coordinates. + + Returns + ------- + np.array + The cartesian coordinates of the center of the camera frame. + """ return self.frame_center.points[0] def set_phi(self, value): + """Sets the polar angle i.e the angle between Z_AXIS and Camera through ORIGIN in radians. + + Parameters + ---------- + value : int, float + The new value of the polar angle in radians. + """ self.phi_tracker.set_value(value) def set_theta(self, value): + """Sets the azimuthal angle i.e the angle that spins the camera around Z_AXIS in radians. + + Parameters + ---------- + value : int, float + The new value of the azimuthal angle in radians. + """ self.theta_tracker.set_value(value) def set_distance(self, value): + """Sets the radial distance between the camera and ORIGIN. + + Parameters + ---------- + value : int, float + The new radial distance. + """ self.distance_tracker.set_value(value) def set_gamma(self, value): + """Sets the angle of rotation of the camera about the vector from the ORIGIN to the Camera. + + Parameters + ---------- + value : int, float + The new angle of rotation of the camera. + """ self.gamma_tracker.set_value(value) def set_frame_center(self, point): + """Sets the camera frame center to the passed cartesian coordinate. + + Parameters + ---------- + point : list, tuple, np.array + The cartesian coordinates of the new frame center. + """ self.frame_center.move_to(point) def reset_rotation_matrix(self): + """Sets the value of self.rotation_matrix to + the matrix corresponding to the current position of the camera + """ self.rotation_matrix = self.generate_rotation_matrix() def get_rotation_matrix(self): + """Returns the matrix corresponding to the current position of the camera. + + Returns + ------- + np.array + The matrix corresponding to the current position of the camera. + """ return self.rotation_matrix def generate_rotation_matrix(self): + """Generates a rotation matrix based off the current position of the camera. + + Returns + ------- + np.array + The matrix corresponding to the current position of the camera. + """ phi = self.get_phi() theta = self.get_theta() gamma = self.get_gamma() @@ -155,6 +259,19 @@ def generate_rotation_matrix(self): return result def project_points(self, points): + """Applies the current rotation_matrix as a projection + matrix to the passed array of points. + + Parameters + ---------- + points : np.array, list + The list of points to project. + + Returns + ------- + np.array + The points after projecting. + """ frame_center = self.get_frame_center() distance = self.get_distance() rot_matrix = self.get_rotation_matrix() @@ -180,9 +297,22 @@ def project_points(self, points): return points def project_point(self, point): + """Applies the current rotation_matrix as a projection + matrix to the passed point. + + Parameters + ---------- + point : list, np.array + The point to project. + + Returns + ------- + np.array + The point after projection. + """ return self.project_points(point.reshape((1, 3)))[0, :] - def transform_points_pre_display(self, mobject, points): + def transform_points_pre_display(self, mobject, points): #TODO: Write Docstrings for this Method. points = super().transform_points_pre_display(mobject, points) fixed_orientation = mobject in self.fixed_orientation_mobjects fixed_in_frame = mobject in self.fixed_in_frame_mobjects @@ -201,6 +331,23 @@ def add_fixed_orientation_mobjects( self, *mobjects, use_static_center_func=False, center_func=None): + """This method allows the mobject to have a fixed orientation, + even when the camera moves around. + E.G If it was passed through this method, facing the camera, it + will continue to face the camera even as the camera moves. + Highly useful when adding labels to graphs and the like. + + Parameters + ---------- + *mobjects : Mobject + The mobject whose orientation must be fixed. + use_static_center_func : bool, optional + Whether or not to use the function that takes the mobject's + center as centerpoint, by default False + center_func : func, optional + The function which returns the centerpoint + with respect to which the mobjec will be oriented, by default None + """ # This prevents the computation of mobject.get_center # every single time a projetion happens def get_static_center_func(mobject): @@ -218,15 +365,45 @@ def get_static_center_func(mobject): self.fixed_orientation_mobjects[submob] = func def add_fixed_in_frame_mobjects(self, *mobjects): + """This method allows the mobject to have a fixed position, + even when the camera moves around. + E.G If it was passed through this method, at the top of the frame, it + will continue to be displayed at the top of the frame. + + Highly useful when displaying Titles or formulae or the like. + + Parameters + ---------- + **mobjects : Mobject + The mobject to fix in frame. + """ for mobject in self.extract_mobject_family_members(mobjects): self.fixed_in_frame_mobjects.add(mobject) def remove_fixed_orientation_mobjects(self, *mobjects): + """If a mobject was fixed in its orientation by passing it through + `self.add_fixed_orientation_mobjects`, then this undoes that fixing. + The Mobject will no longer have a fixed orientation. + + Parameters: + ----------- + *mobjects : Mobject + The mobjects whose orientation need not be fixed any longer. + """ for mobject in self.extract_mobject_family_members(mobjects): if mobject in self.fixed_orientation_mobjects: self.fixed_orientation_mobjects.remove(mobject) def remove_fixed_in_frame_mobjects(self, *mobjects): + """If a mobject was fixed in frame by passing it through + `self.add_fixed_in_frame_mobjects`, then this undoes that fixing. + The Mobject will no longer be fixed in frame. + + Parameters: + ----------- + *mobjects : Mobject + The mobjects which need not be fixed in frame any longer. + """ for mobject in self.extract_mobject_family_members(mobjects): if mobject in self.fixed_in_frame_mobjects: self.fixed_in_frame_mobjects.remove(mobject) diff --git a/manimlib/scene/graph_scene.py b/manimlib/scene/graph_scene.py index 03550e3902..77dd66bbd0 100644 --- a/manimlib/scene/graph_scene.py +++ b/manimlib/scene/graph_scene.py @@ -71,7 +71,7 @@ def setup_axes(self, animate=False): Parameters ---------- - animate (bool=False) + animate : bool, optional Whether or not to animate the setting up of the Axes. """ # TODO, once eoc is done, refactor this to be less redundant. @@ -156,12 +156,12 @@ def coords_to_point(self, x, y): Parameters ---------- - x : (int,float) + x : int, float The x value - y : (int,float) + y : int, float The y value - + Returns ------- np.ndarray @@ -184,9 +184,9 @@ def point_to_coords(self, point): Parameters ---------- - point (np.ndarray) + point : np.ndarray The point on the graph. - + Returns ------- tuple @@ -210,17 +210,17 @@ def get_graph( func : function The function to plot. It's return value should be the y-coordinate for a given x-coordinate - - color : str + + color : str, optional The string of the RGB color of the curve. in Hexadecimal representation. - - x_min : (Union[int,float]) + + x_min : int, float, optional The lower x_value from which to plot the curve. - - x_max : (Union[int,float]) + + x_max : int, float, optional The higher x_value until which to plot the curve. - - **kwargs: + + **kwargs : Any valid keyword arguments of ParametricFunction. Return @@ -259,13 +259,13 @@ def input_to_graph_point(self, x, graph): Parameters ---------- - x (Union[int, float]) + x : int, float The x value for which to find the y value. - - graph ParametricFunction + + graph : ParametricFunction The ParametricFunction object on which the x and y value lie. - + Returns ------- numpy.nparray @@ -280,16 +280,16 @@ def angle_of_tangent(self, x, graph, dx=0.01): Parameters ---------- - x (Union[int, float]) + x : int, float The x value at which the tangent must touch the curve. - - graph ParametricFunction + + graph : ParametricFunction The ParametricFunction for which to calculate the tangent. - - dx (Union(float, int =0.01)) + + dx : int, float, optional The small change in x with which a small change in y will be compared in order to obtain the tangent. - + Returns ------- float @@ -301,21 +301,21 @@ def angle_of_tangent(self, x, graph, dx=0.01): def slope_of_tangent(self, *args, **kwargs): """ - Returns the slople of the tangent to the plotted curve + Returns the slople of the tangent to the plotted curve at a particular x-value. Parameters ---------- - x (Union[int, float]) + x : int, float The x value at which the tangent must touch the curve. - - graph ParametricFunction + + graph : ParametricFunction The ParametricFunction for which to calculate the tangent. - - dx (Union(float, int =0.01)) + + dx : int, float, optional The small change in x with which a small change in y will be compared in order to obtain the tangent. - + Returns ------- float @@ -330,19 +330,19 @@ def get_derivative_graph(self, graph, dx=0.01, **kwargs): Parameters ---------- - graph (ParametricFunction) + graph : ParametricFunction The graph for which the derivative must be found. - - dx (Union(float, int =0.01)) + + dx : float, int, optional The small change in x with which a small change in y will be compared in order to obtain the derivative. - + **kwargs Any valid keyword argument of ParametricFunction - + Returns ------- - ParametricFuncion + ParametricFunction The curve of the derivative. """ if "color" not in kwargs: @@ -370,22 +370,22 @@ def get_graph_label( graph : ParametricFunction The curve of the function plotted. - label : str = "f(x)" + label : str, optional The label for the function's curve. - x_val : Union[float, int] + x_val : int, float, optional The x_value with which the label should be aligned. - direction : Union[np.ndarray,list,tuple]=RIGHT - The position, relative to the curve that the label will be at. + direction : np.ndarray, list, tuple + The cartesian position, relative to the curve that the label will be at. e.g LEFT, RIGHT - buff : Union[float, int] + buff : float, int, option The buffer space between the curve and the label - color : str + color : str, optional The color of the label. - + Returns ------- TexMobject @@ -431,49 +431,49 @@ def get_riemann_rectangles( Parameters ---------- - graph (ParametricFunction) + graph : ParametricFunction The graph whose area needs to be approximated by the Riemann Rectangles. - - x_min Union[int,float] + + x_min : int, float, optional The lower bound from which to start adding rectangles - - x_max Union[int,float] + + x_max : int, float, optional The upper bound where the rectangles stop. - - dx Union[int,float] - The smallest change in x-values that is + + dx : int, float, optional + The smallest change in x-values that is considered significant. - - input_sample_type str + + input_sample_type : {"left", "right", "center"} Can be any of "left", "right" or "center - - stroke_width : Union[int, float] + + stroke_width : int, float, optional The stroke_width of the border of the rectangles. - - stroke_color : str + + stroke_color : str, optional The string of hex colour of the rectangle's border. - fill_opacity Union[int, float] - The opacity of the rectangles. + fill_opacity : int, float + The opacity of the rectangles. Takes values from 0 to 1. - start_color : str, + start_color : str, optional The hex starting colour for the rectangles, this will, if end_color is a different colour, make a nice gradient. - - end_color : str, + + end_color : str, optional The hex ending colour for the rectangles, this will, if start_color is a different colour, make a nice gradient. - - show_signed_area : bool (True) + + show_signed_area : bool, optional Whether or not to indicate -ve area if curve dips below x-axis. - - width_scale_factor : Union[int, float] + + width_scale_factor : int, float, optional How much the width of the rectangles are scaled by when transforming. - + Returns ------- VGroup @@ -533,24 +533,25 @@ def get_riemann_rectangles_list( Parameters ---------- - graph (ParametricFunction) + graph : ParametricFunction The graph whose area needs to be approximated by the Riemann Rectangles. - - n_iterations, + + n_iterations : int, The number of VGroups of successive accuracy that are needed. - - max_dx Union[int,float] + + max_dx : int, float, optional The maximum change in x between two VGroups of Riemann Rectangles - - power_base Union[int,float=2] - - stroke_width : Union[int, float] + + power_base : int, float, optional + Defaults to 2 + + stroke_width : int, float, optional The stroke_width of the border of the rectangles. - + **kwargs Any valid keyword arguments of get_riemann_rectangles. - + Returns ------- list @@ -571,18 +572,18 @@ def get_area(self, graph, t_min, t_max): Returns a VGroup of Riemann rectangles sufficiently small enough to visually approximate the area under the graph passed. - + Parameters ---------- - graph (ParametricFunction) + graph : ParametricFunction The graph/curve for which the area needs to be gotten. - - t_min Union[int, float] + + t_min : int, float The lower bound of x from which to approximate the area. - - t_max Union[int, float] + + t_max : int, float The upper bound of x until which the area must be approximated. - + Returns ------- VGroup @@ -608,10 +609,10 @@ def transform_between_riemann_rects(self, curr_rects, new_rects, **kwargs): ---------- curr_rects : VGroup The current Riemann Rectangles - + new_rects : VGroup The Riemann Rectangles to transform to. - + **kwargs added_anims Any other animations to play simultaneously. @@ -642,25 +643,25 @@ def get_vertical_line_to_graph( **line_kwargs ): """ - This method returns a Vertical line from the x-axis to + This method returns a Vertical line from the x-axis to the corresponding point on the graph/curve. Parameters ---------- - x Union[int,float] + x : int, float The x-value at which the line should be placed/calculated. - graph (ParametricFunction) + graph : ParametricFunction The graph on which the line should extend to. - - line_class (Line and similar) + + line_class : Line and similar The type of line that should be used. - Defaults to Line - + Defaults to Line. + **line_kwargs Any valid keyword arguments of the object passed in "line_class" If line_class is Line, any valid keyword arguments of Line are allowed. - + Return ------ An object of type passed in "line_class" @@ -683,27 +684,27 @@ def get_vertical_lines_to_graph( ): """ Obtains multiple lines from the x axis to the Graph/curve. - + Parameters ---------- - graph (ParametricFunction) + graph : ParametricFunction The graph on which the line should extend to. - - x_min (Union[int, float]) + + x_min : int, float, optional The lower bound from which lines can appear. - - x_max (Union[int, float]) + + x_max : int, float, optional The upper bound until which the lines can appear. - - num_lines (Union[int, float]) + + num_lines : int, optional The number of lines (evenly spaced) that are needed. - + Returns ------- VGroup The VGroup of the evenly spaced lines. - + """ x_min = x_min or self.x_min x_max = x_max or self.x_max @@ -725,46 +726,46 @@ def get_secant_slope_group( secant_line_length=10, ): """ - This method returns a VGroup of (two lines - representing dx and df, the labels for dx and - df, and the Secant to the Graph/curve at a + This method returns a VGroup of (two lines + representing dx and df, the labels for dx and + df, and the Secant to the Graph/curve at a particular x value. Parameters ---------- - x (Union[float, int]) + x : int, float The x value at which the secant enters, and intersects the graph for the first time. - - graph (ParametricFunction) + + graph : ParametricFunction The curve/graph for which the secant must be found. - - dx (Union[float, int]) + + dx : int, float, optional The change in x after which the secant exits. - - dx_line_color (str) + + dx_line_color : str, optional The line color for the line that indicates the change in x. - - df_line_color (str) + + df_line_color : str, optional The line color for the line that indicates the change in y. - - dx_label (str) + + dx_label : str, optional The label to be provided for the change in x. - - df_label (str) + + df_label : str, optional The label to be provided for the change in y. - - include_secant_line (bool=True) + + include_secant_line : bool, optional Whether or not to include the secant line in the graph, or just have the df and dx lines and labels. - - secant_line_color (str) + + secant_line_color : str, optional The color of the secant line. - - secant_line_length (Union[float,int=10]) + + secant_line_length : int, float, optional How long the secant line should be. - + Returns: -------- VGroup @@ -854,21 +855,21 @@ def add_T_label(self, x_val, side=RIGHT, label=None, color=WHITE, animated=False Parameters ---------- - x_val (Union[float, int]) + x_val : float, int The x value at which the secant enters, and intersects the graph for the first time. - - side (np.ndarray()) - - label (str) + + side np.array(), optional + + label : str, optional The label to give the vertline and triangle - - color (str) + + color : str, optional The hex color of the label. - - animated (bool=False) + + animated : bool, optional Whether or not to animate the addition of the T_label - + **kwargs Any valid keyword argument of a self.play call. """ @@ -919,25 +920,25 @@ def get_animation_integral_bounds_change( self.left_v_line and self.right_v_line must be defined from self.get_v_line self.left_T_label_group and self.right_T_label_group must be defined from self.add_T_label - This method will returna VGroup of new mobjects for each of those, when provided the graph/curve, + This method will return a VGroup of new mobjects for each of those, when provided the graph/curve, the new t_min and t_max, the run_time and a bool stating whether or not to fade when close to the origin. Parameters ---------- - graph (ParametricFunction) + graph : ParametricFunction The graph for which this must be done. - - new_t_min (Union[int,float]) + + new_t_min : int, float The new lower bound. - - new_t_max (Union[int,float]) + + new_t_max : int, float The new upper bound. - - fade_close_to_origin (bool=True) + + fade_close_to_origin : bool, optional Whether or not to fade when close to the origin. - - run_time (Union[int,float=1.0]) + + run_time : int, float, optional The run_time of the animation of this change. """ curr_t_min = self.x_axis.point_to_number(self.area.get_left()) @@ -999,21 +1000,21 @@ def animate_secant_slope_group_change( Parameters ---------- - secant_slope_group (VGroup) + secant_slope_group : VGroup The old secant_slope_group - - target_dx Union[int, float] + + target_dx : int, float, optional The new dx value. - - target_x Union[int, float] + + target_x : int, float, optional The new x value at which the secant should be. - - run_time Union[int,float=3] + + run_time : int, float, optional The run time for this change when animated. - - added_anims + + added_anims : list, optional Any exta animations that should be played alongside. - + **anim_kwargs Any valid kwargs of a self.play call. diff --git a/manimlib/scene/moving_camera_scene.py b/manimlib/scene/moving_camera_scene.py index 3d419e198f..5941ee85be 100644 --- a/manimlib/scene/moving_camera_scene.py +++ b/manimlib/scene/moving_camera_scene.py @@ -31,8 +31,8 @@ def get_moving_mobjects(self, *animations): Parameters ---------- - *animations (Animation) - The animations whose mobjects will be checked. + *animations : Animation + The Animations whose mobjects will be checked. """ moving_mobjects = Scene.get_moving_mobjects(self, *animations) all_moving_mobjects = self.camera.extract_mobject_family_members( diff --git a/manimlib/scene/scene.py b/manimlib/scene/scene.py index dc4f1d1eb8..69ba27a049 100644 --- a/manimlib/scene/scene.py +++ b/manimlib/scene/scene.py @@ -23,9 +23,9 @@ class Scene(Container): other named scenes. Use a construct() function to tell Manim what should go on in the Scene. - + E.G: - + class MyScene(Scene): def construct(self): self.play( @@ -130,12 +130,12 @@ def set_variables_as_attrs(self, *objects, **newly_named_objects): def get_attrs(self, *keys): """ Gets attributes of a scene given the attribute's identifier/name. - + Parameters ---------- - *args: (str) + *keys : str Name(s) of the argument(s) to return the attribute of. - + Returns ------- list @@ -147,28 +147,30 @@ def get_attrs(self, *keys): def set_camera(self, camera): """ Sets the scene's camera to be the passed Camera Object. + Parameters ---------- - camera: Union[Camera, MappingCamera,MovingCamera,MultiCamera,ThreeDCamera] - Camera object to use. + camera : Camera + The camera object to use. """ self.camera = camera def get_frame(self): """ - Gets current frame as NumPy array. - + Gets the current frame as NumPy array. + Returns ------- np.array - NumPy array of pixel values of each pixel in screen + NumPy array of pixel values of each pixel in screen. + The shape of the array is height x width x 3 """ return np.array(self.camera.get_pixel_array()) def get_image(self): """ Gets current frame as PIL Image - + Returns ------- PIL.Image @@ -192,7 +194,7 @@ def set_camera_background(self, background): """ Sets the camera to display a Pixel Array in the background. - + Parameters ---------- background: Union[np.ndarray,list,tuple] @@ -222,15 +224,15 @@ def update_frame( #TODO Description in Docstring """ Parameters: ----------- - mobjects: list + mobjects: list, optional list of mobjects - - background: np.ndarray - Pixel Array for Background - - include_submobjects: bool (True) - - ignore_skipping : bool (True) + + background: np.ndarray, optional + Pixel Array for Background. + + include_submobjects: bool, optional + + ignore_skipping : bool, optional **kwargs @@ -259,10 +261,10 @@ def freeze_background(self): def update_mobjects(self, dt): """ Begins updating all mobjects in the Scene. - + Parameters ---------- - dt: Union[int,float] + dt: int or float Change in time between updates. Defaults (mostly) to 1/frames_per_second """ for mobject in self.mobjects: @@ -272,7 +274,7 @@ def should_update_mobjects(self): """ Returns True if any mobject in Scene is being updated or if the scene has always_update_mobjects set to true. - + Returns ------- bool @@ -287,10 +289,10 @@ def should_update_mobjects(self): def get_time(self): """ Returns time in seconds elapsed after initialisation of scene - + Returns ------- - self.time : Union[int,float] + self.time : float Returns time in seconds elapsed after initialisation of scene """ return self.time @@ -299,10 +301,10 @@ def increment_time(self, d_time): """ Increments the time elapsed after intialisation of scene by passed "d_time". - + Parameters ---------- - d_time : Union[int,float] + d_time : int or float Time in seconds to increment by. """ self.time += d_time @@ -352,9 +354,9 @@ def add(self, *mobjects): Parameters --------- - *mobjects + *mobjects : Mobject Mobjects to add. - + Returns ------- Scene @@ -383,6 +385,11 @@ def remove(self, *mobjects): Removes mobjects in the passed list of mobjects from the scene and the foreground, by removing them from "mobjects" and "foreground_mobjects" + + Parameters + ---------- + *mobjects : Mobject + The mobjects to remove. """ for list_name in "mobjects", "foreground_mobjects": self.restructure_mobjects(mobjects, list_name, False) @@ -394,9 +401,9 @@ def restructure_mobjects(self, to_remove, """ tl:wr If your scene has a Group(), and you removed a mobject from the Group, - this dissolves the group and puts the rest of the mobjects directly + this dissolves the group and puts the rest of the mobjects directly in self.mobjects or self.foreground_mobjects. - + In cases where the scene contains a group, e.g. Group(m1, m2, m3), but one of its submobjects is removed, e.g. scene.remove(m1), the list of mobjects will be edited to contain other submobjects, but not m1, e.g. it will now @@ -406,13 +413,13 @@ def restructure_mobjects(self, to_remove, ---------- to_remove : Mobject The Mobject to remove. - - mobject_list_name : str + + mobject_list_name : str, optional The list of mobjects ("mobjects", "foreground_mobjects" etc) to remove from. - - extract_families : bool + + extract_families : bool, optional Whether the mobject's families should be recursively extracted. - + Returns ------- Scene @@ -429,22 +436,22 @@ def get_restructured_mobject_list(self, mobjects, to_remove): """ Given a list of mobjects and a list of mobjects to be removed, this filters out the removable mobjects from the list of mobjects. - + Parameters ---------- mobjects : list The Mobjects to check. - + to_remove : list The list of mobjects to remove. - + Returns ------- list The list of mobjects with the mobjects to remove removed. """ - + new_mobjects = [] def add_safe_mobjects_from_list(list_to_examine, set_to_remove): @@ -462,14 +469,14 @@ def add_safe_mobjects_from_list(list_to_examine, set_to_remove): # TODO, remove this, and calls to this def add_foreground_mobjects(self, *mobjects): """ - Adds mobjects to the foreground, and internally to the list + Adds mobjects to the foreground, and internally to the list foreground_mobjects, and mobjects. Parameters ---------- *mobjects : Mobject The Mobjects to add to the foreground. - + Returns ------ Scene @@ -484,14 +491,14 @@ def add_foreground_mobjects(self, *mobjects): def add_foreground_mobject(self, mobject): """ - Adds a single mobject to the foreground, and internally to the list + Adds a single mobject to the foreground, and internally to the list foreground_mobjects, and mobjects. Parameters ---------- mobject : Mobject The Mobject to add to the foreground. - + Returns ------ Scene @@ -501,14 +508,14 @@ def add_foreground_mobject(self, mobject): def remove_foreground_mobjects(self, *to_remove): """ - Removes mobjects from the foreground, and internally from the list + Removes mobjects from the foreground, and internally from the list foreground_mobjects. Parameters ---------- *to_remove : Mobject The mobject(s) to remove from the foreground. - + Returns ------ Scene @@ -519,14 +526,14 @@ def remove_foreground_mobjects(self, *to_remove): def remove_foreground_mobject(self, mobject): """ - Removes a single mobject from the foreground, and internally from the list + Removes a single mobject from the foreground, and internally from the list foreground_mobjects. Parameters ---------- mobject : Mobject The mobject to remove from the foreground. - + Returns ------ Scene @@ -536,14 +543,14 @@ def remove_foreground_mobject(self, mobject): def bring_to_front(self, *mobjects): """ - Adds the passed mobjects to the scene again, + Adds the passed mobjects to the scene again, pushing them to he front of the scene. Parameters ---------- *mobjects : Mobject The mobject(s) to bring to the front of the scene. - + Returns ------ Scene @@ -562,7 +569,7 @@ def bring_to_back(self, *mobjects): ---------- *mobjects : Mobject The mobject(s) to push to the back of the scene. - + Returns ------ Scene @@ -581,7 +588,7 @@ def clear(self): Returns ------ Scene - The Scene, with all of its mobjects in + The Scene, with all of its mobjects in self.mobjects and self.foreground_mobjects removed. """ @@ -616,10 +623,10 @@ def get_mobject_copies(self): def get_moving_mobjects(self, *animations): """ Gets all moving mobjects in the passed animation(s). - + Parameters ---------- - *animations + *animations : Animation The animations to check for moving mobjects. Returns @@ -650,20 +657,20 @@ def get_time_progression(self, run_time, n_iterations=None, override_skip_animat This method is for Manim's internal use. Returns a CommandLine ProgressBar whose fill_time - is dependent on the run_time of an animation, + is dependent on the run_time of an animation, the iterations to perform in that animation and a bool saying whether or not to consider the skipped animations. Parameters ---------- - run_time: Union[int,float] + run_time: float The run_time of the animation. - - n_iterations: None, int + + n_iterations: int, optional The number of iterations in the animation. - - override_skip_animations: bool (True) + + override_skip_animations: bool, optional Whether or not to show skipped animations in the progress bar. Returns @@ -689,10 +696,10 @@ def get_run_time(self, animations): Parameters ---------- - animations: list - A list of the animations whose total + animations: list of Animation + A list of the animations whose total run_time is to be calculated. - + Returns ------ float @@ -708,11 +715,11 @@ def get_animation_time_progression(self, animations): Uses get_time_progression to obtaina CommandLine ProgressBar whose fill_time is - dependent on the qualities of the passed animation, + dependent on the qualities of the passed Animation, Parameters ---------- - animations : list + animations : list of Animation The list of animations to get the time progression for. @@ -740,10 +747,11 @@ def compile_play_args_to_animation_list(self, *args, **kwargs): s hit, a MoveToTarget animation is built using the args that follow up until either another animation is hit, another method is hit, or the args list runs out. - + Parameters ---------- - *args : Union[Animation, method(of a mobject, which is followed by that method's arguments)] + *args : Animation or method of a mobject, which is followed by that method's arguments + **kwargs : any named arguments like run_time or lag_ratio. Returns @@ -811,10 +819,10 @@ def update_skipping_status(self): This method is used internally to check if the current animation needs to be skipped or not. It also checks if the number of animations that were played correspond to - the number of animations that need to be played, and + the number of animations that need to be played, and raises an EndSceneEarlyException if they don't correspond. """ - + if self.start_at_animation_number: if self.num_plays == self.start_at_animation_number: self.skip_animations = False @@ -828,18 +836,18 @@ def handle_play_like_call(func): This method is used internally to wrap the passed function, into a function that actually writes to the video stream. - Simultaneously, it also adds to the number + Simultaneously, it also adds to the number of animations played. Parameters ---------- - func: function object + func : function The play() like function that has to be written to the video file stream. Returns ------- - function object + function The play() like function that can now write to the video file stream. """ @@ -860,7 +868,7 @@ def begin_animations(self, animations): Parameters ---------- - animations: list + animations : list List of involved animations. """ @@ -882,7 +890,7 @@ def progress_through_animations(self, animations): Parameters ---------- - animations: list + animations : list List of involved animations. """ # Paint all non-moving objects onto the screen, so they don't @@ -909,7 +917,7 @@ def finish_animations(self, animations): Parameters ---------- - animations: list + animations : list list of animations to finish. """ for animation in animations: @@ -933,8 +941,8 @@ def play(self, *args, **kwargs): Parameters ---------- - *args: Animation, mobject with mobject method and params - **kwargs: named parameters affecting what was passed in *args e.g run_time, lag_ratio etc. + *args : Animation or mobject with mobject method and params + **kwargs : named parameters affecting what was passed in *args e.g run_time, lag_ratio etc. """ if len(args) == 0: warnings.warn("Called Scene.play with no animations") @@ -948,9 +956,9 @@ def play(self, *args, **kwargs): def idle_stream(self): """ - This method is used internally to - idle the vide file_writer until an - animation etc needs to be written + This method is used internally to + idle the video file_writer until an + animation etc needs to be written to the video file. """ self.file_writer.idle_stream() @@ -962,7 +970,7 @@ def clean_up_animations(self, *animations): Parameters ---------- - *animations: Animation + *animations : Animation Animation to clean up. Returns @@ -999,12 +1007,12 @@ def get_wait_time_progression(self, duration, stop_condition): Parameters ---------- - duration: Union[list,float] + duration: int or float duration of wait time - - stop_condition: function + + stop_condition : function The function which determines whether to continue waiting. - + Returns ------- ProgressBar @@ -1036,11 +1044,11 @@ def wait(self, duration=DEFAULT_WAIT_TIME, stop_condition=None): Parameters ---------- - duration : Union[float, int] - The duration of wait time. Defaults to None. - stop_condition : + duration : float or int, optional + The duration of wait time. + stop_condition : A function that determines whether to stop waiting or not. - + Returns ------- Scene @@ -1077,15 +1085,14 @@ def wait_until(self, stop_condition, max_time=60): Like a wrapper for wait(). You pass a function that determines whether to continue waiting, and a max wait time if that is never fulfilled. - + Parameters ---------- - stop_condition: function definition + stop_condition : function The function whose boolean return value determines whether to continue waiting - - max_time: Union[int,float] + + max_time : int or float, optional The maximum wait time in seconds, if the stop_condition is never fulfilled. - Defaults to 60. """ self.wait(max_time, stop_condition=stop_condition) @@ -1108,7 +1115,7 @@ def force_skipping(self): def revert_to_original_skipping_status(self): """ Forces the scene to go back to its original skipping status, - by setting skip_animations to whatever it reads + by setting skip_animations to whatever it reads from original_skipping_status. Returns @@ -1142,15 +1149,14 @@ def add_sound(self, sound_file, time_offset=0, gain=None, **kwargs): Parameters ---------- - sound_file: str + sound_file : str The path to the sound file. - - time_offset: int,float = 0 + + time_offset : int,float, optional The offset in the sound file after which the sound can be played. - gain: - - **kwargs : Present for excess? + + gain : """ if self.skip_animations: diff --git a/manimlib/scene/scene_file_writer.py b/manimlib/scene/scene_file_writer.py index 298339748c..2b0182b7e7 100644 --- a/manimlib/scene/scene_file_writer.py +++ b/manimlib/scene/scene_file_writer.py @@ -238,12 +238,14 @@ def add_audio_segment(self, new_segment, Parameters ---------- - new_segment (AudioSegment) + new_segment : AudioSegment The audio segment to add - time (Union[int, float]) + + time : int, float, optional the timestamp at which the sound should be added. - gain_to_background + + gain_to_background : optional The gain of the segment from the background. """ if not self.includes_sound: @@ -275,13 +277,13 @@ def add_sound(self, sound_file, time=None, gain=None, **kwargs): Parameters ---------- - sound_file (str) + sound_file : str The path to the sound file. - time (Union[float, int]) + time : float or int, optional The timestamp at which the audio should be added. - gain + gain : optional The gain of the given audio segment. **kwargs @@ -303,7 +305,7 @@ def begin_animation(self, allow_write=False): Parameters ---------- - allow_write (bool=False) + allow_write : bool, optional Whether or not to write to a video file. """ if self.write_to_movie and allow_write: @@ -316,7 +318,7 @@ def end_animation(self, allow_write=False): Parameters ---------- - allow_write (bool=False) + allow_write : bool, optional Whether or not to write to a video file. """ if self.write_to_movie and allow_write: @@ -329,7 +331,7 @@ def write_frame(self, frame): Parameters ---------- - frame (np.ndarray) + frame : np.array Pixel array of the frame. """ if self.write_to_movie: @@ -342,7 +344,7 @@ def save_final_image(self, image): Parameters ---------- - image (np.ndarray) + image : np.array The pixel array of the image to save. """ file_path = self.get_image_file_path() diff --git a/manimlib/scene/three_d_scene.py b/manimlib/scene/three_d_scene.py index 74d67a72a1..6728462679 100644 --- a/manimlib/scene/three_d_scene.py +++ b/manimlib/scene/three_d_scene.py @@ -32,16 +32,16 @@ def set_camera_orientation(self, phi=None, theta=None, distance=None, gamma=None Parameters ---------- - phi : (int,float) + phi : int or float, optional The polar angle i.e the angle between Z_AXIS and Camera through ORIGIN in radians. - - theta : (int,float) + + theta : int or float, optional The azimuthal angle i.e the angle that spins the camera around the Z_AXIS. - - distance : (int, float) + + distance : int or float, optional The radial distance between ORIGIN and Camera. - - gamma : (int, float) + + gamma : int or float, optional The rotation of the camera about the vector from the ORIGIN to the Camera. """ if phi is not None: @@ -60,7 +60,7 @@ def begin_ambient_camera_rotation(self, rate=0.02): Parameters ---------- - rate : (int,float=0.02) + rate : int or float, optional The rate at which the camera should rotate about the Z_AXIS. Negative rate means clockwise rotation. """ @@ -92,24 +92,24 @@ def move_camera(self, Parameters ---------- - phi : (int,float) + phi : int or float, optional The polar angle i.e the angle between Z_AXIS and Camera through ORIGIN in radians. - - theta : (int,float) + + theta : int or float, optional The azimuthal angle i.e the angle that spins the camera around the Z_AXIS. - - distance : (int, float) + + distance : int or float, optional The radial distance between ORIGIN and Camera. - - gamma : (int, float) + + gamma : int or float, optional The rotation of the camera about the vector from the ORIGIN to the Camera. - - frame_center : Union[list,tuple,array] - The new center of the camera frame. - added_anims : list - Any other animations to be played at the same time? - + frame_center : list, tuple or np.array, optional + The new center of the camera frame in cartesian coordinates + + added_anims : list, optional + Any other animations to be played at the same time. + """ anims = [] value_tracker_pairs = [ @@ -138,7 +138,7 @@ def get_moving_mobjects(self, *animations): Parameters ---------- - *animations (Animation) + *animations : Animation The animations whose mobjects will be checked. """ moving_mobjects = Scene.get_moving_mobjects(self, *animations) @@ -151,19 +151,19 @@ def add_fixed_orientation_mobjects(self, *mobjects, **kwargs): """ This method is used to prevent the rotation and tilting of mobjects as the camera moves around. The mobject can - still move in the x,y,z directions, but will always be - at the angle (relative to the camera) that it was at + still move in the x,y,z directions, but will always be + at the angle (relative to the camera) that it was at when it was passed through this method.) Parameters ---------- - *mobjects (Mobjects) - The Mobjects whose orientation must be fixed. - + *mobjects : Mobject + The Mobject(s) whose orientation must be fixed. + **kwargs - Some valid kwargs are - use_static_center_func (bool) - center_func (function) + Some valid kwargs are + use_static_center_func : bool + center_func : function """ self.add(*mobjects) self.camera.add_fixed_orientation_mobjects(*mobjects, **kwargs) @@ -177,7 +177,7 @@ def add_fixed_in_frame_mobjects(self, *mobjects): Parameters ---------- - *mobjects (Mobjects) + *mobjects : Mobjects The Mobjects whose orientation must be fixed. """ self.add(*mobjects) @@ -192,7 +192,7 @@ def remove_fixed_orientation_mobjects(self, *mobjects): Parameters ---------- - *mobjects (Mobjects) + *mobjects : Mobjects The Mobjects whose orientation must be unfixed. """ self.camera.remove_fixed_orientation_mobjects(*mobjects) @@ -205,7 +205,7 @@ def remove_fixed_in_frame_mobjects(self, *mobjects): Parameters ---------- - *mobjects (Mobjects) + *mobjects : Mobjects The Mobjects whose position and orientation must be unfixed. """ self.camera.remove_fixed_in_frame_mobjects(*mobjects) @@ -219,7 +219,7 @@ def set_to_default_angled_camera_orientation(self, **kwargs): Parameters ---------- **kwargs - Some recognised kwargs are phi, theta, distance, gamma, + Some recognised kwargs are phi, theta, distance, gamma, which have the same meaning as the parameters in set_camera_orientation. """ config = dict(self.default_camera_orientation_kwargs) @@ -291,7 +291,7 @@ def get_axes(self): Returns ------- - ThreeDAxes object + ThreeDAxes """ axes = ThreeDAxes(**self.three_d_axes_config) for axis in axes: @@ -323,7 +323,7 @@ def get_sphere(self, **kwargs): **kwargs Some valid kwargs are: Any param of a Sphere or ParametricSurface. - + Returns ------- Sphere diff --git a/manimlib/scene/vector_space_scene.py b/manimlib/scene/vector_space_scene.py index 825cf758de..1e6b04ddbb 100644 --- a/manimlib/scene/vector_space_scene.py +++ b/manimlib/scene/vector_space_scene.py @@ -52,11 +52,11 @@ def add_plane(self, animate=False, **kwargs): Parameters ---------- - animate : (bool=False) + animate : bool, optional Whether or not to animate the addition of the plane via ShowCreation. **kwargs Any valid keyword arguments accepted by NumberPlane. - + Returns ------- NumberPlane @@ -74,9 +74,9 @@ def add_axes(self, animate=False, color=WHITE, **kwargs): Parameters ---------- - animate (bool=False) + animate : bool, optional Whether or not to animate the addition of the axes through ShowCreation. - color (str) + color : bool, optional The color of the axes. Defaults to WHITE. """ axes = Axes(color=color, tick_frequency=1) @@ -89,13 +89,13 @@ def lock_in_faded_grid(self, dimness=0.7, axes_dimness=0.5): """ This method freezes the NumberPlane and Axes that were already in the background, and adds new, manipulatable ones to the foreground. - + Parameters ---------- - dimness (Union[int,float=0.7]) + dimness : int, float, optional The required dimness of the NumberPlane - - axes_dimness (Union[int,float=0.5]) + + axes_dimness : int, float, optional The required dimness of the Axes. """ plane = self.add_plane() @@ -109,14 +109,14 @@ def lock_in_faded_grid(self, dimness=0.7, axes_dimness=0.5): def get_vector(self, numerical_vector, **kwargs): """ Returns an arrow on the Plane given an input numerical vector. - + Parameters ---------- - numerical_vector : Union(np.ndarray, list, tuple) + numerical_vector : np.array, list, tuple The Vector to plot. **kwargs Any valid keyword argument of Arrow. - + Returns ------- Arrow @@ -135,24 +135,24 @@ def add_vector(self, vector, color=YELLOW, animate=True, **kwargs): Parameters ---------- - vector Union(Arrow,list,tuple,np.ndarray) + vector : Arrow, list, tuple, np.array It can be a pre-made graphical vector, or the coordinates of one. - - color (str) + + color : str The string of the hex color of the vector. This is only taken into consideration if 'vector' is not an Arrow. Defaults to YELLOW. - - animate (bool=True) + + animate : bool Whether or not to animate the addition of the vector by using GrowArrow - + **kwargs Any valid keyword argument of Arrow. These are only considered if vector is not an Arrow. - + Returns ------- Arrow @@ -172,12 +172,12 @@ def write_vector_coordinates(self, vector, **kwargs): Parameters ---------- - vector (Arrow) + vector : Arrow The arrow representing the vector. - + **kwargs Any valid keyword arguments of matrix.vector_coordinate_label - + integer_labels (True) : Whether or not to round the coordinates to integers. n_dim (2) : The number of dimensions of the vector. @@ -198,12 +198,12 @@ def get_basis_vectors(self, i_hat_color=X_COLOR, j_hat_color=Y_COLOR): Parameters ---------- - i_hat_color (str) + i_hat_color : str The hex colour to use for the basis vector in the x direction - - j_hat_color (str) + + j_hat_color : str The hex colour to use for the basis vector in the y direction - + Returns ------- VGroup @@ -261,19 +261,21 @@ def get_vector_label(self, vector, label, Parameters ---------- - vector + vector : Vector Vector Object for which to get the label. - at_tip (bool) + + at_tip : bool Whether or not to place the label at the tip of the vector. - direction (str="left") + + direction : {"left"} If the label should be on the "left" or right of the vector. - rotate (bool=False) + rotate : bool Whether or not to rotate it to align it with the vector. - color (str) + color : str The color to give the label. label_scale_factor (Union[int,float]) How much to scale the label by. - + Returns ------- TexMobject @@ -312,15 +314,18 @@ def label_vector(self, vector, label, animate=True, **kwargs): Parameters ---------- - vector (Vector) + vector : Vector The vector for which the label must be added. - label (TexMobject,str) + + label : TexMobject, str The TexMobject/string of the label. - animate (bool=True) + + animate : bool, optional Whether or not to animate the labelling w/ Write + **kwargs Any valid keyword argument of get_vector_label - + Returns ------- TexMobject @@ -351,16 +356,16 @@ def coords_to_vector(self, vector, coords_start=2 * RIGHT + 2 * UP, clean_up=Tru Parameters ---------- - vector Union(np.ndarray, list, tuple) + vector : np.ndarray, list, tuple The vector to show. - - coords_start Union(np.ndarray,list,tuple) - The starting point of the location of - the label of the vector that shows it + + coords_start : np.ndarray,list,tuple, optional + The starting point of the location of + the label of the vector that shows it numerically. Defaults to 2 * RIGHT + 2 * UP or (2,2) - - clean_up (bool=True) + + clean_up : bool, optional Whether or not to remove whatever this method did after it's done. @@ -399,21 +404,21 @@ def coords_to_vector(self, vector, coords_start=2 * RIGHT + 2 * UP, clean_up=Tru def vector_to_coords(self, vector, integer_labels=True, clean_up=True): """ - This method displays vector as a Vector() based vector, and then shows - the corresponding lines that make up the x and y components of the vector. - Then, a column matrix (henceforth called the label) is created near the + This method displays vector as a Vector() based vector, and then shows + the corresponding lines that make up the x and y components of the vector. + Then, a column matrix (henceforth called the label) is created near the head of the Vector. Parameters ---------- - vector Union(np.ndarray, list, tuple) + vector : np.ndarray, list, tuple The vector to show. - - integer_label (bool=True) + + integer_label : bool, optional Whether or not to round the value displayed. in the vector's label to the nearest integer - - clean_up (bool=True) + + clean_up : bool, optional Whether or not to remove whatever this method did after it's done. @@ -470,13 +475,13 @@ def vector_to_coords(self, vector, integer_labels=True, clean_up=True): def show_ghost_movement(self, vector): """ This method plays an animation that partially shows the entire plane moving - in the direction of a particular vector. This is useful when you wish to + in the direction of a particular vector. This is useful when you wish to convey the idea of mentally moving the entire plane in a direction, without actually moving the plane. Parameters ---------- - vector (Union[Arrow, list, tuple, np.ndarray]) + vector : Arrow, list, tuple, np.ndarray The vector which indicates the direction of movement. """ if isinstance(vector, Arrow): @@ -580,11 +585,11 @@ def add_special_mobjects(self, mob_list, *mobs_to_add): Parameters ---------- - mob_list (list) + mob_list : list The special list to which you want to add these mobjects. - - *mobs_to_add (Mobject) + + *mobs_to_add : Mobject The mobjects to add. """ @@ -600,7 +605,7 @@ def add_background_mobject(self, *mobjects): Parameters ---------- - *mobjects (Mobject) + *mobjects : Mobject The mobjects to add to the list. """ self.add_special_mobjects(self.background_mobjects, *mobjects) @@ -613,7 +618,7 @@ def add_foreground_mobject(self, *mobjects): Parameters ---------- - *mobjects (Mobject) + *mobjects : Mobject The mobjects to add to the list """ self.add_special_mobjects(self.foreground_mobjects, *mobjects) @@ -625,7 +630,7 @@ def add_transformable_mobject(self, *mobjects): Parameters ---------- - *mobjects (Mobject) + *mobjects : Mobject The mobjects to add to the list. """ self.add_special_mobjects(self.transformable_mobjects, *mobjects) @@ -640,10 +645,10 @@ def add_moving_mobject(self, mobject, target_mobject=None): Parameters ---------- - mobject (Mobject) + mobject : Mobject The mobjects to add to the list - - target_mobject (Mobject) + + target_mobject : Mobject, optional What the moving_mobject goes to, etc. """ mobject.target = target_mobject @@ -652,6 +657,21 @@ def add_moving_mobject(self, mobject, target_mobject=None): def get_unit_square(self, color=YELLOW, opacity=0.3, stroke_width=3): """ Returns a unit square for the current NumberPlane. + + Parameters + ---------- + color : str, optional + The string of the hex color code of the color wanted. + + opacity : float, int, optional + The opacity of the square + + stroke_width : int, float, optional + The stroke_width in pixels of the border of the square + + Returns + ------- + Square """ square = self.square = Rectangle( color=color, @@ -678,7 +698,7 @@ def add_unit_square(self, animate=False, **kwargs): **kwargs Any valid keyword arguments of self.get_unit_square() - + Returns ------- Square @@ -702,18 +722,18 @@ def add_vector(self, vector, color=YELLOW, **kwargs): Parameters ---------- - vector Union(Arrow,list,tuple,np.ndarray) + vector : Arrow,list,tuple,np.ndarray It can be a pre-made graphical vector, or the coordinates of one. - - color (str) + + color : str The string of the hex color of the vector. This is only taken into consideration if 'vector' is not an Arrow. Defaults to YELLOW. - + **kwargs Any valid keyword argument of VectorScene.add_vector. - + Returns ------- Arrow @@ -733,9 +753,9 @@ def write_vector_coordinates(self, vector, **kwargs): Parameters ---------- - vector (Arrow) + vector : Arrow The arrow representing the vector. - + **kwargs Any valid keyword arguments of VectorScene.write_vector_coordinates @@ -759,12 +779,18 @@ def add_transformable_label( Parameters ---------- - vector (Vector) + vector : Vector The vector for which the label must be added. - label (TexMobject,str) + + label : TexMobject,str The TexMobject/string of the label. - new_label (TexMobject,str,None) + + transformation_name : str, TexMobject, optional + The name to give the transformation as a label. + + new_label : TexMobject,str, optional What the label should display after a Linear Transformation + **kwargs Any valid keyword argument of get_vector_label @@ -796,15 +822,15 @@ def add_title(self, title, scale_factor=1.5, animate=False): Parameters ---------- - title (str,TexMobject,TextMobject) + title : str,TexMobject,TextMobject What the title should be. - - scale_factor (int,float=1.5) + + scale_factor : int, float, optional How much the title should be scaled by. - - animate (bool=False) + + animate : bool Whether or not to animate the addition. - + Returns ------- LinearTransformationScene @@ -827,7 +853,7 @@ def get_matrix_transformation(self, matrix): Parameters ---------- - matrix (np.ndarray, list, tuple) + matrix : np.ndarray, list, tuple The matrix. """ return self.get_transposed_matrix_transformation(np.array(matrix).T) @@ -835,12 +861,12 @@ def get_matrix_transformation(self, matrix): def get_transposed_matrix_transformation(self, transposed_matrix): """ Returns a function corresponding to the linear - transformation represented by the transposed + transformation represented by the transposed matrix passed. Parameters ---------- - matrix (np.ndarray, list, tuple) + matrix : np.ndarray, list, tuple The matrix. """ transposed_matrix = np.array(transposed_matrix) @@ -854,16 +880,16 @@ def get_transposed_matrix_transformation(self, transposed_matrix): def get_piece_movement(self, pieces): """ - This method returns an animation that moves an arbitrary + This method returns an animation that moves an arbitrary mobject in "pieces" to its corresponding .target value. If self.leave_ghost_vectors is True, ghosts of the original positions/mobjects are left on screen Parameters ---------- - pieces (Union[list, tuple, np.array]) + pieces : list, tuple, np.array The pieces for which the movement must be shown. - + Returns ------- Animation @@ -884,10 +910,10 @@ def get_moving_mobject_movement(self, func): Parameters ---------- - func (function) + func : function The function that determines where the .target of the moving mobject goes. - + Returns ------- Animation @@ -909,10 +935,10 @@ def get_vector_movement(self, func): Parameters ---------- - func (function) + func : function The function that determines where the .target of the moving mobject goes. - + Returns ------- Animation @@ -949,7 +975,7 @@ def apply_matrix(self, matrix, **kwargs): Parameters ---------- - matrix (Union[np.ndarray, list, tuple]) + matrix : np.ndarray, list, tuple The matrix. **kwargs Any valid keyword argument of self.apply_transposed_matrix() @@ -961,10 +987,10 @@ def apply_inverse(self, matrix, **kwargs): This method applies the linear transformation represented by the inverse of the passed matrix to the number plane, and each vector/similar mobject on it. - + Parameters ---------- - matrix (Union[np.ndarray, list, tuple]) + matrix : np.ndarray, list, tuple The matrix whose inverse is to be applied. **kwargs Any valid keyword argument of self.apply_matrix() @@ -979,7 +1005,7 @@ def apply_transposed_matrix(self, transposed_matrix, **kwargs): Parameters ---------- - matrix (Union[np.ndarray, list, tuple]) + matrix : np.ndarray, list, tuple The matrix. **kwargs Any valid keyword argument of self.apply_function() @@ -996,12 +1022,12 @@ def apply_transposed_matrix(self, transposed_matrix, **kwargs): def apply_inverse_transpose(self, t_matrix, **kwargs): """ Applies the inverse of the transformation represented - by the given transposed matrix to the number plane and each + by the given transposed matrix to the number plane and each vector/similar mobject on it. Parameters ---------- - matrix (Union[np.ndarray, list, tuple]) + matrix : np.ndarray, list, tuple The matrix. **kwargs Any valid keyword argument of self.apply_transposed_matrix() @@ -1017,7 +1043,7 @@ def apply_nonlinear_transformation(self, function, **kwargs): Parameters ---------- - function (Function) + function : Function The function. **kwargs Any valid keyword argument of self.apply_function() @@ -1033,14 +1059,14 @@ def apply_function(self, function, added_anims=[], **kwargs): Parameters ---------- - function (Function) + function : Function The function that affects each point of each mobject in self.transformable_mobjects. - - added_anims (list) + + added_anims : list, optional Any other animations that need to be played simulataneously with this. - + **kwargs Any valid keyword argument of a self.play() call. """ diff --git a/manimlib/scene/zoomed_scene.py b/manimlib/scene/zoomed_scene.py index 44ac52badb..2fde508605 100644 --- a/manimlib/scene/zoomed_scene.py +++ b/manimlib/scene/zoomed_scene.py @@ -68,10 +68,10 @@ def activate_zooming(self, animate=False): """ This method is used to activate the zooming for the zoomed_camera. - + Parameters ---------- - animate (bool=False) + animate : bool, optional Whether or not to animate the activation of the zoomed camera. """ @@ -88,14 +88,14 @@ def activate_zooming(self, animate=False): def get_zoom_in_animation(self, run_time=2, **kwargs): """ Returns the animation of camera zooming in. - + Parameters ---------- - run_time (Union[int,float=2]) + run_time : int or float, optional The run_time of the animation of the camera zooming in. **kwargs Any valid keyword arguments of ApplyMethod() - + Returns ------- ApplyMethod @@ -115,7 +115,7 @@ def get_zoomed_display_pop_out_animation(self, **kwargs): """ This is the animation of the popping out of the mini-display that shows the content of the zoomed - camera. + camera. Returns -------