diff --git a/docs/source/_static/example_scenes/AnimatingMethods.mp4 b/docs/source/_static/example_scenes/AnimatingMethods.mp4 index e94a27fc..ce56fc11 100644 Binary files a/docs/source/_static/example_scenes/AnimatingMethods.mp4 and b/docs/source/_static/example_scenes/AnimatingMethods.mp4 differ diff --git a/docs/source/_static/example_scenes/CoordinateSystemExample.mp4 b/docs/source/_static/example_scenes/CoordinateSystemExample.mp4 new file mode 100644 index 00000000..f8f9f582 Binary files /dev/null and b/docs/source/_static/example_scenes/CoordinateSystemExample.mp4 differ diff --git a/docs/source/_static/example_scenes/GraphExample.mp4 b/docs/source/_static/example_scenes/GraphExample.mp4 new file mode 100644 index 00000000..869b788f Binary files /dev/null and b/docs/source/_static/example_scenes/GraphExample.mp4 differ diff --git a/docs/source/_static/example_scenes/InteractiveDevlopment.mp4 b/docs/source/_static/example_scenes/InteractiveDevlopment.mp4 new file mode 100644 index 00000000..e6e87be8 Binary files /dev/null and b/docs/source/_static/example_scenes/InteractiveDevlopment.mp4 differ diff --git a/docs/source/_static/example_scenes/OpeningManimExample.mp4 b/docs/source/_static/example_scenes/OpeningManimExample.mp4 index 91ba83a0..6b8a238e 100644 Binary files a/docs/source/_static/example_scenes/OpeningManimExample.mp4 and b/docs/source/_static/example_scenes/OpeningManimExample.mp4 differ diff --git a/docs/source/_static/example_scenes/SurfaceExample.mp4 b/docs/source/_static/example_scenes/SurfaceExample.mp4 index 457d19d6..7e4f35db 100644 Binary files a/docs/source/_static/example_scenes/SurfaceExample.mp4 and b/docs/source/_static/example_scenes/SurfaceExample.mp4 differ diff --git a/docs/source/_static/example_scenes/TexTransformExample.mp4 b/docs/source/_static/example_scenes/TexTransformExample.mp4 index 2dbac232..d5167ccc 100644 Binary files a/docs/source/_static/example_scenes/TexTransformExample.mp4 and b/docs/source/_static/example_scenes/TexTransformExample.mp4 differ diff --git a/docs/source/_static/example_scenes/TextExample.mp4 b/docs/source/_static/example_scenes/TextExample.mp4 index 3b5979dd..3dd48c8e 100644 Binary files a/docs/source/_static/example_scenes/TextExample.mp4 and b/docs/source/_static/example_scenes/TextExample.mp4 differ diff --git a/docs/source/_static/example_scenes/UpdatersExample.mp4 b/docs/source/_static/example_scenes/UpdatersExample.mp4 index f20c48b9..bc0e41da 100644 Binary files a/docs/source/_static/example_scenes/UpdatersExample.mp4 and b/docs/source/_static/example_scenes/UpdatersExample.mp4 differ diff --git a/docs/source/getting_started/example_scenes.rst b/docs/source/getting_started/example_scenes.rst index ce34eb32..20fb9913 100644 --- a/docs/source/getting_started/example_scenes.rst +++ b/docs/source/getting_started/example_scenes.rst @@ -5,15 +5,15 @@ After understanding the previous knowledge, we can understand more scenes. Many example scenes are given in ``example_scenes.py``, let's start with the simplest and one by one. -SquareToCircle --------------- +InteractiveDevlopment +--------------------- -.. manim-example:: SquareToCircle - :media: ../_static/example_scenes/SquareToCircle.mp4 +.. manim-example:: InteractiveDevlopment + :media: ../_static/example_scenes/InteractiveDevlopment.mp4 from manimlib.imports import * - class SquareToCircle(Scene): + class InteractiveDevlopment(Scene): def construct(self): circle = Circle() circle.set_fill(BLUE, opacity=0.5) @@ -22,11 +22,45 @@ SquareToCircle self.play(ShowCreation(square)) self.wait() + + # This opens an iPython termnial where you can keep writing + # lines as if they were part of this construct method. + # In particular, 'square', 'circle' and 'self' will all be + # part of the local namespace in that terminal. + self.embed() + + # Try copying and pasting some of the lines below into + # the interactive shell self.play(ReplacementTransform(square, circle)) self.wait() + self.play(circle.animate.stretch(4, 0)) + self.play(Rotate(circle, 90 * DEGREES)) + self.play(circle.animate.shift(2 * RIGHT, circle.scale, 0.25)) -This scene is what we wrote in :doc:`quickstart`. -No more explanation here + text = Text(""" + In general, using the interactive shell + is very helpful when developing new scenes + """) + self.play(Write(text)) + + # In the interactive shell, you can just type + # play, add, remove, clear, wait, save_state and restore, + # instead of self.play, self.add, self.remove, etc. + + # To interact with the window, type touch(). You can then + # scroll in the window, or zoom by holding down 'z' while scrolling, + # and change camera perspective by holding down 'd' while moving + # the mouse. Press 'r' to reset to the standard camera position. + # Press 'q' to stop interacting with the window and go back to + # typing new commands into the shell. + + # In principle you can customize a scene to be responsive to + # mouse and keyboard interactions + always(circle.move_to, self.mouse_point) + +This scene is similar to what we wrote in :doc:`quickstart`. +And how to interact has been written in the comments. +No more explanation here. AnimatingMethods ---------------- @@ -342,6 +376,177 @@ The new classes and usage in this scene are ``always_redraw()``, ``DecimalNumber - ``.set_y()`` means to set the ordinate of the object on the screen. - ``.add_updater()`` sets an update function for the object. For example: ``mob1.add_updater(lambda mob: mob.next_to(mob2))`` means ``mob1.next_to(mob2)`` is executed every frame. +CoordinateSystemExample +----------------------- + +.. manim-example:: CoordinateSystemExample + :media: ../_static/example_scenes/CoordinateSystemExample.mp4 + + class CoordinateSystemExample(Scene): + def construct(self): + axes = Axes( + # x-axis ranges from -1 to 10, with a default step size of 1 + x_range=(-1, 10), + # y-axis ranges from -2 to 10 with a step size of 0.5 + y_range=(-2, 2, 0.5), + # The axes will be stretched so as to match the specified + # height and width + height=6, + width=10, + # Axes is made of two NumberLine mobjects. You can specify + # their configuration with axis_config + axis_config={ + "stroke_color": GREY_A, + "stroke_width": 2, + }, + # Alternatively, you can specify configuration for just one + # of them, like this. + y_axis_config={ + "include_tip": False, + } + ) + # Keyword arguments of add_coordinate_labels can be used to + # configure the DecimalNumber mobjects which it creates and + # adds to the axes + axes.add_coordinate_labels( + font_size=20, + num_decimal_places=1, + ) + self.add(axes) + + # Axes descends from the CoordinateSystem class, meaning + # you can call call axes.coords_to_point, abbreviated to + # axes.c2p, to associate a set of coordinates with a point, + # like so: + dot = Dot(color=RED) + dot.move_to(axes.c2p(0, 0)) + self.play(FadeIn(dot, scale=0.5)) + self.play(dot.animate.move_to(axes.c2p(3, 2))) + self.wait() + self.play(dot.animate.move_to(axes.c2p(5, 0.5))) + self.wait() + + # Similarly, you can call axes.point_to_coords, or axes.p2c + # print(axes.p2c(dot.get_center())) + + # We can draw lines from the axes to better mark the coordinates + # of a given point. + # Here, the always_redraw command means that on each new frame + # the lines will be redrawn + h_line = always_redraw(lambda: axes.get_h_line(dot.get_left())) + v_line = always_redraw(lambda: axes.get_v_line(dot.get_bottom())) + + self.play( + ShowCreation(h_line), + ShowCreation(v_line), + ) + self.play(dot.animate.move_to(axes.c2p(3, -2))) + self.wait() + self.play(dot.animate.move_to(axes.c2p(1, 1))) + self.wait() + + # If we tie the dot to a particular set of coordinates, notice + # that as we move the axes around it respects the coordinate + # system defined by them. + f_always(dot.move_to, lambda: axes.c2p(1, 1)) + self.play( + axes.animate.scale(0.75), + axes.animate.to_corner(UL), + run_time=2, + ) + self.wait() + self.play(FadeOut(VGroup(axes, dot, h_line, v_line))) + + # Other coordinate systems you can play around with include + # ThreeDAxes, NumberPlane, and ComplexPlane. + + +GraphExample +------------ + +.. manim-example:: GraphExample + :media: ../_static/example_scenes/GraphExample.mp4 + + class GraphExample(Scene): + def construct(self): + axes = Axes((-3, 10), (-1, 8)) + axes.add_coordinate_labels() + + self.play(Write(axes, lag_ratio=0.01, run_time=1)) + + # Axes.get_graph will return the graph of a function + sin_graph = axes.get_graph( + lambda x: 2 * math.sin(x), + color=BLUE, + ) + # By default, it draws it so as to somewhat smoothly interpolate + # between sampled points (x, f(x)). If the graph is meant to have + # a corner, though, you can set use_smoothing to False + relu_graph = axes.get_graph( + lambda x: max(x, 0), + use_smoothing=False, + color=YELLOW, + ) + # For discontinuous functions, you can specify the point of + # discontinuity so that it does not try to draw over the gap. + step_graph = axes.get_graph( + lambda x: 2.0 if x > 3 else 1.0, + discontinuities=[3], + color=GREEN, + ) + + # Axes.get_graph_label takes in either a string or a mobject. + # If it's a string, it treats it as a LaTeX expression. By default + # it places the label next to the graph near the right side, and + # has it match the color of the graph + sin_label = axes.get_graph_label(sin_graph, "\\sin(x)") + relu_label = axes.get_graph_label(relu_graph, Text("ReLU")) + step_label = axes.get_graph_label(step_graph, Text("Step"), x=4) + + self.play( + ShowCreation(sin_graph), + FadeIn(sin_label, RIGHT), + ) + self.wait(2) + self.play( + ReplacementTransform(sin_graph, relu_graph), + FadeTransform(sin_label, relu_label), + ) + self.wait() + self.play( + ReplacementTransform(relu_graph, step_graph), + FadeTransform(relu_label, step_label), + ) + self.wait() + + parabola = axes.get_graph(lambda x: 0.25 * x**2) + parabola.set_stroke(BLUE) + self.play( + FadeOut(step_graph), + FadeOut(step_label), + ShowCreation(parabola) + ) + self.wait() + + # You can use axes.input_to_graph_point, abbreviated + # to axes.i2gp, to find a particular point on a graph + dot = Dot(color=RED) + dot.move_to(axes.i2gp(2, parabola)) + self.play(FadeIn(dot, scale=0.5)) + + # A value tracker lets us animate a parameter, usually + # with the intent of having other mobjects update based + # on the parameter + x_tracker = ValueTracker(2) + f_always( + dot.move_to, + lambda: axes.i2gp(x_tracker.get_value(), parabola) + ) + + self.play(x_tracker.animate.set_value(4), run_time=3) + self.play(x_tracker.animate.set_value(-2), run_time=3) + self.wait() + SurfaceExample -------------- diff --git a/docs/source/getting_started/whatsnew.rst b/docs/source/getting_started/whatsnew.rst new file mode 100644 index 00000000..200cd6ad --- /dev/null +++ b/docs/source/getting_started/whatsnew.rst @@ -0,0 +1,144 @@ +What's new +========== + +Usage changes of new version manim +---------------------------------- + +There are many changes in the new version of manim, and here are only the changes that +may have an impact at the code writing level. + +Some of the changes here may not have any major impact on the use, and some changes +that affect the use are not mentioned below. + +This document is for reference only, see the source code for details. + +- ``Animation`` + + - Added ``Fade`` as the parent class of ``FadeIn`` and ``FadeOut`` + - ``FadeIn`` and ``FadeOut`` can be passed in ``shift`` and ``scale`` parameters + - Deleted ``FadeInFrom, FadeInFromDown, FadeOutAndShift, FadeOutAndShiftDown, FadeInFromLarge``, these can be used ``FadeIn, FadeOut`` to achieve the same effect more easily + - Added ``FadeTransform`` to cross fade between two objects, and subclass ``FadeTransformPieces`` + - Added ``CountInFrom(decimal_mob, source_number=0)`` to count ``decimal_mob`` from ``source_number`` to the current value + - ``Rotating`` can directly pass in ``angle`` and ``axis`` without writing keywords ``angle=, axis=`` + - ``Rotate`` has become a subclass of ``Rotating``, and the distortion effect in ``Transform`` will not appear + - Removed ``MoveCar`` animation + - Added ``TransformMatchingShapes(mobject, target_mobject)`` and ``TransformMatchingTex(mobject, target_mobject)`` + +- ``Camera`` + + - Removed all camera classes except ``Camera`` (``MappingCamera``, ``MovingCamera``, ``MultiCamera``) and all functions in ``ThreeDCamera`` + - Implemented ``CameraFrame`` (as a ``Mobject``) + + - Can be called by ``self.camera.frame`` in ``Scene`` + - All methods of ``Mobject`` can be used, such as ``.shift()``, ``.scale()``, etc. + - Call ``.to_default_state()`` to place in the default position + - Set the Euler angles of the camera by ``.set_euler_angles(theta, phi, gamma)`` + - Set three single Euler angles by ``.set_theta(theta)``, ``.set_phi(phi)``, ``.set_gamma(gamma)`` + - Use ``.increment_theta(dtheta)``, ``.increment_phi(dphi)``, ``.increment_gamma(gamma)`` to increase the three Euler angles by a certain value. Can be used to realize automatic rotation ``self.camera.frame.add_updater(lambda mob, dt: mob.increment_theta(0.1 * dt))`` + + - ``Camera`` adds a light source, which is a ``Point``, which can be called by ``self.camera.light_source`` in ``Scene`` to move and so on. The default position is ``(- 10, 10, 10)`` + +- Delete ``Container`` +- ``Mobject`` + + - ``svg`` related + + - Added ``Checkmark`` and ``Exmark`` + - Some unnecessary classes have been removed from ``drawings.py`` + - Removed ``Code`` and ``Paragraph`` (by mistake) + - ``TexMobject`` is renamed to ``Tex``, ``TextMobject`` is renamed to ``TexText`` + - ``font_size`` has been added to ``Tex``, ``TexText`` and ``Text`` + - ``Tex`` and ``TexText`` added ``isolate``, which is a list, which will be automatically split + + - Mobject ``types`` + + - Added a new class ``Surface``, which is the parent class of ``ParametricSurface`` and ``TexturedSurface``. + - Added the group ``SGroup`` for ``Surface`` + - Added ``TexturedSurface(uv_surface, image_file, dark_image_file=None)``, where ``uv_surface`` is a ``Surface``, ``image_file`` is the image to be posted, and ``dark_image_file`` is the image to be posted in the dark (default and ``image_file`` is the same) + - Deleted ``Mobject1D``, ``Mobject2D``, ``PointCloudDot`` + - Added ``DotCloud`` (a ``PMobject``), which has been greatly optimized + - Removed ``AbstractImageMobject``, ``ImageMobjectFromCamera`` + - Removed ``sheen`` from ``VMobject`` + + - ``Mobject`` + + - Added ``gloss`` and ``shadow``, which are the numbers between ``[0, 1]`` respectively. There are four methods of ``.get_gloss()``, ``.set_gloss(gloss)``, ``.get_shadow()``, ``.set_shadow(shadow)`` + - Added ``.get_grid(n_rows, n_cols)`` to copy into grid + - Added ``.set_color_by_code(glsl_code)`` to use GLSL code to change the color + - Added ``.set_color_by_xyz_func(glsl_snippet, min_value=-5.0, max_value=5.0, colormap="viridis")`` to pass in GLSL expression in the form of ``x,y,z``, the return value should be a floating point number + + - Coordinate system (including ``Axes``, ``ThreeDAxes``, ``NumberPlane``, ``ComplexPlane``) + + - No longer use ``x_min``, ``x_max``, ``y_min``, ``y_max``, but use ``x_range``, ``y_range`` as a ``np.array()``, containing three numbers ``np.array([ Minimum, maximum, step size])`` + - Added the abbreviation ``.i2gp(x, graph)`` of ``.input_to_graph_point(x, graph)`` + - Added some functions of the original ``GraphScene`` + + - Added ``.get_v_line(point)``, ``.get_h_line(point)`` to return the line from ``point`` to the two coordinate axes, and specify the line type through the keyword argument of ``line_func`` (default ``DashedLine``) + - Added ``.get_graph_label(graph, label, x, direction, buff, color)`` to return the label added to the image + - Added ``.get_v_line_to_graph(x, graph)``, ``.get_h_line_to_graph(x, graph)`` to return the line from the point with the abscissa of ``x`` on the ``graph`` to the two- axis line + - Added ``.angle_of_tangent(x, graph, dx=EPSILON)``, returns the inclination angle of ``graph`` at ``x`` + - Added ``.slope_of_tangent(x, graph, dx=EPSILON)``, returns the slope of tangent line of ``graph`` at ``x`` + - Added ``.get_tangent_line(x, graph, length=5)`` to return the tangent line of ``graph`` at ``x`` + - Added ``.get_riemann_rectangles(graph, x_range, dx, input_sample_type, ...)`` to return Riemann rectangles (a ``VGroup``) + + - The attribute ``number_line_config`` of ``Axes`` is renamed to ``axis_config`` + - ``Axes`` original ``.get_coordinate_labels(x_values, y_values)`` method was renamed to ``.add_coordinate_labels(x_values, y_values)`` (but it is not added to the screen) + - ``.add_coordinate_labels(numbers)`` of ``ComplexPlane`` will directly add the coordinates to the screen + + - ``NumberLine`` + + - No longer use ``x_min``, ``x_max``, ``tick_frequency``, but use ``x_range``, which is an array containing three numbers ``[min, max, step]`` + - The original ``label_direction`` attribute changed to the ``line_to_number_direction`` attribute + - Replace ``tip_width`` and ``tip_height`` with ``tip_config`` (dictionary) attributes + - The original ``exclude_zero_from_default`` attribute is modified to the ``numbers_to_exclude`` attribute (default is None) + - The original ``.add_tick_marks()`` method was changed to the ``.add_ticks()`` method + - Delete the ``.get_number_mobjects(*numbers)`` method, only use the ``.add_numbers(x_values=None, excluding=None)`` method + + - Three-dimensional objects + + - Added ``SurfaceMesh(uv_surface)``, pass in a ``Surface`` to generate its uv mesh + - ``ParametricSurface`` no longer uses ``u_min, u_max, v_min, v_max``, but instead uses ``u_range, v_range``, which is a tuple (``(min, max)``), and ``resolution`` can be set larger, don’t worry Speed ​​issue + - Added ``Torus``, controlled by ``r1, r2`` keyword parameters + - Added ``Cylinder``, controlled by ``height, radius`` keyword parameters + - Added ``Line3D`` (extremely thin cylinder), controlled by the ``width`` keyword parameter + - Added ``Disk3D``, controlled by ``radius`` keyword parameter + - Add ``Square3D``, controlled by ``side_length`` keyword parameter + - Improved ``Cube`` and ``Prism``, the usage remains unchanged + + - Other objects + + - ``ParametricFunction`` is renamed to ``ParametricCurve``. Instead of using ``t_min, t_max, step_size``, use ``t_range``, which is an array of three numbers (``[t_min, t_max, step_size]``). ``dt`` was renamed to ``epsilon``. Other usage remains unchanged + - All ``TipableVMobject`` can pass in ``tip_length`` to control the style of ``tip`` + - ``Line`` adds ``.set_points_by_ends(start, end, buff=0, path_arc=0)`` method + - ``Line`` added ``.get_projection(point)`` to return the projection position of ``point`` on a straight line + - ``Arrow`` adds three attributes of ``thickness, tip_width_ratio, tip_angle`` + - ``CubicBezier`` is changed to ``a0, h0, h1, a1``, that is, only a third-order Bezier curve is supported + - ``Square`` can be initialized directly by passing in ``side_length`` instead of using the keyword ``side_length=`` + - ``always_redraw(func, *args, **kwargs)`` supports incoming parameters ``*args, **kwargs`` + - The ``digit_to_digit_buff`` property of ``DecimalNumber`` has been renamed to ``digit_buff_per_font_unit``, and the ``.scale()`` method has been improved + - ``ValueTracker`` adds ``value_type`` attribute, the default is ``np.float64`` + +- ``Scene`` + + - Removed all functions of ``GraphScene`` (moved to ``once_useful_constructs``), ``MovingCameraScene``, ``ReconfigurableScene``, ``SceneFromVideo``, ``ZoomedScene``, and ``ThreeDScene``. Because these can basically be achieved by adjusting ``CameraFrame`` (``self.camera.frame``) + - Currently ``SampleSpaceScene`` and ``VectorScene`` have not been changed for the new version, so it is not recommended to use (only ``Scene`` is recommended) + - Fix the export of gif, just use the ``-i`` option directly + - Added the ``.interact()`` method, during which the mouse and keyboard can be used to continue the interaction, which will be executed by default after the scene ends + - Added ``.embed()`` method, open iPython terminal to enter interactive mode + - Added ``.save_state()`` method to save the current state of the scene + - Added ``.restore()`` method to restore the entire scene to the saved state + +- ``utils`` + + - A series of functions related to second-order Bezier have been added to ``utils/bezier.py`` + - Added a function to read color map from ``matplotlib`` in ``utils/color.py`` + - Added a series of related functions for processing folders/custom styles/object families + - ``resize_array``, ``resize_preserving_order``, ``resize_with_interpolation`` three functions have been added to ``utils/iterables.py`` + - The definition of ``smooth`` is updated in ``utils/rate_functions.py`` + - ``clip(a, min_a, max_a)`` function has been added to ``utils/simple_functions.py`` + - Some functions have been improved in ``utils/space_ops.py``, some functions for space calculation, and functions for processing triangulation have been added + +- ``constants`` + + - Fixed the aspect ratio of the screen to 16:9 + - Deleted the old gray series (``LIGHT_GREY``, ``GREY``, ``DARK_GREY``, ``DARKER_GREY``), added a new series of gray ``GREY_A`` ~ ``GREY_E`` \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index 84df7151..25fc02a1 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -18,6 +18,7 @@ And here is a Chinese version of this documentation: https://manim.ml/shaders getting_started/example_scenes getting_started/config getting_started/structure + getting_started/whatsnew .. toctree:: :maxdepth: 2 diff --git a/example_scenes.py b/example_scenes.py index b7a1afcb..331c96e6 100644 --- a/example_scenes.py +++ b/example_scenes.py @@ -331,6 +331,85 @@ class UpdatersExample(Scene): self.wait(4 * PI) +class CoordinateSystemExample(Scene): + def construct(self): + axes = Axes( + # x-axis ranges from -1 to 10, with a default step size of 1 + x_range=(-1, 10), + # y-axis ranges from -2 to 10 with a step size of 0.5 + y_range=(-2, 2, 0.5), + # The axes will be stretched so as to match the specified + # height and width + height=6, + width=10, + # Axes is made of two NumberLine mobjects. You can specify + # their configuration with axis_config + axis_config={ + "stroke_color": GREY_A, + "stroke_width": 2, + }, + # Alternatively, you can specify configuration for just one + # of them, like this. + y_axis_config={ + "include_tip": False, + } + ) + # Keyword arguments of add_coordinate_labels can be used to + # configure the DecimalNumber mobjects which it creates and + # adds to the axes + axes.add_coordinate_labels( + font_size=20, + num_decimal_places=1, + ) + self.add(axes) + + # Axes descends from the CoordinateSystem class, meaning + # you can call call axes.coords_to_point, abbreviated to + # axes.c2p, to associate a set of coordinates with a point, + # like so: + dot = Dot(color=RED) + dot.move_to(axes.c2p(0, 0)) + self.play(FadeIn(dot, scale=0.5)) + self.play(dot.animate.move_to(axes.c2p(3, 2))) + self.wait() + self.play(dot.animate.move_to(axes.c2p(5, 0.5))) + self.wait() + + # Similarly, you can call axes.point_to_coords, or axes.p2c + # print(axes.p2c(dot.get_center())) + + # We can draw lines from the axes to better mark the coordinates + # of a given point. + # Here, the always_redraw command means that on each new frame + # the lines will be redrawn + h_line = always_redraw(lambda: axes.get_h_line(dot.get_left())) + v_line = always_redraw(lambda: axes.get_v_line(dot.get_bottom())) + + self.play( + ShowCreation(h_line), + ShowCreation(v_line), + ) + self.play(dot.animate.move_to(axes.c2p(3, -2))) + self.wait() + self.play(dot.animate.move_to(axes.c2p(1, 1))) + self.wait() + + # If we tie the dot to a particular set of coordinates, notice + # that as we move the axes around it respects the coordinate + # system defined by them. + f_always(dot.move_to, lambda: axes.c2p(1, 1)) + self.play( + axes.animate.scale(0.75), + axes.animate.to_corner(UL), + run_time=2, + ) + self.wait() + self.play(FadeOut(VGroup(axes, dot, h_line, v_line))) + + # Other coordinate systems you can play around with include + # ThreeDAxes, NumberPlane, and ComplexPlane. + + class GraphExample(Scene): def construct(self): axes = Axes((-3, 10), (-1, 8)) @@ -412,85 +491,6 @@ class GraphExample(Scene): self.wait() -class CoordinateSystemExample(Scene): - def construct(self): - axes = Axes( - # x-axis ranges from -1 to 10, with a default step size of 1 - x_range=(-1, 10), - # y-axis ranges from -2 to 10 with a step size of 0.5 - y_range=(-2, 2, 0.5), - # The axes will be stretched so as to match the specified - # height and width - height=6, - width=10, - # Axes is made of two NumberLine mobjects. You can specify - # their configuration with axis_config - axis_config={ - "stroke_color": GREY_A, - "stroke_width": 2, - }, - # Alternatively, you can specify configuration for just one - # of them, like this. - y_axis_config={ - "include_tip": False, - } - ) - # Keyword arguments of add_coordinate_labels can be used to - # configure the DecimalNumber mobjects which it creates and - # adds to the axes - axes.add_coordinate_labels( - font_size=20, - num_decimal_places=1, - ) - self.add(axes) - - # Axes descends from the CoordinateSystem class, meaning - # you can call call axes.coords_to_point, abbreviated to - # axes.c2p, to associate a set of coordinates with a point, - # like so: - dot = Dot(color=RED) - dot.move_to(axes.c2p(0, 0)) - self.play(FadeIn(dot, scale=0.5)) - self.play(dot.animate.move_to(axes.c2p(3, 2))) - self.wait() - self.play(dot.animate.move_to(axes.c2p(5, 0.5))) - self.wait() - - # Similarly, you can call axes.point_to_coords, or axes.p2c - # print(axes.p2c(dot.get_center())) - - # We can draw lines from the axes to better mark the coordinates - # of a given point. - # Here, the always_redraw command means that on each new frame - # the lines will be redrawn - h_line = always_redraw(lambda: axes.get_h_line(dot.get_left())) - v_line = always_redraw(lambda: axes.get_v_line(dot.get_bottom())) - - self.play( - ShowCreation(h_line), - ShowCreation(v_line), - ) - self.play(dot.animate.move_to(axes.c2p(3, -2))) - self.wait() - self.play(dot.animate.move_to(axes.c2p(1, 1))) - self.wait() - - # If we tie the dot to a particular set of coordinates, notice - # that as we move the axes around it respects the coordinate - # system defined by them. - f_always(dot.move_to, lambda: axes.c2p(1, 1)) - self.play( - axes.animate.scale(0.75), - axes.animate.to_corner(UL), - run_time=2, - ) - self.wait() - self.play(FadeOut(VGroup(axes, dot, h_line, v_line))) - - # Other coordinate systems you can play around with include - # ThreeDAxes, NumberPlane, and ComplexPlane. - - class SurfaceExample(Scene): CONFIG = { "camera_class": ThreeDCamera, diff --git a/manimlib/mobject/coordinate_systems.py b/manimlib/mobject/coordinate_systems.py index 980b5106..fa293be8 100644 --- a/manimlib/mobject/coordinate_systems.py +++ b/manimlib/mobject/coordinate_systems.py @@ -25,8 +25,8 @@ class CoordinateSystem(): """ CONFIG = { "dimension": 2, - "x_range": np.array([-8, 8, 1]), - "y_range": np.array([-4, 4, 1]), + "x_range": np.array([-8, 8, 1.0]), + "y_range": np.array([-4, 4, 1.0]), "width": None, "height": None, "num_sampled_graph_points_per_tick": 5, @@ -280,7 +280,7 @@ class Axes(VGroup, CoordinateSystem): if x_range is not None: self.x_range[:len(x_range)] = x_range if y_range is not None: - self.y_range[:len(x_range)] = y_range + self.y_range[:len(y_range)] = y_range self.x_axis = self.create_axis( self.x_range, self.x_axis_config, self.width,