Closed Danny-Xiao closed 4 years ago
MovingCameraScene has an assert that collides with the others so there's that.
The last scene argument passed which in this case is ThreeDScene dominates the camera class making the other stuff like LinearTransformationScene and MovingCameraScene unusable.
Also, two things:
It's better to learn how to make your own attributes to modify them to what you're making. This means actually learning Python otherwise you stick with the arbitrary decisions of others.
I have tried this out before and it's really annoying. Needing to 3D transform something that isn't compatible with an animation before it e.g moving the camera so I usually opt to make two scenes where the second is a continuation of the first. Obvious disadvantage here is having to follow up results of animations in the second scene by copy pasting code.
Also, UpdateFromAlphaFunc does a better and less traumatizing job than a value tracker. I used it in my version of your code but I realized you were transforming the thing into an ellipse so I just made that happen. There's also other tricks you can find there such as defining class methods for specific scenes and using them kind of like functions which is more of a Python thing than a Manim thing.
Lastly, please use slightly deeper indentation. Makes code more readable.
class ExtractScene(MovingCameraScene):
CONFIG = {
"have_basis_vectors" : True
}
def setup(self):
MovingCameraScene.setup(self)
self.add(
NumberPlane(
x_min = -10,
x_max = 10,
y_min = -7,
y_max = 7
)
)
if self.have_basis_vectors:
self.add(
self.get_basis_vectors())
def construct(self):
point = Dot(
point = UP,
color = YELLOW,
)
func = Circle(
radius = 1,
color = ORANGE,
stroke_width = 2
)
self.play(
ShowCreation(point),
ShowCreation(func),
run_time = 3
)
self.wait()
matrix = np.array([[0, 1],[1, 0]])
self.apply_matrix(
matrix,
run_time=3
)
self.wait()
self.camera_frame.save_state()
self.play(
self.camera_frame.set_height, point.radius * 2 * 1.5,
self.camera_frame.move_to, point.get_center(),
run_time = 3
)
self.wait(3)
self.play(
Restore(self.camera_frame)
)
self.wait()
self.play(
self.turn_into_ellipse(func, 5),
rate_func = there_and_back,
run_time = 6
)
def get_basis_vectors(self):
return VGroup(*[
Vector(
vect,
color=color,
stroke_width=6
)
for vect, color in [
([1, 0], RED),
([0, 1], GREEN)
]
])
def apply_matrix(self, matrix, **kwargs):
proper = matrix
anims = [ApplyMatrix(
matrix.T, mobject)
for mobject in self.mobjects]
self.play(*anims, **kwargs)
def turn_into_ellipse(self, circle, new_width):
anim = ApplyMatrix(
matrix = np.array([[new_width, 0], [0,1]]),
mobject = circle
)
return anim
class ExtractScene2(ThreeDScene):
CONFIG = {
"have_basis_vectors" : True
}
def setup(self):
ThreeDScene.setup(self)
self.add(
NumberPlane(
x_min = -10,
x_max = 10,
y_min = -7,
y_max = 7
)
)
if self.have_basis_vectors:
self.add(
self.get_basis_vectors())
point = Dot(
point = UP,
color = YELLOW,
)
self.add(point)
matrix = np.array([[0, 1],[1, 0]])
for mob in self.get_mobjects():
ApplyMatrix(matrix, mob)
def construct(self):
func = Circle(
radius = 1,
color = ORANGE,
stroke_width = 2
)
self.add(func)
self.move_camera(
phi = 75 * DEGREES,
theta = -55 * DEGREES,
run_time = 3
)
sph = Sphere(radius = 1)
self.begin_ambient_camera_rotation(0.5)
self.play(
ReplacementTransform(func, sph),
run_time = 3
)
self.wait(4)
self.play(*[FadeOut(mob) for mob in self.mobjects])
def get_basis_vectors(self):
return VGroup(*[
Vector(
vect,
color=color,
stroke_width=6
)
for vect, color in [
([1, 0], RED),
([0, 1], GREEN)
]
])
def apply_matrix(self, matrix, **kwargs):
anims = [ApplyMatrix(
matrix.T, mobject)
for mobject in self.mobjects]
self.play(*anims, **kwargs)
If you want something done in Manim you do it yourself
- Someone with a lot of PTSD working with Manim
MovingCameraScene has an assert that collides with the others so there's that.
The last scene argument passed which in this case is ThreeDScene dominates the camera class making the other stuff like LinearTransformationScene and MovingCameraScene unusable.
Also, two things:
- It's better to learn how to make your own attributes to modify them to what you're making. This means actually learning Python otherwise you stick with the arbitrary decisions of others.
- I have tried this out before and it's really annoying. Needing to 3D transform something that isn't compatible with an animation before it e.g moving the camera so I usually opt to make two scenes where the second is a continuation of the first. Obvious disadvantage here is having to follow up results of animations in the second scene by copy pasting code.
Also, UpdateFromAlphaFunc does a better and less traumatizing job than a value tracker. I used it in my version of your code but I realized you were transforming the thing into an ellipse so I just made that happen. There's also other tricks you can find there such as defining class methods for specific scenes and using them kind of like functions which is more of a Python thing than a Manim thing.
Lastly, please use slightly deeper indentation. Makes code more readable.
class ExtractScene(MovingCameraScene): CONFIG = { "have_basis_vectors" : True } def setup(self): MovingCameraScene.setup(self) self.add( NumberPlane( x_min = -10, x_max = 10, y_min = -7, y_max = 7 ) ) if self.have_basis_vectors: self.add( self.get_basis_vectors()) def construct(self): point = Dot( point = UP, color = YELLOW, ) func = Circle( radius = 1, color = ORANGE, stroke_width = 2 ) self.play( ShowCreation(point), ShowCreation(func), run_time = 3 ) self.wait() matrix = np.array([[0, 1],[1, 0]]) self.apply_matrix( matrix, run_time=3 ) self.wait() self.camera_frame.save_state() self.play( self.camera_frame.set_height, point.radius * 2 * 1.5, self.camera_frame.move_to, point.get_center(), run_time = 3 ) self.wait(3) self.play( Restore(self.camera_frame) ) self.wait() self.play( self.turn_into_ellipse(func, 5), rate_func = there_and_back, run_time = 6 ) def get_basis_vectors(self): return VGroup(*[ Vector( vect, color=color, stroke_width=6 ) for vect, color in [ ([1, 0], RED), ([0, 1], GREEN) ] ]) def apply_matrix(self, matrix, **kwargs): proper = matrix anims = [ApplyMatrix( matrix.T, mobject) for mobject in self.mobjects] self.play(*anims, **kwargs) def turn_into_ellipse(self, circle, new_width): anim = ApplyMatrix( matrix = np.array([[new_width, 0], [0,1]]), mobject = circle ) return anim class ExtractScene2(ThreeDScene): CONFIG = { "have_basis_vectors" : True } def setup(self): ThreeDScene.setup(self) self.add( NumberPlane( x_min = -10, x_max = 10, y_min = -7, y_max = 7 ) ) if self.have_basis_vectors: self.add( self.get_basis_vectors()) point = Dot( point = UP, color = YELLOW, ) self.add(point) matrix = np.array([[0, 1],[1, 0]]) for mob in self.get_mobjects(): ApplyMatrix(matrix, mob) def construct(self): func = Circle( radius = 1, color = ORANGE, stroke_width = 2 ) self.add(func) self.move_camera( phi = 75 * DEGREES, theta = -55 * DEGREES, run_time = 3 ) sph = Sphere(radius = 1) self.begin_ambient_camera_rotation(0.5) self.play( ReplacementTransform(func, sph), run_time = 3 ) self.wait(4) self.play(*[FadeOut(mob) for mob in self.mobjects]) def get_basis_vectors(self): return VGroup(*[ Vector( vect, color=color, stroke_width=6 ) for vect, color in [ ([1, 0], RED), ([0, 1], GREEN) ] ]) def apply_matrix(self, matrix, **kwargs): anims = [ApplyMatrix( matrix.T, mobject) for mobject in self.mobjects] self.play(*anims, **kwargs)
If you want something done in Manim you do it yourself
- Someone with a lot of PTSD working with Manim
Thanks for your help and advice,well appreciated.I'll try to learn writing attributes myself as you suggested.
Watching the tutorial of Theorem Of Beethoven,I knew that I can use "def setup(self):" to use two scenes in one chass.However,when trying to use three scenes in one class,I find it will raise an error:
Traceback (most recent call last): File "D:\Desktop\manim\manimlib\extract_scene.py", line 155, in main scene = SceneClass(**scene_kwargs) File "D:\Desktop\manim\manimlib\scene\scene.py", line 75, in init self.construct() File ".\ThreeDScene.py", line 13, in construct self.add_transformable_mobject(point,func) AttributeError: 'scene' object has no attribute 'add_transformable_mobject'
So is there anything wrong with my script,or it's couldn't be done in theory? 3Scenes.txt