├── README.md ├── Epicycloid.py ├── Addition.py ├── Parabola.py ├── Kmap.py ├── CircleIllusion.py └── LogicGates.py /README.md: -------------------------------------------------------------------------------- 1 | # 🎬 Manim Animation Collection 2 | 3 | Hi, this is the repository that I store all my Manim code inside. 4 | 5 | These animations were created using [ManimCE](https://www.manim.community/), a powerful mathematical animation engine. 6 | Feel free to explore and use them for learning or teaching purposes! 7 | 8 | ## 📹 Video Showcase 9 | 10 | | File Name | Video Link | 11 | |---------------------|------------| 12 | | `Addition.py` | [▶️ Watch](https://youtu.be/uSNoMc2sixw) | 13 | | `Kmap.py` | [▶️ Watch](https://youtu.be/v2Bqy8FOwv4) | 14 | | `LogicGates.py` | [▶️ Watch](https://youtu.be/bVJ28jPvYxM) | 15 | | `Parabola.py` | [▶️ Watch](https://youtu.be/4sYztGxXPDI) | 16 | | `Epicycloid.py` | [▶️ Watch](https://youtu.be/WKGogr0tetQ) | 17 | | `CircleIllusion.py` | [▶️ Watch](https://youtu.be/eFq2xi2chNA) | 18 | -------------------------------------------------------------------------------- /Epicycloid.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | class EpicycloidScene(Scene): 4 | def construct(self): 5 | total_runtime = 6 6 | stable_circle_radius = 2.5 7 | moving_circle_radius = 0.5 8 | ratio = stable_circle_radius/moving_circle_radius + 1 9 | # When only focusing on the movements of moving_circle and dot, although the circumference ratio is 5:1, the dot actually revolutes 6 times about moving_circle. 10 | 11 | def update_trace(trace): 12 | previous_trace = trace.copy() 13 | previous_trace.add_points_as_corners([dot.get_center()]) 14 | trace.become(previous_trace) 15 | 16 | path = Circle(radius=stable_circle_radius+moving_circle_radius, stroke_opacity=0.2) 17 | stable_circle = Circle(radius=stable_circle_radius) 18 | moving_circle = Arc(radius=moving_circle_radius, start_angle=PI, angle=TAU).move_to(path.get_right()) 19 | dot = Dot().move_to(moving_circle.get_start()) 20 | trace = VMobject() 21 | trace.set_points_as_corners([moving_circle.get_start(), moving_circle.get_start()]) 22 | trace.add_updater(update_trace) 23 | trace.set_color(YELLOW) 24 | 25 | description = MathTex("R : r = 5 : 1").to_corner(UL) 26 | R_line = Line(start=stable_circle.get_center(), end=stable_circle.get_right()) 27 | R_tex = MathTex("R").move_to(R_line, aligned_edge=DOWN) 28 | r_line = Line(start=moving_circle.get_center(), end=dot.get_center()) 29 | r_tex = MathTex("r").move_to(r_line, aligned_edge=DOWN) 30 | r_line.add_updater(lambda mob: mob.become(Line(start=moving_circle.get_center(), end=dot.get_center()))) 31 | R = VGroup(R_line, R_tex) 32 | r = VGroup(r_line, r_tex) 33 | 34 | 35 | moving_cir_animation = MoveAlongPath(moving_circle, path=path, run_time=total_runtime, rate_func=linear) 36 | moving_dot_animation = Succession(*[MoveAlongPath(dot, path=moving_circle, run_time=total_runtime/ratio, rate_func=linear) for i in range(int(ratio))]) 37 | 38 | self.add(stable_circle, moving_circle, trace, dot, R, r) 39 | self.play(Write(description)) 40 | self.wait() 41 | self.play(Unwrite(R), Unwrite(r_tex)) 42 | self.wait(0.5) 43 | self.play(AnimationGroup(moving_cir_animation, moving_dot_animation)) 44 | self.wait(3) 45 | 46 | -------------------------------------------------------------------------------- /Addition.py: -------------------------------------------------------------------------------- 1 | import manim from * 2 | 3 | class Addition(Scene): 4 | def construct(self): 5 | expression = Tex("1257 + 894 = ", "?").scale(1.5) 6 | self.play(Write(expression)) 7 | self.wait() 8 | self.play(expression.animate.to_corner(UL)) 9 | self.wait() 10 | 11 | num1 = MathTex("1", "2", "5", "7", color=WHITE).scale(2) 12 | num2 = MathTex("8", "9", "4", color=WHITE).scale(2) 13 | ans = MathTex("2", "1", "5", "1", color=WHITE).scale(2) 14 | line = Line(start=num1.get_left() + LEFT*2, end=num1.get_right(), color=WHITE) 15 | numbers = VGroup(num1, num2, line, ans).arrange(DOWN, aligned_edge = RIGHT, buff=0.5) 16 | plus_sign = MathTex("+").scale(2).next_to(num2, direction=LEFT, buff=1.5) 17 | 18 | # Create scene 19 | self.play( 20 | Write(num1), 21 | Write(num2), 22 | Write(plus_sign), 23 | Create(line), 24 | ) 25 | self.wait() 26 | 27 | # ones 28 | ones_sum = MathTex("1", "1", color=WHITE).scale(2).move_to(ans[-1],aligned_edge=RIGHT) 29 | self.play( 30 | Indicate(num1[-1]), 31 | Indicate(num2[-1]), 32 | ) 33 | self.wait() 34 | self.play(Write(ones_sum)) 35 | self.wait() 36 | self.play(ones_sum[0].animate.next_to(num1[-2], direction=UP, buff=0.5).scale(0.8)) 37 | 38 | # tens 39 | tens_sum = MathTex("1", "5", color=WHITE).scale(2).move_to(ans[-2],aligned_edge=RIGHT) 40 | self.play( 41 | Indicate(num1[-2]), 42 | Indicate(num2[-2]), 43 | Indicate(ones_sum[0]), 44 | ) 45 | self.wait() 46 | self.play(Write(tens_sum)) 47 | self.wait() 48 | self.play(tens_sum[0].animate.next_to(num1[-3], direction=UP, buff=0.5).scale(0.8)) 49 | 50 | # hundreds 51 | hunds_sum = MathTex("1", "1", color=WHITE).scale(2).move_to(ans[-3],aligned_edge=RIGHT) 52 | self.play( 53 | Indicate(num1[-3]), 54 | Indicate(num2[-3]), 55 | Indicate(tens_sum[0]), 56 | ) 57 | self.wait() 58 | self.play(Write(hunds_sum)) 59 | self.wait() 60 | self.play(hunds_sum[0].animate.next_to(num1[-4], direction=UP, buff=0.5).scale(0.8)) 61 | 62 | # thousands 63 | self.play( 64 | Indicate(num1[-4]), 65 | Indicate(hunds_sum[0]), 66 | ) 67 | self.wait() 68 | self.play(Write(ans[0])) 69 | self.wait() 70 | 71 | # ending 72 | qmark_transform = Tex("2151", color=YELLOW).scale(1.5).move_to(expression[1], aligned_edge=LEFT) 73 | self.play(Circumscribe(ans, fade_out=True)) 74 | self.wait() 75 | self.play(Transform(expression[-1], qmark_transform)) 76 | self.wait() 77 | -------------------------------------------------------------------------------- /Parabola.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | class ParabolaScene(Scene): 4 | def construct(self): 5 | # (x-h)^2 = 4c(y-k) 6 | c = 3 7 | h = 0 8 | k = 0 9 | 10 | # Used in x_range: x_range = [startvalue, endvalue] 11 | # Detect whether y exceed config["frame_x_radius"] when x is config["frame_x_radius"], so that the center of the circle doesn't go out of the screen. 12 | startvalue = max(-np.sqrt(4*abs(c)*(config["frame_y_radius"]-k))+h, -config["frame_x_radius"]) 13 | endvalue = min(np.sqrt(4*abs(c)*(config["frame_y_radius"]-k))+h, config["frame_x_radius"]) 14 | e = ValueTracker(startvalue) 15 | plane = NumberPlane( 16 | faded_line_ratio=2, 17 | background_line_style = { 18 | "stroke_color": BLUE_D, 19 | "stroke_width": 2, 20 | "stroke_opacity": 0.5, 21 | }, 22 | axis_config = { 23 | "stroke_opacity": 0, 24 | }, 25 | ) 26 | 27 | # y = (x-h)^2/4c + k 28 | parabola = FunctionGraph(lambda x: ((x-h)**2)/(4*c) + k, color=WHITE) 29 | directrix = Line(start=[-config["frame_x_radius"], k-c, 0], end=[config["frame_x_radius"], k - c, 0]) 30 | focus = Dot(point=[h, k+c, 0], color=RED) 31 | 32 | moving_dot = always_redraw(lambda: Dot(point=[e.get_value(), ((e.get_value()-h)**2)/(4*c) + k, 0])) 33 | dot_to_directrix = always_redraw(lambda: DashedLine(start=moving_dot.get_center(), end=[e.get_value(), k-c, 0], stroke_opacity=0.5)) 34 | dot_to_focus = always_redraw(lambda: DashedLine(start=moving_dot.get_center(), end=focus.get_center(), stroke_opacity=0.5)) 35 | circle = always_redraw(lambda: Circle(radius=((e.get_value()-h)**2)/(4*c) + k - (k-c), stroke_opacity=0.8).move_to(moving_dot)) 36 | 37 | self.add(plane) 38 | self.add(parabola, directrix, focus) 39 | self.wait() 40 | self.add(moving_dot, dot_to_directrix, dot_to_focus, circle) 41 | self.play(e.animate.set_value(endvalue), run_time=10, rate_func=linear) 42 | self.wait() 43 | 44 | # The animation of changing the previous parabola to the current one. 45 | class ParabolaChangingScene(Scene): 46 | def construct(self): 47 | c = ValueTracker(1) 48 | h = ValueTracker(0) 49 | k = ValueTracker(-1) 50 | 51 | plane = NumberPlane( 52 | faded_line_ratio=2, 53 | background_line_style = { 54 | "stroke_color": BLUE_D, 55 | "stroke_width": 2, 56 | "stroke_opacity": 0.5, 57 | }, 58 | axis_config = { 59 | "stroke_opacity": 0, 60 | }, 61 | ) 62 | 63 | parabola = always_redraw(lambda: FunctionGraph(lambda x: ((x-h.get_value())**2)/(4*c.get_value()) + k.get_value(), color=WHITE)) 64 | directrix = always_redraw(lambda: Line(start=[-config["frame_x_radius"], k.get_value() - c.get_value(), 0], end=[config["frame_x_radius"], k.get_value() - c.get_value(), 0])) 65 | focus = always_redraw(lambda: Dot(point=[h.get_value(), k.get_value()+c.get_value(), 0], color=RED)) 66 | 67 | self.add(plane, parabola, directrix, focus) 68 | self.play(c.animate.set_value(3), k.animate.set_value(0), run_time=2) 69 | self.wait() 70 | -------------------------------------------------------------------------------- /Kmap.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | class KmapScene(Scene): 4 | def construct(self): 5 | # Truth Table 6 | TopLeftEntry = VGroup( 7 | Tex("x", "y", font_size=DEFAULT_FONT_SIZE).shift(DOWN*0.6), 8 | Tex("z", "w", font_size=DEFAULT_FONT_SIZE).shift(RIGHT*0.6), 9 | ) 10 | Kmap = IntegerTable( 11 | [[1,1,1,0], 12 | [1,1,1,0], 13 | [0,1,1,1], 14 | [0,1,1,1]], 15 | row_labels=[MathTex("0", "0"), MathTex("0", "1"), MathTex("1", "1"), MathTex("1", "0")], 16 | col_labels=[MathTex("0", "0"), MathTex("0", "1"), MathTex("1", "1"), MathTex("1", "0")], 17 | v_buff=1.0, 18 | h_buff=1.0, 19 | top_left_entry=TopLeftEntry, 20 | ).shift(LEFT*3) 21 | 22 | # Expressions 23 | expression = MathTex("f(x,y,z,w)=\\Sigma m(0,1,3,4,5,7,9,10,11,13,14,15)") 24 | expression_simp = MathTex("x'z'", "+", "xz", "+", "w").shift(RIGHT*(config["frame_x_radius"]+Kmap.get_right())/2).scale(1.5) 25 | 26 | # Ones to be surrounded 27 | frame1_group = VGroup(Kmap.get_entries_without_labels()[0:2], Kmap.get_entries_without_labels()[4:6]) 28 | frame2_group = VGroup(Kmap.get_entries_without_labels()[1:3], Kmap.get_entries_without_labels()[5:7], Kmap.get_entries_without_labels()[9:11], Kmap.get_entries_without_labels()[13:15]) 29 | frame3_group = VGroup(Kmap.get_entries_without_labels()[10:12], Kmap.get_entries_without_labels()[14:16]) 30 | frame1 = SurroundingRectangle(VGroup(frame1_group), color=RED, buff=0.3).round_corners(radius=0.2) 31 | frame2 = SurroundingRectangle(VGroup(frame2_group), color=RED, buff=0.3).round_corners(radius=0.2) 32 | frame3 = SurroundingRectangle(VGroup(frame3_group), color=RED, buff=0.3).round_corners(radius=0.2) 33 | 34 | 35 | self.play(Write(expression)) 36 | self.wait(3) 37 | self.play(FadeOut(expression)) 38 | self.wait() 39 | self.play(Kmap.create(), run_time=5) 40 | self.wait(3) 41 | 42 | self.play(Create(frame1)) 43 | self.wait() 44 | self.play(Indicate(TopLeftEntry[0][0]), Indicate(Kmap.get_labels()[5][0]), Indicate(Kmap.get_labels()[6][0])) 45 | self.wait() 46 | self.play(Indicate(TopLeftEntry[1][0]), Indicate(Kmap.get_labels()[1][0]), Indicate(Kmap.get_labels()[2][0])) 47 | self.wait() 48 | self.play(Write(expression_simp[0])) 49 | self.wait(3) 50 | 51 | self.play(Create(frame2)) 52 | self.wait() 53 | self.play(Indicate(TopLeftEntry[1][1]), Indicate(Kmap.get_labels()[2][1]), Indicate(Kmap.get_labels()[3][1])) 54 | self.wait() 55 | self.play(Write(expression_simp[4])) 56 | self.wait(3) 57 | 58 | self.play(Create(frame3)) 59 | self.wait() 60 | self.play(Indicate(TopLeftEntry[0][0]), Indicate(Kmap.get_labels()[7][0]), Indicate(Kmap.get_labels()[8][0])) 61 | self.wait() 62 | self.play(Indicate(TopLeftEntry[1][0]), Indicate(Kmap.get_labels()[3][0]), Indicate(Kmap.get_labels()[4][0])) 63 | self.wait() 64 | self.play(Write(expression_simp[2])) 65 | self.wait() 66 | 67 | self.play(Write(expression_simp[1]), Write(expression_simp[3]), FadeOut(frame1), FadeOut(frame2), FadeOut(frame3), FadeOut(Kmap)) 68 | self.play(expression_simp.animate.move_to(ORIGIN)) 69 | self.wait(3) 70 | -------------------------------------------------------------------------------- /CircleIllusion.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | class CircleIllusion(Scene): 4 | def construct(self): 5 | bg_circle_radius = 3 6 | origin_point = np.array([-3,0,0]) 7 | period = 4 8 | revolution = 2*PI 9 | 10 | # Dot moving around the circle(rotating_dot). 11 | phase = ValueTracker(0*DEGREES) 12 | rdot = always_redraw(lambda: Dot(point=[bg_circle_radius*np.cos(phase.get_value())-3,bg_circle_radius*np.sin(phase.get_value()),0], color=RED)) 13 | rdot_vect_length = np.sqrt((rdot.get_center()[0] - origin_point[0])**2 + (rdot.get_center()[1] - origin_point[1])**2) 14 | 15 | # Background Circle 16 | bg_circle = Circle(radius=bg_circle_radius, color=WHITE, stroke_opacity=0.5).move_to(origin_point) 17 | imaginary_circle = Circle(radius=bg_circle_radius/2).shift(LEFT*1.5) 18 | imaginary_circle_path = Circle(radius=bg_circle_radius/2).shift(LEFT*3) 19 | 20 | # Creating paths that dots follow 21 | path_angles = np.arange(0*DEGREES, 180*DEGREES, 22.5*DEGREES) 22 | paths = VGroup() 23 | for angle in path_angles: 24 | paths.add(Line(start=[bg_circle_radius,0,0], end=[-bg_circle_radius,0,0], stroke_opacity=0.3).rotate_about_origin(angle).move_to(origin_point)) 25 | 26 | 27 | # By projecting rdot on every path will create S.H.M. 28 | def SHM_on_path0(): 29 | unit_vect = Vector(RIGHT).rotate_about_origin(path_angles[0]) 30 | scalar = rdot_vect_length*np.cos(phase.get_value()-path_angles[0]) 31 | hodot_vect = Arrow(start=origin_point, end=origin_point+unit_vect.get_end()*scalar, buff=0) 32 | return Dot(point=hodot_vect.get_end()) 33 | dot0 = always_redraw(SHM_on_path0) 34 | 35 | def SHM_on_path1(): 36 | unit_vect = Vector(RIGHT).rotate_about_origin(path_angles[1]) 37 | scalar = rdot_vect_length*np.cos(phase.get_value()-path_angles[1]) 38 | hodot_vect = Arrow(start=origin_point, end=origin_point+unit_vect.get_end()*scalar, buff=0) 39 | return Dot(point=hodot_vect.get_end()) 40 | dot1 = always_redraw(SHM_on_path1) 41 | 42 | def SHM_on_path2(): 43 | unit_vect = Vector(RIGHT).rotate_about_origin(path_angles[2]) 44 | scalar = rdot_vect_length*np.cos(phase.get_value()-path_angles[2]) 45 | hodot_vect = Arrow(start=origin_point, end=origin_point+unit_vect.get_end()*scalar, buff=0) 46 | return Dot(point=hodot_vect.get_end()) 47 | dot2 = always_redraw(SHM_on_path2) 48 | 49 | def SHM_on_path3(): 50 | unit_vect = Vector(RIGHT).rotate_about_origin(path_angles[3]) 51 | scalar = rdot_vect_length*np.cos(phase.get_value()-path_angles[3]) 52 | hodot_vect = Arrow(start=origin_point, end=origin_point+unit_vect.get_end()*scalar, buff=0) 53 | return Dot(point=hodot_vect.get_end()) 54 | dot3 = always_redraw(SHM_on_path3) 55 | 56 | def SHM_on_path4(): 57 | unit_vect = Vector(RIGHT).rotate_about_origin(path_angles[4]) 58 | scalar = rdot_vect_length*np.cos(phase.get_value()-path_angles[4]) 59 | hodot_vect = Arrow(start=origin_point, end=origin_point+unit_vect.get_end()*scalar, buff=0) 60 | return Dot(point=hodot_vect.get_end()) 61 | dot4 = always_redraw(SHM_on_path4) 62 | 63 | def SHM_on_path5(): 64 | unit_vect = Vector(RIGHT).rotate_about_origin(path_angles[5]) 65 | scalar = rdot_vect_length*np.cos(phase.get_value()-path_angles[5]) 66 | hodot_vect = Arrow(start=origin_point, end=origin_point+unit_vect.get_end()*scalar, buff=0) 67 | return Dot(point=hodot_vect.get_end()) 68 | dot5 = always_redraw(SHM_on_path5) 69 | 70 | def SHM_on_path6(): 71 | unit_vect = Vector(RIGHT).rotate_about_origin(path_angles[6]) 72 | scalar = rdot_vect_length*np.cos(phase.get_value()-path_angles[6]) 73 | hodot_vect = Arrow(start=origin_point, end=origin_point+unit_vect.get_end()*scalar, buff=0) 74 | return Dot(point=hodot_vect.get_end()) 75 | dot6 = always_redraw(SHM_on_path6) 76 | 77 | def SHM_on_path7(): 78 | unit_vect = Vector(RIGHT).rotate_about_origin(path_angles[7]) 79 | scalar = rdot_vect_length*np.cos(phase.get_value()-path_angles[7]) 80 | hodot_vect = Arrow(start=origin_point, end=origin_point+unit_vect.get_end()*scalar, buff=0) 81 | return Dot(point=hodot_vect.get_end()) 82 | dot7 = always_redraw(SHM_on_path7) 83 | 84 | dots = VGroup(dot0, dot1, dot2, dot3, dot4, dot5, dot6, dot7) 85 | 86 | # Show the projection of rdot on every path 87 | projection0 = always_redraw(lambda: DashedLine(start=rdot.get_center(), end=dot0.get_center(), color=RED, stroke_opacity=0.5)) 88 | projection1 = always_redraw(lambda: DashedLine(start=rdot.get_center(), end=dot1.get_center(), color=RED, stroke_opacity=0.5)) 89 | projection2 = always_redraw(lambda: DashedLine(start=rdot.get_center(), end=dot2.get_center(), color=RED, stroke_opacity=0.5)) 90 | projection3 = always_redraw(lambda: DashedLine(start=rdot.get_center(), end=dot3.get_center(), color=RED, stroke_opacity=0.5)) 91 | projection4 = always_redraw(lambda: DashedLine(start=rdot.get_center(), end=dot4.get_center(), color=RED, stroke_opacity=0.5)) 92 | projection5 = always_redraw(lambda: DashedLine(start=rdot.get_center(), end=dot5.get_center(), color=RED, stroke_opacity=0.5)) 93 | projection6 = always_redraw(lambda: DashedLine(start=rdot.get_center(), end=dot6.get_center(), color=RED, stroke_opacity=0.5)) 94 | projection7 = always_redraw(lambda: DashedLine(start=rdot.get_center(), end=dot7.get_center(), color=RED, stroke_opacity=0.5)) 95 | 96 | projections = VGroup(projection0, projection1, projection2, projection3, projection4, projection5, projection6, projection7) 97 | 98 | # Subtitles 99 | subtitles = VGroup( 100 | Text("首先來看一下動畫"), #0 101 | VGroup(Text("看起來像不像是"), Text("一個圓圈在滾動")).arrange(DOWN), #1 102 | Text("但如果仔細觀察的話"), #2 103 | VGroup(Text("每個點都是在直線上"), Text("來回走動的")).arrange(DOWN), #3 104 | VGroup(Text("現在假如圓上有一個"), Text("紅點等速旋轉")).arrange(DOWN), #4 105 | VGroup(Text("直線上的每一個點都"), Text("可以看成是圓上的點"), Text("在每個直線上投影出"), Text("來的影子")).arrange(DOWN), #5 106 | VGroup(Text("可以細觀察虛線的"), Text("移動方式")).arrange(DOWN), #6 107 | VGroup(Text("接下來我們來拆解成"), Text("一條直線的情況")).arrange(DOWN), #7 108 | VGroup(Text("可以看到線上的點"), Text("正在做簡諧運動")).arrange(DOWN), #8 109 | VGroup(Text("即使在不同角度的線"), Text("上仍做簡諧運動")).arrange(DOWN), #9 110 | VGroup(Text("但起始位置與原本的"), Text("會有些許改變")).arrange(DOWN), #10 111 | VGroup(Text("這個改變的量"), Text("就是相位差")).arrange(DOWN), #11 112 | VGroup(Text("接著我們換回成"), Text("原本的動畫")).arrange(DOWN), #12 113 | ) 114 | subtitles.scale(0.8) 115 | subtitles.shift(RIGHT*config["frame_x_radius"]/2) 116 | 117 | 118 | # part 1 119 | self.add(bg_circle) 120 | self.play(FadeIn(subtitles[0])) 121 | self.wait() 122 | self.play(FadeIn(dots), run_time=2) 123 | self.wait() 124 | self.play(phase.animate.increment_value(3*revolution), run_time=3*period, rate_func=linear) 125 | self.wait() 126 | 127 | # part 2 128 | self.play( 129 | ReplacementTransform(subtitles[0], subtitles[1]), 130 | FadeIn(imaginary_circle), 131 | ) 132 | self.wait() 133 | self.play( 134 | MoveAlongPath(imaginary_circle, imaginary_circle_path), 135 | phase.animate.increment_value(revolution), 136 | run_time=2*period, 137 | rate_func=linear, 138 | ) 139 | self.wait() 140 | self.play( 141 | ReplacementTransform(subtitles[1], subtitles[2]), 142 | FadeOut(imaginary_circle), 143 | ) 144 | self.wait() 145 | 146 | # part 3 147 | self.play(AnimationGroup(*[FadeIn(path) for path in paths], lag_ratio=0.5, run_time=period)) 148 | self.wait() 149 | self.play(ReplacementTransform(subtitles[2], subtitles[3])) 150 | self.wait() 151 | self.play(phase.animate.increment_value(2*revolution), run_time=2*period, rate_func=linear) 152 | self.wait() 153 | 154 | # part 4 155 | self.play(ReplacementTransform(subtitles[3], subtitles[4]), FadeIn(rdot)) 156 | self.wait(2) 157 | self.play(ReplacementTransform(subtitles[4], subtitles[5]), FadeIn(projections)) 158 | self.wait(3) 159 | self.play(ReplacementTransform(subtitles[5], subtitles[6])) 160 | self.wait() 161 | self.play(phase.animate.increment_value(2*revolution), run_time=4*period, rate_func=linear) 162 | self.wait() 163 | self.play( 164 | ReplacementTransform(subtitles[6], subtitles[7]), 165 | FadeOut(paths[1:8]), 166 | FadeOut(projections[1:8]), 167 | FadeOut(dots[1:8]), 168 | ) 169 | self.wait(2) 170 | 171 | # part 5 172 | self.play(ReplacementTransform(subtitles[7], subtitles[8])) 173 | self.play(phase.animate.increment_value(revolution), run_time=2*period, rate_func=linear) 174 | self.wait() 175 | self.play( 176 | ReplacementTransform(subtitles[8], subtitles[9]), 177 | FadeOut(paths[0]), FadeOut(projections[0]), FadeOut(dots[0]), 178 | FadeIn(paths[1]), FadeIn(projections[1]), FadeIn(dots[1]), 179 | ) 180 | self.play(phase.animate.increment_value(revolution), run_time=2*period, rate_func=linear) 181 | self.wait() 182 | self.play( 183 | ReplacementTransform(subtitles[9], subtitles[10]), 184 | FadeOut(paths[1]), FadeOut(projections[1]), FadeOut(dots[1]), 185 | FadeIn(paths[2]), FadeIn(projections[2]), FadeIn(dots[2]), 186 | ) 187 | self.play(phase.animate.increment_value(revolution), run_time=2*period, rate_func=linear) 188 | self.wait() 189 | self.play( 190 | ReplacementTransform(subtitles[10], subtitles[11]), 191 | FadeOut(paths[2]), FadeOut(projections[2]), FadeOut(dots[2]), 192 | FadeIn(paths[3]), FadeIn(projections[3]), FadeIn(dots[3]), 193 | ) 194 | self.play(phase.animate.increment_value(revolution), run_time=2*period, rate_func=linear) 195 | self.wait() 196 | self.play( 197 | FadeOut(paths[3]), FadeOut(projections[3]), FadeOut(dots[3]), 198 | FadeIn(paths[4]), FadeIn(projections[4]), FadeIn(dots[4]), 199 | ) 200 | self.play(phase.animate.increment_value(revolution), run_time=2*period, rate_func=linear) 201 | self.wait() 202 | self.play( 203 | ReplacementTransform(subtitles[11], subtitles[12]), 204 | FadeOut(paths[4]), 205 | FadeOut(dots[4]), 206 | FadeOut(projections[4]), 207 | FadeOut(rdot), 208 | ) 209 | self.wait(2) 210 | self.play(FadeIn(paths), FadeIn(dots)) 211 | self.wait() 212 | self.play(phase.animate.increment_value(3*revolution), run_time=3*period, rate_func=linear) 213 | self.wait() 214 | self.play(FadeOut(paths), FadeOut(dots), FadeOut(bg_circle), FadeOut(subtitles[12])) 215 | self.wait() 216 | 217 | 218 | 219 | -------------------------------------------------------------------------------- /LogicGates.py: -------------------------------------------------------------------------------- 1 | from manim import * 2 | 3 | class TitleScene(Scene): 4 | def construct(self): 5 | title = Text("Logic Gates").scale(2) 6 | self.add(title) 7 | self.wait() 8 | self.play(FadeOut(title)) 9 | self.wait() 10 | 11 | 12 | 13 | class LogicGates(Scene): 14 | def construct(self): 15 | # AND 16 | and_uphor = Line(start = [0,1,0], end = [-1,1,0]) 17 | and_lowhor = Line(start = [0,-1,0], end = [-1,-1, 0]) 18 | and_ver = Line(start = [-1,1,0], end = [-1,-1,0]) 19 | and_arc = Arc(radius = 1.0, start_angle = -PI/2 , angle = PI) 20 | and_text = Text("AND").shift(DOWN*2) 21 | AND_gate = Group(and_uphor, and_lowhor, and_ver, and_arc, and_text) 22 | self.play( 23 | Create(and_uphor), 24 | Create(and_lowhor), 25 | Create(and_ver), 26 | Create(and_arc), 27 | run_time = 1, 28 | ) 29 | self.play(Write(and_text)) 30 | self.add(AND_gate) 31 | self.wait() 32 | self.play(AND_gate.animate.move_to([-6,2,0]).scale(0.6)) 33 | self.wait() 34 | 35 | # OR 36 | or_uparc = ArcBetweenPoints(start = [-1,-1,0], end = [1,0,0], angle = PI/4) 37 | or_lowarc = ArcBetweenPoints(start = [-1,1,0], end = [1,0,0], angle = -PI/4) 38 | or_leftarc = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3) 39 | or_text = Text("OR").shift(DOWN*2) 40 | OR_gate = Group(or_uparc, or_lowarc, or_leftarc, or_text) 41 | self.play( 42 | Create(or_uparc), 43 | Create(or_lowarc), 44 | Create(or_leftarc), 45 | run_time = 1, 46 | ) 47 | self.play(Write(or_text)) 48 | self.add(OR_gate) 49 | self.wait() 50 | self.play(OR_gate.animate.move_to([-3,2,0]).scale(0.6)) 51 | self.wait() 52 | 53 | # NOT 54 | not_tri = Polygon([1 - np.sqrt(3),1,0],[1 - np.sqrt(3),-1,0],[1,0,0], color = WHITE) 55 | not_cir = Circle(radius = 0.2, color = WHITE).move_to([1.2,0,0]) 56 | not_text = Text("NOT").shift(DOWN*2) 57 | NOT_gate = Group(not_tri, not_cir, not_text) 58 | self.play( 59 | Create(not_tri), 60 | Create(not_cir), 61 | run_time = 1, 62 | ) 63 | self.play(Write(not_text)) 64 | self.add(NOT_gate) 65 | self.wait() 66 | self.play(NOT_gate.animate.move_to([3,2,0]).scale(0.6)) 67 | self.wait() 68 | 69 | # BUFFER 70 | buf_tri = Polygon([1 - np.sqrt(3),1,0],[1 - np.sqrt(3),-1,0],[1,0,0], color = WHITE) 71 | buf_text = Text("BUFFER").shift(DOWN*2) 72 | BUFFER = Group(buf_tri, buf_text) 73 | self.play( 74 | Create(buf_tri), 75 | run_time = 1, 76 | ) 77 | self.play(Write(buf_text)) 78 | self.add(BUFFER) 79 | self.wait() 80 | self.play(BUFFER.animate.move_to([6,2,0]).scale(0.6)) 81 | self.wait() 82 | 83 | # NAND 84 | nand_uphor = Line(start = [0,1,0], end = [-1,1,0]) 85 | nand_lowhor = Line(start = [0,-1,0], end = [-1,-1, 0]) 86 | nand_ver = Line(start = [-1,1,0], end = [-1,-1,0]) 87 | nand_arc = Arc(radius = 1.0, start_angle = -PI/2 , angle = PI) 88 | nand_cir = Circle(radius = 0.2, color = WHITE).move_to([1.2,0,0]) 89 | nand_text = Text("NAND").shift(DOWN*2) 90 | NAND_gate = Group(nand_uphor, nand_lowhor, nand_ver, nand_arc, nand_cir, nand_text) 91 | self.play( 92 | Create(nand_uphor), 93 | Create(nand_lowhor), 94 | Create(nand_ver), 95 | Create(nand_arc), 96 | Create(nand_cir), 97 | run_time = 1, 98 | ) 99 | self.play(Write(nand_text)) 100 | self.add(NAND_gate) 101 | self.wait() 102 | self.play(NAND_gate.animate.move_to([-6,-2,0]).scale(0.6)) 103 | self.wait() 104 | 105 | # NOR 106 | nor_uparc = ArcBetweenPoints(start = [-1,-1,0], end = [1,0,0], angle = PI/4) 107 | nor_lowarc = ArcBetweenPoints(start = [-1,1,0], end = [1,0,0], angle = -PI/4) 108 | nor_leftarc = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3) 109 | nor_cir = Circle(radius = 0.2, color = WHITE).move_to([1.2,0,0]) 110 | nor_text = Text("NOR").shift(DOWN*2) 111 | NOR_gate = Group(nor_uparc, nor_lowarc, nor_leftarc, nor_cir, nor_text) 112 | self.play( 113 | Create(nor_uparc), 114 | Create(nor_lowarc), 115 | Create(nor_leftarc), 116 | Create(nor_cir), 117 | run_time = 1, 118 | ) 119 | self.play(Write(nor_text)) 120 | self.add(NOR_gate) 121 | self.wait() 122 | self.play(NOR_gate.animate.move_to([-3,-2,0]).scale(0.6)) 123 | self.wait() 124 | 125 | # XOR 126 | xor_uparc = ArcBetweenPoints(start = [-1,-1,0], end = [1,0,0], angle = PI/4) 127 | xor_lowarc = ArcBetweenPoints(start = [-1,1,0], end = [1,0,0], angle = -PI/4) 128 | xor_leftarc = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3) 129 | xor_leftarc2 = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3).shift(LEFT*0.2) 130 | xor_text = Text("XOR").shift(DOWN*2) 131 | XOR_gate = Group(xor_uparc, xor_lowarc, xor_leftarc, xor_leftarc2, xor_text) 132 | self.play( 133 | Create(xor_uparc), 134 | Create(xor_lowarc), 135 | Create(xor_leftarc), 136 | Create(xor_leftarc2), 137 | run_time = 1, 138 | ) 139 | self.play(Write(xor_text)) 140 | self.add(XOR_gate) 141 | self.wait() 142 | self.play(XOR_gate.animate.move_to([3,-2,0]).scale(0.6)) 143 | self.wait() 144 | 145 | # XNOR 146 | xnor_uparc = ArcBetweenPoints(start = [-1,-1,0], end = [1,0,0], angle = PI/4) 147 | xnor_lowarc = ArcBetweenPoints(start = [-1,1,0], end = [1,0,0], angle = -PI/4) 148 | xnor_leftarc = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3) 149 | xnor_leftarc2 = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3).shift(LEFT*0.2) 150 | xnor_cir = Circle(radius = 0.2, color = WHITE).move_to([1.2,0,0]) 151 | xnor_text = Text("XNOR").shift(DOWN*2) 152 | XNOR_gate = Group(xnor_leftarc, xnor_leftarc2, xnor_uparc, xnor_lowarc, xnor_cir, xnor_text) 153 | self.play( 154 | Create(xnor_uparc), 155 | Create(xnor_lowarc), 156 | Create(xnor_leftarc), 157 | Create(xnor_leftarc2), 158 | Create(xnor_cir), 159 | run_time = 1, 160 | ) 161 | self.play(Write(xnor_text)) 162 | self.add(XNOR_gate) 163 | self.wait() 164 | self.play(XNOR_gate.animate.move_to([6,-2,0]).scale(0.6)) 165 | self.wait(3) 166 | self.play( 167 | FadeOut(AND_gate), 168 | FadeOut(OR_gate), 169 | FadeOut(NOT_gate), 170 | FadeOut(BUFFER), 171 | FadeOut(NAND_gate), 172 | FadeOut(NOR_gate), 173 | FadeOut(XOR_gate), 174 | FadeOut(XNOR_gate), 175 | ) 176 | self.wait() 177 | 178 | 179 | 180 | class AndGate(Scene): 181 | def construct(self): 182 | 183 | # Create AND gate 184 | and_uphor = Line(start = [0,1,0], end = [-1,1,0]) 185 | and_lowhor = Line(start = [0,-1,0], end = [-1,-1, 0]) 186 | and_ver = Line(start = [-1,1,0], end = [-1,-1,0]) 187 | and_arc = Arc(radius = 1.0, start_angle = -PI/2 , angle = PI) 188 | self.play(Create(and_lowhor), Create(and_uphor), Create(and_ver), Create(and_arc)) 189 | 190 | # Create input and output wires 191 | wireA = Line(start = [-1,0.7,0], end = [-2,0.7,0]) 192 | wireB = Line(start = [-1,-0.7,0], end = [-2,-0.7,0]) 193 | wireO = Line(start = [1,0,0], end = [2,0,0]) 194 | AND_gate = Group(and_lowhor, and_uphor, and_ver, and_arc, wireA, wireB, wireO) 195 | self.play(Create(wireA), Create(wireB), Create(wireO)) 196 | self.add(AND_gate) 197 | self.play(ApplyMethod(AND_gate.shift, LEFT*3)) 198 | 199 | # wire values 200 | oneA = Text("1", color = RED).next_to(wireA.get_end(), direction = LEFT) 201 | zeroA = Text("0").next_to(wireA.get_end(), direction = LEFT) 202 | oneB = Text("1", color = RED).next_to(wireB.get_end(), direction = LEFT) 203 | zeroB = Text("0").next_to(wireB.get_end(), direction = LEFT) 204 | oneB_2 = oneB.copy() 205 | zeroB_2 = zeroB.copy() 206 | oneO = Text("1", color = RED).next_to(wireO.get_end(), direction = RIGHT) 207 | zeroO = Text("0").next_to(wireO.get_end(), direction = RIGHT) 208 | textA = Text("A", color = BLUE).next_to(zeroA, direction = LEFT) 209 | textB = Text("B", color = BLUE).next_to(zeroB, direction = LEFT) 210 | textO = Text("O", color = BLUE_D).next_to(zeroO, direction = RIGHT) 211 | self.play(Write(textA), Write(textB), Write(textO)) 212 | self.play(Write(zeroA), Write(zeroB), Write(zeroO)) 213 | 214 | # Truth table 215 | AND_table = Table( 216 | [ 217 | ["0","0","0"], 218 | ["0","1","0"], 219 | ["1","0","0"], 220 | ["1","1","1"] 221 | ], 222 | col_labels = [Text("A", color = BLUE), Text("B", color = BLUE), Text("O", color = BLUE_D)], 223 | include_outer_lines = True, 224 | ).shift(RIGHT*4) 225 | self.play(Create(AND_table), run_time = 1) 226 | self.wait() 227 | 228 | # 00 229 | self.play(Indicate(AND_table.get_rows()[1][0:3]), run_time = 1) 230 | self.wait() 231 | 232 | # 01 233 | self.play( 234 | ApplyMethod(wireB.set_color, RED, run_time = 0.1), 235 | ReplacementTransform(zeroB, oneB, run_time = 0.1), 236 | Indicate(AND_table.get_rows()[2][0:3], run_time = 1), 237 | ) 238 | self.wait() 239 | 240 | # 10 241 | self.play( 242 | ApplyMethod(wireA.set_color, RED, run_time = 0.1), 243 | ApplyMethod(wireB.set_color, WHITE, run_time = 0.1), 244 | ReplacementTransform(zeroA, oneA, run_time = 0.1), 245 | ReplacementTransform(oneB, zeroB_2, run_time = 0.1), 246 | Indicate(AND_table.get_rows()[3][0:3], run_time = 1), 247 | ) 248 | self.wait() 249 | 250 | # 11 251 | self.play( 252 | ApplyMethod(wireB.set_color, RED, run_time = 0.1), 253 | ApplyMethod(wireO.set_color, RED, run_time = 0.1), 254 | ReplacementTransform(zeroB_2, oneB_2, run_time = 0.1), 255 | ReplacementTransform(zeroO, oneO, run_time = 0.1), 256 | Indicate(AND_table.get_rows()[4][0:3], run_time = 1), 257 | ) 258 | self.wait() 259 | 260 | self.play( 261 | Uncreate(AND_table), 262 | Uncreate(and_arc), 263 | Uncreate(and_lowhor), 264 | Uncreate(and_uphor), 265 | Uncreate(and_ver), 266 | Uncreate(wireA), 267 | Uncreate(wireB), 268 | Uncreate(wireO), 269 | Uncreate(textA), 270 | Uncreate(textB), 271 | Uncreate(textO), 272 | Uncreate(oneA), 273 | Uncreate(oneB_2), 274 | Uncreate(oneO), 275 | ) 276 | self.wait() 277 | 278 | 279 | 280 | class OrGate(Scene): 281 | def construct(self): 282 | 283 | # Create OR gate 284 | or_uparc = ArcBetweenPoints(start = [-1,-1,0], end = [1,0,0], angle = PI/4) 285 | or_lowarc = ArcBetweenPoints(start = [-1,1,0], end = [1,0,0], angle = -PI/4) 286 | or_leftarc = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3) 287 | self.play(Create(or_uparc), Create(or_lowarc), Create(or_leftarc)) 288 | 289 | # Create input and output wires 290 | wireA = Line(start = [-0.88,0.7,0], end = [-2,0.7,0]) 291 | wireB = Line(start = [-0.88,-0.7,0], end = [-2,-0.7,0]) 292 | wireO = Line(start = [1,0,0], end = [2,0,0]) 293 | OR_gate = Group(or_uparc, or_lowarc, or_leftarc, wireA, wireB, wireO) 294 | self.play(Create(wireA), Create(wireB), Create(wireO)) 295 | self.add(OR_gate) 296 | self.play(ApplyMethod(OR_gate.shift, LEFT*3)) 297 | 298 | # wire values 299 | oneA = Text("1", color = RED).next_to(wireA.get_end(), direction = LEFT) 300 | zeroA = Text("0").next_to(wireA.get_end(), direction = LEFT) 301 | oneB = Text("1", color = RED).next_to(wireB.get_end(), direction = LEFT) 302 | zeroB = Text("0").next_to(wireB.get_end(), direction = LEFT) 303 | oneB_2 = oneB.copy() 304 | zeroB_2 = zeroB.copy() 305 | oneO = Text("1", color = RED).next_to(wireO.get_end(), direction = RIGHT) 306 | zeroO = Text("0").next_to(wireO.get_end(), direction = RIGHT) 307 | textA = Text("A", color = BLUE).next_to(zeroA, direction = LEFT) 308 | textB = Text("B", color = BLUE).next_to(zeroB, direction = LEFT) 309 | textO = Text("O", color = BLUE_D).next_to(zeroO, direction = RIGHT) 310 | self.play(Write(textA), Write(textB), Write(textO)) 311 | self.play(Write(zeroA), Write(zeroB), Write(zeroO)) 312 | 313 | # Truth table 314 | OR_table = Table( 315 | [ 316 | ["0","0","0"], 317 | ["0","1","1"], 318 | ["1","0","1"], 319 | ["1","1","1"] 320 | ], 321 | col_labels = [Text("A", color = BLUE), Text("B", color = BLUE), Text("O", color = BLUE_D)], 322 | include_outer_lines = True, 323 | ).shift(RIGHT*4) 324 | self.play(Create(OR_table), run_time = 1) 325 | self.wait() 326 | 327 | # 00 328 | self.play(Indicate(OR_table.get_rows()[1][0:3]), run_time = 1) 329 | self.wait() 330 | 331 | # 01 332 | self.play( 333 | ApplyMethod(wireB.set_color, RED, run_time = 0.1), 334 | ApplyMethod(wireO.set_color, RED, run_time = 0.1), 335 | ReplacementTransform(zeroB, oneB, run_time = 0.1), 336 | ReplacementTransform(zeroO, oneO, run_time = 0.1), 337 | Indicate(OR_table.get_rows()[2][0:3], run_time = 1), 338 | ) 339 | self.wait() 340 | 341 | # 10 342 | self.play( 343 | ApplyMethod(wireA.set_color, RED, run_time = 0.1), 344 | ApplyMethod(wireB.set_color, WHITE, run_time = 0.1), 345 | ReplacementTransform(zeroA, oneA, run_time = 0.1), 346 | ReplacementTransform(oneB, zeroB_2, run_time = 0.1), 347 | Indicate(OR_table.get_rows()[3][0:3], run_time = 1), 348 | ) 349 | self.wait() 350 | 351 | # 11 352 | self.play( 353 | ApplyMethod(wireB.set_color, RED, run_time = 0.1), 354 | ReplacementTransform(zeroB_2, oneB_2, run_time = 0.1), 355 | Indicate(OR_table.get_rows()[4][0:3], run_time = 1), 356 | ) 357 | self.wait() 358 | 359 | self.play( 360 | Uncreate(OR_table), 361 | Uncreate(or_leftarc), 362 | Uncreate(or_lowarc), 363 | Uncreate(or_uparc), 364 | Uncreate(wireA), 365 | Uncreate(wireB), 366 | Uncreate(wireO), 367 | Uncreate(textA), 368 | Uncreate(textB), 369 | Uncreate(textO), 370 | Uncreate(oneA), 371 | Uncreate(oneB_2), 372 | Uncreate(oneO), 373 | ) 374 | self.wait() 375 | 376 | 377 | 378 | class NotGate(Scene): 379 | def construct(self): 380 | 381 | # Create NOT Gate 382 | not_tri = Polygon([1 - np.sqrt(3),1,0],[1 - np.sqrt(3),-1,0],[1,0,0], color = WHITE) 383 | not_cir = Circle(radius = 0.2, color = WHITE).move_to([1.2,0,0]) 384 | self.play(Create(not_tri), Create(not_cir)) 385 | 386 | # Create input and output wires 387 | wireA = Line(start = [1 - np.sqrt(3), 0,0], end = [-2,0,0]) 388 | wireO = Line(start = [1.4,0,0], end = [2,0,0], color = RED) 389 | NOT_gate = Group(not_tri, not_cir, wireA, wireO) 390 | self.play(Create(wireA), Create(wireO)) 391 | self.add(NOT_gate) 392 | self.play(ApplyMethod(NOT_gate.shift, LEFT*3)) 393 | 394 | # wire values 395 | oneA = Text("1", color = RED).next_to(wireA.get_end(), direction = LEFT) 396 | zeroA = Text("0").next_to(wireA.get_end(), direction = LEFT) 397 | oneO = Text("1", color = RED).next_to(wireO.get_end(), direction = RIGHT) 398 | zeroO = Text("0").next_to(wireO.get_end(), direction = RIGHT) 399 | textA = Text("A", color = BLUE).next_to(zeroA, direction = LEFT) 400 | textO = Text("O", color = BLUE_D).next_to(zeroO, direction = RIGHT) 401 | self.play(Write(textA), Write(textO)) 402 | self.play(Write(zeroA), Write(oneO)) 403 | 404 | # Truth table 405 | NOT_table = Table( 406 | [ 407 | ["0","1"], 408 | ["1","0"] 409 | ], 410 | col_labels = [Text("A", color = BLUE), Text("O", color = BLUE_D)], 411 | include_outer_lines = True, 412 | ).shift(RIGHT*4) 413 | self.play(Create(NOT_table), run_time = 1) 414 | self.wait() 415 | 416 | # 0 417 | self.play(Indicate(NOT_table.get_rows()[1][0:2]), run_time = 1) 418 | self.wait() 419 | 420 | # 1 421 | self.play( 422 | ApplyMethod(wireA.set_color, RED , run_time = 0.1), 423 | ApplyMethod(wireO.set_color, WHITE, run_time = 0.1), 424 | ReplacementTransform(zeroA, oneA, run_time = 0.1), 425 | ReplacementTransform(oneO, zeroO, run_time = 0.1), 426 | Indicate(NOT_table.get_rows()[2][0:2], run_time = 1), 427 | ) 428 | self.wait() 429 | 430 | self.play( 431 | Uncreate(NOT_table), 432 | Uncreate(not_tri), 433 | Uncreate(not_cir), 434 | Uncreate(wireA), 435 | Uncreate(wireO), 436 | Uncreate(textA), 437 | Uncreate(textO), 438 | Uncreate(oneA), 439 | Uncreate(zeroO), 440 | ) 441 | self.wait() 442 | 443 | 444 | 445 | class Buffer(Scene): 446 | def construct(self): 447 | 448 | # Create BUFFER 449 | buff_tri = Polygon([1 - np.sqrt(3),1,0],[1 - np.sqrt(3),-1,0],[1,0,0], color = WHITE) 450 | self.play(Create(buff_tri)) 451 | 452 | # Create input and output wires 453 | wireA = Line(start = [1 - np.sqrt(3), 0,0], end = [-2,0,0]) 454 | wireO = Line(start = [1,0,0], end = [2,0,0]) 455 | BUFFER = Group(buff_tri, wireA, wireO) 456 | self.play(Create(wireA), Create(wireO)) 457 | self.add(BUFFER) 458 | self.play(ApplyMethod(BUFFER.shift, LEFT*3)) 459 | 460 | # wire values 461 | oneA = Text("1", color = RED).next_to(wireA.get_end(), direction = LEFT) 462 | zeroA = Text("0").next_to(wireA.get_end(), direction = LEFT) 463 | oneO = Text("1", color = RED).next_to(wireO.get_end(), direction = RIGHT) 464 | zeroO = Text("0").next_to(wireO.get_end(), direction = RIGHT) 465 | textA = Text("A", color = BLUE).next_to(zeroA, direction = LEFT) 466 | textO = Text("O", color = BLUE_D).next_to(zeroO, direction = RIGHT) 467 | self.play(Write(textA), Write(textO)) 468 | self.play(Write(zeroA), Write(zeroO)) 469 | 470 | # Truth table 471 | BUFFER_table = Table( 472 | [ 473 | ["0","0"], 474 | ["1","1"] 475 | ], 476 | col_labels = [Text("A", color = BLUE), Text("O", color = BLUE_D)], 477 | include_outer_lines = True, 478 | ).shift(RIGHT*4) 479 | self.play(Create(BUFFER_table), run_time = 1) 480 | self.wait() 481 | 482 | # 0 483 | self.play(Indicate(BUFFER_table.get_rows()[1][0:2]), run_time = 1) 484 | self.wait() 485 | 486 | # 1 487 | self.play( 488 | ApplyMethod(wireA.set_color, RED , run_time = 0.1), 489 | ApplyMethod(wireO.set_color, RED, run_time = 0.1), 490 | ReplacementTransform(zeroA, oneA, run_time = 0.1), 491 | ReplacementTransform(zeroO, oneO, run_time = 0.1), 492 | Indicate(BUFFER_table.get_rows()[2][0:2], run_time = 1), 493 | ) 494 | self.wait() 495 | 496 | self.play( 497 | Uncreate(BUFFER_table), 498 | Uncreate(buff_tri), 499 | Uncreate(wireA), 500 | Uncreate(wireO), 501 | Uncreate(textA), 502 | Uncreate(textO), 503 | Uncreate(oneA), 504 | Uncreate(oneO), 505 | ) 506 | self.wait() 507 | 508 | 509 | 510 | class NandGate(Scene): 511 | def construct(self): 512 | 513 | 514 | # And 515 | and_uphor = Line(start = [0,1,0], end = [-1,1,0]).shift(LEFT*2) 516 | and_lowhor = Line(start = [0,-1,0], end = [-1,-1, 0]).shift(LEFT*2) 517 | and_ver = Line(start = [-1,1,0], end = [-1,-1,0]).shift(LEFT*2) 518 | and_arc = Arc(radius = 1.0, start_angle = -PI/2 , angle = PI).shift(LEFT*2) 519 | # Not 520 | not_tri = Polygon([1 - np.sqrt(3),1,0],[1 - np.sqrt(3),-1,0],[1,0,0], color = WHITE).shift(RIGHT*2) 521 | not_cir = Circle(radius = 0.2, color = WHITE).move_to([1.2,0,0]).shift(RIGHT*2) 522 | plus_sign = Text("+") 523 | self.play( 524 | Create(and_lowhor), 525 | Create(and_uphor), 526 | Create(and_ver), 527 | Create(and_arc), 528 | Create(not_tri), 529 | Create(not_cir), 530 | FadeIn(plus_sign), 531 | ) 532 | self.wait() 533 | self.play( 534 | Uncreate(not_tri, run_time = 0.2), 535 | ApplyMethod(and_lowhor.shift, RIGHT*2), 536 | ApplyMethod(and_uphor.shift, RIGHT*2), 537 | ApplyMethod(and_ver.shift, RIGHT*2), 538 | ApplyMethod(and_arc.shift, RIGHT*2), 539 | ApplyMethod(not_cir.shift, LEFT*2), 540 | FadeOut(plus_sign, run_time = 0.2), 541 | ) 542 | self.wait() 543 | 544 | 545 | # Create input and output wires 546 | wireA = Line(start = [-1,0.7,0], end = [-2,0.7,0]) 547 | wireB = Line(start = [-1,-0.7,0], end = [-2,-0.7,0]) 548 | wireO = Line(start = [1.4,0,0], end = [2,0,0], color = RED) 549 | NAND_gate = Group(and_lowhor, and_uphor, and_ver, and_arc, not_cir, wireA, wireB, wireO) 550 | self.play(Create(wireA), Create(wireB), Create(wireO)) 551 | self.add(NAND_gate) 552 | self.play(ApplyMethod(NAND_gate.shift, LEFT*3)) 553 | 554 | # wire values 555 | oneA = Text("1", color = RED).next_to(wireA.get_end(), direction = LEFT) 556 | zeroA = Text("0").next_to(wireA.get_end(), direction = LEFT) 557 | oneB = Text("1", color = RED).next_to(wireB.get_end(), direction = LEFT) 558 | zeroB = Text("0").next_to(wireB.get_end(), direction = LEFT) 559 | oneB_2 = oneB.copy() 560 | zeroB_2 = zeroB.copy() 561 | oneO = Text("1", color = RED).next_to(wireO.get_end(), direction = RIGHT) 562 | zeroO = Text("0").next_to(wireO.get_end(), direction = RIGHT) 563 | textA = Text("A", color = BLUE).next_to(zeroA, direction = LEFT) 564 | textB = Text("B", color = BLUE).next_to(zeroB, direction = LEFT) 565 | textO = Text("O", color = BLUE_D).next_to(zeroO, direction = RIGHT) 566 | self.play(Write(textA), Write(textB), Write(textO)) 567 | self.play(Write(zeroA), Write(zeroB), Write(oneO)) 568 | 569 | # Truth table 570 | NAND_table = Table( 571 | [ 572 | ["0","0","1"], 573 | ["0","1","1"], 574 | ["1","0","1"], 575 | ["1","1","0"] 576 | ], 577 | col_labels = [Text("A", color = BLUE), Text("B", color = BLUE), Text("O", color = BLUE_D)], 578 | include_outer_lines = True, 579 | ).shift(RIGHT*4) 580 | self.play(Create(NAND_table), run_time = 1) 581 | self.wait() 582 | 583 | # 00 584 | self.play(Indicate(NAND_table.get_rows()[1][0:3]), run_time = 1) 585 | self.wait() 586 | 587 | # 01 588 | self.play( 589 | ApplyMethod(wireB.set_color, RED , run_time = 0.1), 590 | ReplacementTransform(zeroB, oneB, run_time = 0.1), 591 | Indicate(NAND_table.get_rows()[2][0:3], run_time = 1), 592 | ) 593 | self.wait() 594 | 595 | # 10 596 | self.play( 597 | ApplyMethod(wireA.set_color, RED, run_time = 0.1), 598 | ApplyMethod(wireB.set_color, WHITE, run_time = 0.1), 599 | ReplacementTransform(zeroA, oneA, run_time = 0.1), 600 | ReplacementTransform(oneB, zeroB_2, run_time = 0.1), 601 | Indicate(NAND_table.get_rows()[3][0:3], run_time = 1), 602 | ) 603 | self.wait() 604 | 605 | # 11 606 | self.play( 607 | ApplyMethod(wireB.set_color, RED, run_time = 0.1), 608 | ApplyMethod(wireO.set_color, WHITE, run_time = 0.1), 609 | ReplacementTransform(zeroB_2, oneB_2, run_time = 0.1), 610 | ReplacementTransform(oneO, zeroO, run_time = 0.1), 611 | Indicate(NAND_table.get_rows()[4][0:3], run_time = 1), 612 | ) 613 | self.wait() 614 | 615 | self.play( 616 | Uncreate(NAND_table), 617 | Uncreate(and_arc), 618 | Uncreate(and_lowhor), 619 | Uncreate(and_uphor), 620 | Uncreate(and_ver), 621 | Uncreate(not_cir), 622 | Uncreate(wireA), 623 | Uncreate(wireB), 624 | Uncreate(wireO), 625 | Uncreate(textA), 626 | Uncreate(textB), 627 | Uncreate(textO), 628 | Uncreate(oneA), 629 | Uncreate(oneB_2), 630 | Uncreate(zeroO), 631 | ) 632 | self.wait() 633 | 634 | 635 | 636 | class NorGate(Scene): 637 | def construct(self): 638 | 639 | # Or 640 | or_uparc = ArcBetweenPoints(start = [-1,-1,0], end = [1,0,0], angle = PI/4).shift(LEFT*2) 641 | or_lowarc = ArcBetweenPoints(start = [-1,1,0], end = [1,0,0], angle = -PI/4).shift(LEFT*2) 642 | or_leftarc = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3).shift(LEFT*2) 643 | # Not 644 | not_tri = Polygon([1 - np.sqrt(3),1,0],[1 - np.sqrt(3),-1,0],[1,0,0], color = WHITE).shift(RIGHT*2) 645 | not_cir = Circle(radius = 0.2, color = WHITE).move_to([1.2,0,0]).shift(RIGHT*2) 646 | plus_sign = Text("+") 647 | self.play( 648 | Create(or_uparc), 649 | Create(or_lowarc), 650 | Create(or_leftarc), 651 | Create(not_tri), 652 | Create(not_cir), 653 | FadeIn(plus_sign), 654 | ) 655 | self.wait() 656 | self.play( 657 | Uncreate(not_tri, run_time = 0.2), 658 | ApplyMethod(or_uparc.shift, RIGHT*2), 659 | ApplyMethod(or_lowarc.shift, RIGHT*2), 660 | ApplyMethod(or_leftarc.shift, RIGHT*2), 661 | ApplyMethod(not_cir.shift, LEFT*2), 662 | FadeOut(plus_sign, run_time = 0.2), 663 | ) 664 | self.wait() 665 | 666 | 667 | # Create input and output wires 668 | wireA = Line(start = [-0.88,0.7,0], end = [-2,0.7,0]) 669 | wireB = Line(start = [-0.88,-0.7,0], end = [-2,-0.7,0]) 670 | wireO = Line(start = [1.4,0,0], end = [2,0,0], color = RED) 671 | NOR_gate = Group(or_lowarc, or_uparc, or_leftarc, not_cir, wireA, wireB, wireO) 672 | self.play(Create(wireA), Create(wireB), Create(wireO)) 673 | self.add(NOR_gate) 674 | self.play(ApplyMethod(NOR_gate.shift, LEFT*3)) 675 | 676 | # wire values 677 | oneA = Text("1", color = RED).next_to(wireA.get_end(), direction = LEFT) 678 | zeroA = Text("0").next_to(wireA.get_end(), direction = LEFT) 679 | oneB = Text("1", color = RED).next_to(wireB.get_end(), direction = LEFT) 680 | zeroB = Text("0").next_to(wireB.get_end(), direction = LEFT) 681 | oneB_2 = oneB.copy() 682 | zeroB_2 = zeroB.copy() 683 | oneO = Text("1", color = RED).next_to(wireO.get_end(), direction = RIGHT) 684 | zeroO = Text("0").next_to(wireO.get_end(), direction = RIGHT) 685 | textA = Text("A", color = BLUE).next_to(zeroA, direction = LEFT) 686 | textB = Text("B", color = BLUE).next_to(zeroB, direction = LEFT) 687 | textO = Text("O", color = BLUE_D).next_to(zeroO, direction = RIGHT) 688 | self.play(Write(textA), Write(textB), Write(textO)) 689 | self.play(Write(zeroA), Write(zeroB), Write(oneO)) 690 | 691 | # Truth table 692 | NOR_table = Table( 693 | [ 694 | ["0","0","1"], 695 | ["0","1","0"], 696 | ["1","0","0"], 697 | ["1","1","0"] 698 | ], 699 | col_labels = [Text("A", color = BLUE), Text("B", color = BLUE), Text("O", color = BLUE_D)], 700 | include_outer_lines = True, 701 | ).shift(RIGHT*4) 702 | self.play(Create(NOR_table), run_time = 1) 703 | self.wait() 704 | 705 | # 00 706 | self.play(Indicate(NOR_table.get_rows()[1][0:3]), run_time = 1) 707 | self.wait() 708 | 709 | # 01 710 | self.play( 711 | ApplyMethod(wireB.set_color, RED , run_time = 0.1), 712 | ApplyMethod(wireO.set_color, WHITE, run_time = 0.1), 713 | ReplacementTransform(zeroB, oneB, run_time = 0.1), 714 | ReplacementTransform(oneO, zeroO, run_time = 0.1), 715 | Indicate(NOR_table.get_rows()[2][0:3], run_time = 1), 716 | ) 717 | self.wait() 718 | 719 | # 10 720 | self.play( 721 | ApplyMethod(wireA.set_color, RED, run_time = 0.1), 722 | ApplyMethod(wireB.set_color, WHITE, run_time = 0.1), 723 | ReplacementTransform(zeroA, oneA, run_time = 0.1), 724 | ReplacementTransform(oneB, zeroB_2, run_time = 0.1), 725 | Indicate(NOR_table.get_rows()[3][0:3], run_time = 1), 726 | ) 727 | self.wait() 728 | 729 | # 11 730 | self.play( 731 | ApplyMethod(wireB.set_color, RED, run_time = 0.1), 732 | ReplacementTransform(zeroB_2, oneB_2, run_time = 0.1), 733 | Indicate(NOR_table.get_rows()[4][0:3], run_time = 1), 734 | ) 735 | self.wait() 736 | 737 | self.play( 738 | Uncreate(NOR_table), 739 | Uncreate(or_leftarc), 740 | Uncreate(or_lowarc), 741 | Uncreate(or_uparc), 742 | Uncreate(not_cir), 743 | Uncreate(wireA), 744 | Uncreate(wireB), 745 | Uncreate(wireO), 746 | Uncreate(textA), 747 | Uncreate(textB), 748 | Uncreate(textO), 749 | Uncreate(oneA), 750 | Uncreate(oneB_2), 751 | Uncreate(zeroO), 752 | ) 753 | self.wait() 754 | 755 | 756 | 757 | class XorGate(Scene): 758 | def construct(self): 759 | # Create XOR gate 760 | xor_uparc = ArcBetweenPoints(start = [-1,-1,0], end = [1,0,0], angle = PI/4) 761 | xor_lowarc = ArcBetweenPoints(start = [-1,1,0], end = [1,0,0], angle = -PI/4) 762 | xor_leftarc = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3) 763 | xor_leftarc2 = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3).shift(LEFT*0.2) 764 | self.play(Create(xor_uparc), Create(xor_lowarc), Create(xor_leftarc), Create(xor_leftarc2)) 765 | 766 | # Create input and output wires 767 | wireA = Line(start = [-1.08,0.7,0], end = [-2,0.7,0]) 768 | wireB = Line(start = [-1.08,-0.7,0], end = [-2,-0.7,0]) 769 | wireO = Line(start = [1,0,0], end = [2,0,0]) 770 | XOR_gate = Group(xor_uparc, xor_lowarc, xor_leftarc, xor_leftarc2, wireA, wireB, wireO) 771 | self.play(Create(wireA), Create(wireB), Create(wireO)) 772 | self.add(XOR_gate) 773 | self.play(ApplyMethod(XOR_gate.shift, LEFT*3)) 774 | 775 | # wire values 776 | oneA = Text("1", color = RED).next_to(wireA.get_end(), direction = LEFT) 777 | zeroA = Text("0").next_to(wireA.get_end(), direction = LEFT) 778 | oneB = Text("1", color = RED).next_to(wireB.get_end(), direction = LEFT) 779 | zeroB = Text("0").next_to(wireB.get_end(), direction = LEFT) 780 | oneB_2 = oneB.copy() 781 | zeroB_2 = zeroB.copy() 782 | oneO = Text("1", color = RED).next_to(wireO.get_end(), direction = RIGHT) 783 | zeroO = Text("0").next_to(wireO.get_end(), direction = RIGHT) 784 | zeroO_2 = zeroO.copy() 785 | textA = Text("A", color = BLUE).next_to(zeroA, direction = LEFT) 786 | textB = Text("B", color = BLUE).next_to(zeroB, direction = LEFT) 787 | textO = Text("O", color = BLUE_D).next_to(zeroO, direction = RIGHT) 788 | self.play(Write(textA), Write(textB), Write(textO)) 789 | self.play(Write(zeroA), Write(zeroB), Write(zeroO)) 790 | 791 | # Truth table 792 | XOR_table = Table( 793 | [ 794 | ["0","0","0"], 795 | ["0","1","1"], 796 | ["1","0","1"], 797 | ["1","1","0"] 798 | ], 799 | col_labels = [Text("A", color = BLUE), Text("B", color = BLUE), Text("O", color = BLUE_D)], 800 | include_outer_lines = True, 801 | ).shift(RIGHT*4) 802 | self.play(Create(XOR_table), run_time = 1) 803 | self.wait() 804 | 805 | # 00 806 | self.play(Indicate(XOR_table.get_rows()[1][0:3]), run_time = 1) 807 | self.wait() 808 | 809 | # 01 810 | self.play( 811 | ApplyMethod(wireB.set_color, RED, run_time = 0.1), 812 | ApplyMethod(wireO.set_color, RED, run_time = 0.1), 813 | ReplacementTransform(zeroB, oneB, run_time = 0.1), 814 | ReplacementTransform(zeroO, oneO, run_time = 0.1), 815 | Indicate(XOR_table.get_rows()[2][0:3], run_time = 1), 816 | ) 817 | self.wait() 818 | 819 | # 10 820 | self.play( 821 | ApplyMethod(wireA.set_color, RED, run_time = 0.1), 822 | ApplyMethod(wireB.set_color, WHITE, run_time = 0.1), 823 | ReplacementTransform(zeroA, oneA, run_time = 0.1), 824 | ReplacementTransform(oneB, zeroB_2, run_time = 0.1), 825 | Indicate(XOR_table.get_rows()[3][0:3], run_time = 1), 826 | ) 827 | self.wait() 828 | 829 | # 11 830 | self.play( 831 | ApplyMethod(wireB.set_color, RED , run_time = 0.1), 832 | ApplyMethod(wireO.set_color, WHITE, run_time = 0.1), 833 | ReplacementTransform(zeroB_2, oneB_2, run_time = 0.1), 834 | ReplacementTransform(oneO, zeroO_2, run_time = 0.1), 835 | Indicate(XOR_table.get_rows()[4][0:3], run_time = 1), 836 | ) 837 | self.wait() 838 | 839 | self.play( 840 | Uncreate(XOR_table), 841 | Uncreate(xor_leftarc), 842 | Uncreate(xor_leftarc2), 843 | Uncreate(xor_lowarc), 844 | Uncreate(xor_uparc), 845 | Uncreate(wireA), 846 | Uncreate(wireB), 847 | Uncreate(wireO), 848 | Uncreate(textA), 849 | Uncreate(textB), 850 | Uncreate(textO), 851 | Uncreate(oneA), 852 | Uncreate(oneB_2), 853 | Uncreate(zeroO_2), 854 | ) 855 | self.wait() 856 | 857 | 858 | 859 | class XnorGate(Scene): 860 | def construct(self): 861 | 862 | # Xor 863 | xor_uparc = ArcBetweenPoints(start = [-1,-1,0], end = [1,0,0], angle = PI/4).shift(LEFT*2) 864 | xor_lowarc = ArcBetweenPoints(start = [-1,1,0], end = [1,0,0], angle = -PI/4).shift(LEFT*2) 865 | xor_leftarc = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3).shift(LEFT*2) 866 | xor_leftarc2 = ArcBetweenPoints(start = [-1,1,0], end = [-1,-1,0], angle = -PI/3).shift(LEFT*2.2) 867 | # Not 868 | not_tri = Polygon([1 - np.sqrt(3),1,0],[1 - np.sqrt(3),-1,0],[1,0,0], color = WHITE).shift(RIGHT*2) 869 | not_cir = Circle(radius = 0.2, color = WHITE).move_to([1.2,0,0]).shift(RIGHT*2) 870 | plus_sign = Text("+") 871 | self.play( 872 | Create(xor_uparc), 873 | Create(xor_lowarc), 874 | Create(xor_leftarc), 875 | Create(xor_leftarc2), 876 | Create(not_tri), 877 | Create(not_cir), 878 | FadeIn(plus_sign), 879 | ) 880 | self.wait() 881 | self.play( 882 | Uncreate(not_tri, run_time = 0.2), 883 | ApplyMethod(xor_uparc.shift, RIGHT*2), 884 | ApplyMethod(xor_lowarc.shift, RIGHT*2), 885 | ApplyMethod(xor_leftarc.shift, RIGHT*2), 886 | ApplyMethod(xor_leftarc2.shift, RIGHT*2), 887 | ApplyMethod(not_cir.shift, LEFT*2), 888 | FadeOut(plus_sign, run_time = 0.2), 889 | ) 890 | self.wait() 891 | 892 | 893 | # Create input and output wires 894 | wireA = Line(start = [-1.08,0.7,0], end = [-2,0.7,0]) 895 | wireB = Line(start = [-1.08,-0.7,0], end = [-2,-0.7,0]) 896 | wireO = Line(start = [1.4,0,0], end = [2,0,0], color = RED) 897 | NOR_gate = Group(xor_lowarc, xor_uparc, xor_leftarc, xor_leftarc2, not_cir, wireA, wireB, wireO) 898 | self.play(Create(wireA), Create(wireB), Create(wireO)) 899 | self.add(NOR_gate) 900 | self.play(ApplyMethod(NOR_gate.shift, LEFT*3)) 901 | 902 | # wire values 903 | oneA = Text("1", color = RED).next_to(wireA.get_end(), direction = LEFT) 904 | zeroA = Text("0").next_to(wireA.get_end(), direction = LEFT) 905 | oneB = Text("1", color = RED).next_to(wireB.get_end(), direction = LEFT) 906 | zeroB = Text("0").next_to(wireB.get_end(), direction = LEFT) 907 | oneB_2 = oneB.copy() 908 | zeroB_2 = zeroB.copy() 909 | oneO = Text("1", color = RED).next_to(wireO.get_end(), direction = RIGHT) 910 | oneO_2 = oneO.copy() 911 | zeroO = Text("0").next_to(wireO.get_end(), direction = RIGHT) 912 | textA = Text("A", color = BLUE).next_to(zeroA, direction = LEFT) 913 | textB = Text("B", color = BLUE).next_to(zeroB, direction = LEFT) 914 | textO = Text("O", color = BLUE_D).next_to(zeroO, direction = RIGHT) 915 | self.play(Write(textA), Write(textB), Write(textO)) 916 | self.play(Write(zeroA), Write(zeroB), Write(oneO)) 917 | 918 | # Truth table 919 | XNOR_table = Table( 920 | [ 921 | ["0","0","1"], 922 | ["0","1","0"], 923 | ["1","0","0"], 924 | ["1","1","1"] 925 | ], 926 | col_labels = [Text("A", color = BLUE), Text("B", color = BLUE), Text("O", color = BLUE_D)], 927 | include_outer_lines = True, 928 | ).shift(RIGHT*4) 929 | self.play(Create(XNOR_table), run_time = 1) 930 | self.wait() 931 | 932 | # 00 933 | self.play(Indicate(XNOR_table.get_rows()[1][0:3]), run_time = 1) 934 | self.wait() 935 | 936 | # 01 937 | self.play( 938 | ApplyMethod(wireB.set_color, RED , run_time = 0.1), 939 | ApplyMethod(wireO.set_color, WHITE, run_time = 0.1), 940 | ReplacementTransform(zeroB, oneB, run_time = 0.1), 941 | ReplacementTransform(oneO, zeroO, run_time = 0.1), 942 | Indicate(XNOR_table.get_rows()[2][0:3], run_time = 1), 943 | ) 944 | self.wait() 945 | 946 | # 10 947 | self.play( 948 | ApplyMethod(wireA.set_color, RED, run_time = 0.1), 949 | ApplyMethod(wireB.set_color, WHITE, run_time = 0.1), 950 | ReplacementTransform(zeroA, oneA, run_time = 0.1), 951 | ReplacementTransform(oneB, zeroB_2, run_time = 0.1), 952 | Indicate(XNOR_table.get_rows()[3][0:3], run_time = 1), 953 | ) 954 | self.wait() 955 | 956 | # 11 957 | self.play( 958 | ApplyMethod(wireB.set_color, RED, run_time = 0.1), 959 | ApplyMethod(wireO.set_color, RED, run_time = 0.1), 960 | ReplacementTransform(zeroB_2, oneB_2, run_time = 0.1), 961 | ReplacementTransform(zeroO, oneO_2, run_time = 0.1), 962 | Indicate(XNOR_table.get_rows()[4][0:3], run_time = 1), 963 | ) 964 | self.wait() 965 | 966 | self.play( 967 | Uncreate(XNOR_table), 968 | Uncreate(xor_leftarc2), 969 | Uncreate(xor_leftarc), 970 | Uncreate(xor_lowarc), 971 | Uncreate(xor_uparc), 972 | Uncreate(not_cir), 973 | Uncreate(wireA), 974 | Uncreate(wireB), 975 | Uncreate(wireO), 976 | Uncreate(textA), 977 | Uncreate(textB), 978 | Uncreate(textO), 979 | Uncreate(oneA), 980 | Uncreate(oneB_2), 981 | Uncreate(oneO_2), 982 | ) 983 | self.wait() 984 | --------------------------------------------------------------------------------