I wanted to apply two linear transformations with matrices one after the other in manimce
.
Here is the code for one transformation:
from manim import *
class LT(LinearTransformationScene):
def __init__(self):
LinearTransformationScene.__init__(
self,
show_coordinates=True,
leave_ghost_vectors=True,
)
def construct(self):
matrix = [[1, 1], [0, 1]]
self.apply_matrix(matrix)
self.wait()
This works perfectly for a single transformation.
But I want to apply another transformation after this. I tried using self.apply_matrix
again:
from manim import *
class LT(LinearTransformationScene):
def __init__(self):
LinearTransformationScene.__init__(
self,
show_coordinates=True,
leave_ghost_vectors=True,
)
def construct(self):
matrix1 = [[1, 1], [0, 1]]
self.apply_matrix(matrix1)
self.wait()
def construct(self):
matrix2 = [[2, 1], [3, 1]]
self.apply_matrix(matrix2)
self.wait()
with this code, only the last matrix was rendered. What might have happened?
This must be very simple. But I have no idea- didnt found anything in the documentation or search results.Any help is greatly appreciated.
Update:
As suggested by Nils Werner, I changed LinearTransformationScene.__init__(...)
to super().__init__(...)
and
included the two matrices in the same
def construct(self):
.
from manim import *
class LT(LinearTransformationScene):
def __init__(self):
super().__init__(
self,
show_coordinates=True,
leave_ghost_vectors=True,
)
def construct(self):
matrix1 = [[1, 1], [0, 1]]
self.apply_matrix(matrix1)
matrix2 = [[2, 1], [3, 1]]
self.apply_matrix(matrix2)
self.wait()
But this didn't work either. Shows error:
ValueError: operands could not be broadcast together with shapes (4,3) (12,3)
Full log:
PS C:\Python38> manim LTmul.py -pql
Manim Community v0.11.0
[10/26/21 21:24:39] INFO Animation 0 : Using cached data (hash : cairo_renderer.py:110
3163782288_2165879958_531335182)
┌─────────────────────────────── Traceback (most recent call last) ────────────────────────────────┐
│ │
│ C:\tools\Manim\Lib\site-packages\manim\cli\render\commands.py:139 in render │
│ │
│ 136 │ │ for SceneClass in scene_classes_from_file(file): │
│ 137 │ │ │ try: │
│ 138 │ │ │ │ scene = SceneClass() │
│ > 139 │ │ │ │ scene.render() │
│ 140 │ │ │ except Exception: │
│ 141 │ │ │ │ error_console.print_exception() │
│ 142 │ │ │ │ sys.exit(1) │
│ C:\tools\Manim\Lib\site-packages\manim\scene\scene.py:213 in render │
│ │
│ 210 │ │ """ │
│ 211 │ │ self.setup() │
│ 212 │ │ try: │
│ > 213 │ │ │ self.construct() │
│ 214 │ │ except EndSceneEarlyException: │
│ 215 │ │ │ pass │
│ 216 │ │ except RerunSceneException as e: │
│ │
│ C:\Python38\LTmul.py:16 in construct │
│ │
│ 13 │ │ self.apply_matrix(matrix1) │
│ 14 │ │ │
│ 15 │ │ matrix2 = [[2, 2], [3, 3]] │
│ > 16 │ │ self.apply_matrix(matrix2) │
│ 17 │ │ │
│ 18 │ │ self.wait() │
│ 19 │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\scene\vector_space_scene.py:1041 in apply_matrix │
│ │
│ 1038 │ │ **kwargs │
│ 1039 │ │ │ Any valid keyword argument of self.apply_transposed_matrix() │
│ 1040 │ │ """ │
│ > 1041 │ │ self.apply_transposed_matrix(np.array(matrix).T, **kwargs) │
│ 1042 │ │
│ 1043 │ def apply_inverse(self, matrix, **kwargs): │
│ 1044 │ │ """ │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\scene\vector_space_scene.py:1077 in │
│ apply_transposed_matrix │
│ │
│ 1074 │ │ │ │ [angle_of_vector(func(RIGHT)), angle_of_vector(func(UP)) - np.pi / 2], │
│ 1075 │ │ │ ) │
│ 1076 │ │ │ kwargs["path_arc"] = net_rotation │
│ > 1077 │ │ self.apply_function(func, **kwargs) │
│ 1078 │ │
│ 1079 │ def apply_inverse_transpose(self, t_matrix, **kwargs): │
│ 1080 │ │ """ │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\scene\vector_space_scene.py:1145 in apply_function │
│ │
│ 1142 │ │ │ + [Animation(f_mob) for f_mob in self.foreground_mobjects] │
│ 1143 │ │ │ + added_anims │
│ 1144 │ │ ) │
│ > 1145 │ │ self.play(*anims, **kwargs) │
│ 1146 │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\scene\scene.py:888 in play │
│ │
│ 885 │ │ │ return np.max([animation.run_time for animation in animations]) │
│ 886 │ │
│ 887 │ def play(self, *args, **kwargs): │
│ > 888 │ │ self.renderer.play(self, *args, **kwargs) │
│ 889 │ │
│ 890 │ def wait(self, duration=DEFAULT_WAIT_TIME, stop_condition=None): │
│ 891 │ │ self.play(Wait(run_time=duration, stop_condition=stop_condition)) │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\renderer\cairo_renderer.py:127 in play │
│ │
│ 124 │ │ self.static_image = self.save_static_frame_data(scene, scene.static_mobjects) │
│ 125 │ │ │
│ 126 │ │ self.file_writer.begin_animation(not self.skip_animations) │
│ > 127 │ │ scene.begin_animations() │
│ 128 │ │ if scene.is_current_animation_frozen_frame(): │
│ 129 │ │ │ self.update_frame(scene) │
│ 130 │ │ │ # self.duration stands for the total run time of all the animations. │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\scene\scene.py:961 in begin_animations │
│ │
│ 958 │ def begin_animations(self) -> None: │
│ 959 │ │ """Start the animations of the scene.""" │
│ 960 │ │ for animation in self.animations: │
│ > 961 │ │ │ animation.begin() │
│ 962 │ │
│ 963 │ def is_current_animation_frozen_frame(self) -> bool: │
│ 964 │ │ """Returns whether the current animation produces a static frame (generally a Wa │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\animation\transform.py:114 in begin │
│ │
│ 111 │ │ │ self.mobject.align_data_and_family(self.target_copy) │
│ 112 │ │ else: │
│ 113 │ │ │ self.mobject.align_data(self.target_copy) │
│ > 114 │ │ super().begin() │
│ 115 │ │
│ 116 │ def create_target(self) -> Mobject: │
│ 117 │ │ # Has no meaningful effect here, but may be useful │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\animation\animation.py:184 in begin │
│ │
│ 181 │ │ │ # the internal updaters of self.starting_mobject, │
│ 182 │ │ │ # or any others among self.get_all_mobjects() │
│ 183 │ │ │ self.mobject.suspend_updating() │
│ > 184 │ │ self.interpolate(0) │
│ 185 │ │
│ 186 │ def finish(self) -> None: │
│ 187 │ │ # TODO: begin and finish should require a scene as parameter. │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\animation\animation.py:284 in interpolate │
│ │
│ 281 │ │ │ The relative time to set the aniamtion to, 0 meaning the start, 1 meaning │
│ 282 │ │ │ the end. │
│ 283 │ │ """ │
│ > 284 │ │ self.interpolate_mobject(alpha) │
│ 285 │ │
│ 286 │ def interpolate_mobject(self, alpha: float) -> None: │
│ 287 │ │ """Interpolates the mobject of the :class:`Animation` based on alpha value. │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\animation\animation.py:299 in interpolate_mobject │
│ │
│ 296 │ │ families = list(self.get_all_families_zipped()) │
│ 297 │ │ for i, mobs in enumerate(families): │
│ 298 │ │ │ sub_alpha = self.get_sub_alpha(alpha, i, len(families)) │
│ > 299 │ │ │ self.interpolate_submobject(*mobs, sub_alpha) │
│ 300 │ │
│ 301 │ def interpolate_submobject( │
│ 302 │ │ self, │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\animation\transform.py:152 in interpolate_submobject │
│ │
│ 149 │ │ target_copy: Mobject, │
│ 150 │ │ alpha: float, │
│ 151 │ ) -> "Transform": │
│ > 152 │ │ submobject.interpolate(starting_submobject, target_copy, alpha, self.path_func) │
│ 153 │ │ return self │
│ 154 │
│ 155 │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\mobject\mobject.py:2597 in interpolate │
│ │
│ 2594 │ │ │ │ │ │
│ 2595 │ │ │ │ │ self.add(dotL, dotR, dotMiddle) │
│ 2596 │ │ """ │
│ > 2597 │ │ self.points = path_func(mobject1.points, mobject2.points, alpha) │
│ 2598 │ │ self.interpolate_color(mobject1, mobject2, alpha) │
│ 2599 │ │ return self │
│ 2600 │
│ │
│ C:\tools\Manim\Lib\site-packages\manim\utils\paths.py:43 in path │
│ │
│ 40 │ │
│ 41 │ def path(start_points, end_points, alpha): │
│ 42 │ │ if arc_centers is None: │
│ > 43 │ │ │ vects = end_points - start_points │
│ 44 │ │ │ centers = start_points + 0.5 * vects │
│ 45 │ │ │ if arc_angle != np.pi: │
│ 46 │ │ │ │ centers += np.cross(unit_axis, vects / 2.0) / np.tan(arc_angle / 2) │
└──────────────────────────────────────────────────────────────────────────────────────────────────┘
ValueError: operands could not be broadcast together with shapes (4,3) (12,3)
Apply the two matrices in the same construct()
call.
from manim import *
class LT(LinearTransformationScene):
def __init__(self):
super().__init__(
self,
show_coordinates=True,
leave_ghost_vectors=True,
)
def construct(self):
matrix1 = [[1, 1], [0, 1]]
self.apply_matrix(matrix1)
self.wait()
matrix2 = [[2, 1], [3, 1]]
self.apply_matrix(matrix2)
self.wait()