{"id":426615,"date":"2024-07-18T21:00:04","date_gmt":"2024-07-18T21:00:04","guid":{"rendered":"http:\/\/savepearlharbor.com\/?p=426615"},"modified":"-0001-11-30T00:00:00","modified_gmt":"-0001-11-29T21:00:00","slug":"","status":"publish","type":"post","link":"https:\/\/savepearlharbor.com\/?p=426615","title":{"rendered":"<span>\u0418\u0441\u043f\u043e\u043b\u044c\u0437\u043e\u0432\u0430\u043d\u0438\u0435 Manim + Python \u0434\u043b\u044f \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438. \u041f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 (\u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u0438\u043a\u0430)<\/span>"},"content":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><strong><em>\u0412\u043c\u0435\u0441\u0442\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f<\/em><\/strong><\/p>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430\u00a0\u0442\u043e, \u0447\u0442\u043e\u00a0\u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u00a0\u2014 \u044d\u0442\u043e \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u0439 \u0430\u043d\u0434\u0435\u0440\u0433\u0440\u0430\u0443\u043d\u0434, \u0440\u0430\u0431\u043e\u0442\u044b 3Blue1Brown \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u043b\u044f\u044e\u0442 \u0438 \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0430\u044e\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u0447\u0442\u043e\u2011\u0442\u043e \u0438\u0437\u00a0\u0434\u0430\u043b\u0451\u043a\u043e\u0433\u043e \u0434\u0435\u0442\u0441\u0442\u0432\u0430, \u0433\u0434\u0435 \u0432\u0435\u0441\u044c \u043c\u0438\u0440\u00a0\u0431\u044b\u043b \u043d\u0435\u043f\u043e\u0441\u0442\u0438\u0436\u0438\u043c\u043e\u0439 \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u043e\u0439, \u0430\u00a0\u0438\u0437\u00a0\u043a\u0438\u0441\u043b\u043e\u0433\u043e\u00a0\u0431\u044b\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0443\u0440\u0430\u0432\u044c\u0438\u043d\u044b\u0435 \u0436\u043e\u043f\u043a\u0438. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u2011\u0442\u043e \u043f\u0440\u0438\u043a\u043e\u0441\u043d\u0443\u0442\u044c\u0441\u044f \u043a\u00a0\u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e\u043c\u0443. \u0422\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u0447\u0442\u043e <a href=\"https:\/\/habr.com\/ru\/companies\/ruvds\/news\/591147\/\" rel=\"noopener noreferrer nofollow\"><strong>\u0413\u0440\u0430\u043d\u0442 \u0421\u0430\u043d\u0434\u0435\u0440\u0441\u043e\u043d<\/strong><\/a> \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0434\u043b\u044f\u00a0\u044d\u0442\u043e\u0433\u043e \u0446\u0435\u043b\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0438 \u0431\u0435\u0437\u0432\u043e\u0437\u043c\u0435\u0437\u0434\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043b \u0435\u0451 \u043d\u0430\u043c, \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u043c \u043a\u043e\u0434\u0435\u0440\u0430\u043c \u0441\u043e \u0432\u0441\u0435\u0433\u043e \u043c\u0438\u0440\u0430.<\/p>\n<p><strong><em>\u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 Manim<\/em><\/strong><\/p>\n<p>\u0415\u0441\u0442\u044c \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 <a href=\"https:\/\/www.manim.community\" rel=\"noopener noreferrer nofollow\">\u0441\u0430\u0439\u0442 \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 \u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438<\/a> \u043e\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430. \u0418 \u0432 \u0440\u0443-\u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0435, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0425\u0430\u0431\u0440\u0435, \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u044b [<a href=\"https:\/\/habr.com\/ru\/articles\/821743\/\" rel=\"noopener noreferrer nofollow\">1<\/a>, <a href=\"https:\/\/habr.com\/ru\/companies\/yandex_praktikum\/articles\/578910\/\" rel=\"noopener noreferrer nofollow\">2<\/a>, <a href=\"https:\/\/habr.com\/ru\/companies\/skillfactory\/articles\/556944\/\" rel=\"noopener noreferrer nofollow\">3<\/a>]. \u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0436\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0448\u044c, \u0447\u0442\u043e \u043c\u0430\u043b\u043e \u043e\u0431\u0443\u0447\u0430\u043b\u043e\u043a \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e 39 \u0442\u044b\u0441\u044f\u0447 \u0437\u0432\u0451\u0437\u0434 <em>Github<\/em>. \u0421 \u0432\u044f\u0437\u0438 \u0441 \u0447\u0435\u043c, \u043e-\u043e-\u043e\u0447\u0435\u043d\u044c \u0440\u0430\u0434\u0443\u0435\u0442, \u0447\u0442\u043e <em>chatGPT<\/em> \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0443\u043c\u0435\u0435\u0442 \u0432 <em>Manim<\/em> \u0438 \u0441\u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u043c \u043f\u043e\u043c\u043e\u0447\u044c \u043f\u043e\u0447\u0442\u0438 \u0441 \u043b\u044e\u0431\u044b\u043c \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c.<\/p>\n<p><strong><em>\u0412\u044b\u0431\u043e\u0440 \u0442\u0435\u043c\u044b<\/em><\/strong><\/p>\n<p>\u0426\u0435\u043b\u044c \u0440\u0430\u0431\u043e\u0442\u044b\u00a0\u2014 \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u044e \u043d\u0430\u00a0\u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u043e\u043f\u0438\u043a\u0430. \u0412\u00a0\u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0447\u0442\u043e\u2011\u0442\u043e \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0435 \u0434\u043b\u044f <s>\u043f\u0430\u0446\u0430\u043d\u043e\u0432 \u0441\u00a0\u0440\u0430\u0439\u043e\u043d\u0430<\/s> \u0441\u0440\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430. \u0410\u00a0\u0442\u0430\u043a \u043a\u0430\u043a\u00a0\u044f \u0438 \u0441\u0430\u043c \u0441\u0435\u0439\u0447\u0430\u0441 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u044e\u0441\u044c \u0441\u00a0\u043c\u0430\u0442\u0441\u0442\u0430\u0442\u043e\u043c, \u0442\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u0438\u043a\u0430 \u043f\u0440\u0438\u0448\u043b\u0430 \u0432\u00a0\u0433\u043e\u043b\u043e\u0432\u0443 \u043f\u043e\u0447\u0442\u0438 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e. \u0422\u0430\u043c, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043f\u043e\u043b\u0435 \u043d\u0435\u043f\u0430\u0445\u0430\u043d\u043e\u0435 \u0432\u00a0\u043f\u043b\u0430\u043d\u0435 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0432\u0437\u044f\u043b \u0441\u0430\u043c\u043e\u0435 \u0431\u0430\u0437\u043e\u0432\u043e\u0435. \u0415\u0441\u043b\u0438 \u0442\u0435\u043c\u0430 \u0437\u0430\u0439\u0434\u0451\u0442, \u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0443 \u0432\u00a0\u0442\u043e\u043c\u00a0\u0436\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438, \u0430\u00a0\u0435\u0441\u043b\u0438 \u043d\u0435\u00a0\u0437\u0430\u0439\u0434\u0451\u0442.. \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0443, \u043d\u043e\u00a0\u0443\u0436\u0435 \u0433\u0440\u0443\u0441\u0442\u043d\u0435\u0435.<\/p>\n<p><strong><em>\u041a\u043e\u0434<\/em><\/strong><\/p>\n<p>\u0412\u0435\u0441\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0431\u0440\u0430\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/RomanBashmakov\/Manim_Permutations_Habr.git\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>. \u0422\u0430\u043a \u0436\u0435 \u043d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430  <a href=\"https:\/\/drive.google.com\/drive\/folders\/1j0EM7nMGM1K_BHbN04ACtWfzl4K_e_7W?usp=share_link\" rel=\"noopener noreferrer nofollow\">\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/a> \u0434\u043b\u044f <em>python&#8217;\u0430<\/em>.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043a\u0440\u0438\u043f\u0442 \u0446\u0435\u043b\u0438\u043a\u043e\u043c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import os import shutil from manim import * import copy  shutil.rmtree(os.path.join('media')) os.mkdir('media')  def make_mobs (mob_type) -> list:     mobs = list()     for x in np.nditer(mob_type):         if x == 0:              mobs.append(SVGMobject(\"cucumber.svg\"))         elif x == 1:             mobs.append(SVGMobject(\"plum.svg\"))         elif x == 2:             mobs.append(SVGMobject(\"lemo.svg\"))         elif x == 3:             mobs.append(SVGMobject(\"apple_red.svg\"))     return mobs   def moveAlongPath(mobject_1, mobject_2, movingCameraScene, f_up_down) -> Dot:     dot = Dot().move_to(mobject_1)     path = Line(mobject_1.get_center(), mobject_2.get_center(),stroke_opacity=0.5).set_opacity(0)     if f_up_down:         path.points[1:3] += UP*2     else:         path.points[1:3] -= UP*2      mobject_1.save_state()     def update_rotate_move(mob,alpha):         mobject_1.restore()         mobject_1.move_to(path.point_from_proportion(alpha))         mobject_1.rotate(2*PI*alpha)      movingCameraScene.play(             UpdateFromAlphaFunc(mobject_1,update_rotate_move),             run_time = 1         )     return dot  def swapMobs(mobject_1, mobject_2, movingCameraScene):      mobject_1.save_state()     mobject_2.save_state()      dot_1 = Dot().move_to(mobject_1)     dot_2 = Dot().move_to(mobject_2)      def update_rotate_move_up(mob,alpha):         mob.restore()         path = Line(dot_1.get_center(), dot_2.get_center(),stroke_opacity=0.5).set_opacity(0)         path.points[1:3] += UP*2         mob.move_to(path.point_from_proportion(alpha))         mob.rotate(2*PI*alpha)      def update_rotate_move_down(mob,alpha):         mob.restore()         path = Line(dot_2.get_center(), dot_1.get_center(),stroke_opacity=0.5).set_opacity(0)         path.points[1:3] -= UP*2         mob.move_to(path.point_from_proportion(alpha))         mob.rotate(2*PI*alpha)      movingCameraScene.play(             AnimationGroup(                 UpdateFromAlphaFunc(mobject_1, update_rotate_move_up),                 UpdateFromAlphaFunc(mobject_2, update_rotate_move_down),                 run_time = 1             )         )  def placeInLine (mobs, rows, cols, x_step, y_step):     for i, mob in enumerate(mobs):         row = i \/\/ cols         col = i % cols         mob.move_to(np.array([col * x_step - (cols-1) * x_step \/ 2,                                  -(row * y_step) + (rows-1) * y_step \/ 2, 0]))          def playReplaceMobs (movingCameraScene, mobs_1, mobs_2):     for i, mob_1 in enumerate(mobs_1):         movingCameraScene.play(Transform(mobs_1[i], mobs_2[i]))  def placeGrid(movingCameraScene):     # \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0435\u0442\u043a\u0443 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438     grid = NumberPlane(         x_range=[-100, 100, 1],   # \u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u043f\u043e \u043e\u0441\u0438 X: \u043e\u0442 -10 \u0434\u043e 10 \u0441 \u0448\u0430\u0433\u043e\u043c 1         y_range=[-100, 100, 1],   # \u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u043f\u043e \u043e\u0441\u0438 Y: \u043e\u0442 -10 \u0434\u043e 10 \u0441 \u0448\u0430\u0433\u043e\u043c 1         background_line_style = {             \"stroke_color\": BLUE,     # \u0426\u0432\u0435\u0442 \u043b\u0438\u043d\u0438\u0439 \u0441\u0435\u0442\u043a\u0438             \"stroke_width\": 1,        # \u0422\u043e\u043b\u0449\u0438\u043d\u0430 \u043b\u0438\u043d\u0438\u0439 \u0441\u0435\u0442\u043a\u0438             \"stroke_opacity\": 0.6     # \u041f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c \u043b\u0438\u043d\u0438\u0439 \u0441\u0435\u0442\u043a\u0438         }     )     # \u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043e\u0441\u0438     grid.axes.set_color(BLUE).set(stroke_width = 0.5, stroke_opacity = 0.6)  # \u0426\u0432\u0435\u0442 \u043e\u0441\u0435\u0439      # \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0435\u0442\u043a\u0443 \u043d\u0430 \u0441\u0446\u0435\u043d\u0443     movingCameraScene.add(grid)     grid.remove(grid.x_axis, grid.y_axis)  def showEverithing(group, movingCameraScene):     # \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430 \u043a\u0430\u043c\u0435\u0440\u044b \u043f\u043e \u0448\u0438\u0440\u0438\u043d\u0435 \u0438 \u0432\u044b\u0441\u043e\u0442\u0435     scale_width = movingCameraScene.camera.frame_width \/ group.width     scale_height = movingCameraScene.camera.frame_height \/ group.height      # \u0412\u044b\u0431\u043e\u0440 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0435\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430 \u0434\u043b\u044f \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438, \u0447\u0442\u043e \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u0432 \u043a\u0430\u0434\u0440     optimal_scale = min(scale_width, scale_height)      # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0448\u0438\u0440\u0438\u043d\u044b \u0438 \u0432\u044b\u0441\u043e\u0442\u044b \u043a\u0430\u0434\u0440\u0430 \u043a\u0430\u043c\u0435\u0440\u044b     movingCameraScene.play(movingCameraScene.camera.frame.animate.set(width = movingCameraScene.camera.frame_width \/ optimal_scale * 1.3))     movingCameraScene.play(movingCameraScene.camera.frame.animate.move_to(group))       #============================================================================================================ ############################################################################################################# ############################################################################################################# #============================================================================================================ class Permutations(MovingCameraScene):     def construct(self):         self.camera.background_color = GREY_BROWN          placeGrid(self)          # \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432         mob_type = np.array([0, 1, 2, 3])         mobs = make_mobs(mob_type)         mobs_2 = make_mobs(mob_type)          # \u0420\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c mobs \u043f\u043e \u0441\u0435\u0442\u043a\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e         placeInLine(mobs, 5, 1, 0, 2.1)                      # \u0420\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c mobs_2 \u043f\u043e \u0441\u0435\u0442\u043a\u0435 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e         placeInLine(mobs_2, 1, 5, 1.3, 0)          # \u0413\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u043c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b         grid = VGroup(*mobs).scale(0.5)         # \u0413\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u043c \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b         grid_2 = VGroup(*mobs_2).next_to(grid.get_top(), UP).scale(0.5)          # \u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432         self.play(self.camera.frame.animate.move_to(grid).set(height = grid.height * 1.1))         self.play(Create(grid))                  group = VGroup(grid, grid_2)          showEverithing(group, self)          # \u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043d\u0430 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435         playReplaceMobs(self, mobs, mobs_2)          self.remove(grid)         self.play(grid_2.animate.move_to(self.camera.frame.get_top()))          self.play(self.camera.frame.animate.move_to(grid_2))         self.play(self.camera.frame.animate.set(width = grid_2.width * 2.0))          swapMobs(grid_2[0], grid_2[3], self)         swapMobs(grid_2[1], grid_2[2], self)         swapMobs(grid_2[0], grid_2[1], self)         swapMobs(grid_2[2], grid_2[3], self)         swapMobs(grid_2[1], grid_2[2], self)         swapMobs(grid_2[0], grid_2[1], self)         swapMobs(grid_2[2], grid_2[3], self)          self.wait(2) #============================================================================================================ ############################################################################################################# ############################################################################################################# #============================================================================================================ class Permutations_2(MovingCameraScene):     def construct(self):         self.camera.background_color = GREY_BROWN          placeGrid(self)          # \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432         list_of_grids = list() #\u0441\u043f\u0438\u0441\u043e\u043a grids'\u043e\u0432           mob_type = np.array([0, 1, 2, 3])         mobs_1 = make_mobs(mob_type)         mobs_2 = make_mobs(mob_type)          # \u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0444\u0440\u0443\u043a\u0442\u044b-\u043e\u0432\u043e\u0449\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e         placeInLine(mobs_1, 4, 1, 0, 1.5)         grid_1 = VGroup(*mobs_1).scale(0.5)         list_of_grids.append(grid_1)                  # \u0421\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u044d\u043a\u0440\u0430\u043d         self.play(self.camera.frame.animate.move_to(grid_1).set(height = grid_1.height * 1.1))         self.play(Create(grid_1))          # \u041f\u0435\u0440\u0432\u044b\u0439 \u0441\u043b\u043e\u0439         placeInLine(mobs_2, 4, 1, 0, 8)         grid_2 = VGroup(*mobs_2).scale(1).next_to(grid_1, RIGHT * 5)         list_of_grids.append(grid_2)          showEverithing(VGroup(*list_of_grids), self)          # \u0420\u0430\u0441\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u043b\u043e\u0439         self.play(             AnimationGroup(                 TransformFromCopy(mobs_1[0], mobs_2[0]),                 TransformFromCopy(mobs_1[1], mobs_2[1]),                 TransformFromCopy(mobs_1[2], mobs_2[2]),                 TransformFromCopy(mobs_1[3], mobs_2[3]),                 run_time = 1             )         )          self.wait(0.3)  #============================================================================================================ # \u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u043b\u043e\u0439 #============================================================================================================         mobs_3 = []         for i in range(0,4):             mobs_i = make_mobs(mob_type)             inner_mob_list = []             for n in range(0,4):                 if n != i:                     inner_mob_list.append(mobs_i[n])             mobs_3.append(inner_mob_list)              placeInLine(mobs_3[i], 4, 1, 0, 3)             list_of_grids.append(VGroup(*mobs_3[i]).scale(0.75).next_to(mobs_2[i]))          showEverithing(VGroup(*list_of_grids), self)          for i in range(0,4):             c = 0             for n in range(0,4):                 if n != i:                     self.play(TransformFromCopy(mobs_1[n], mobs_3[i][c]), run_time = 0.5)                     path = Line(mobs_2[i].get_center(), mobs_3[i][c].get_center(),stroke_opacity=0.5).set_opacity(0.5)                     self.play(Create(path), run_time = 0.1)                     c += 1         self.wait(0.3)  #============================================================================================================ # \u0422\u0440\u0435\u0442\u0438\u0439 \u0441\u043b\u043e\u0439 #============================================================================================================         mobs_4 = [[[]]]                  mob_list_1_lvl = [] #\u041a\u043e\u043b-\u0432\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 4         c = 0         for i in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u044f             cc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u043e\u0435             mob_list_2_lvl = [] #\u041a\u043e\u043b-\u0432\u043e \u0432\u0442\u043e\u0440\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 3             for n in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043b\u043e\u044f                 if (n != i):                     ccc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u043c \u0441\u043b\u043e\u0435                     mob_list_3_lvl = [] #\u041a\u043e\u043b-\u0432\u043e \u0442\u0440\u0435\u0442\u044c\u0438\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 2                     for k in range(0,4): # \u041f\u0435\u0440\u0435\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f                         mobs_i = make_mobs(mob_type) #\u043d\u0430\u0431\u043e\u0440-\u0434\u043e\u043d\u043e\u0440                         if (k != i) and (k != n):                             mob_list_3_lvl.append(mobs_i[k])                             ccc += 1                     placeInLine(mob_list_3_lvl, 3, 1, 0, 2)                     this_group = VGroup(*mob_list_3_lvl).scale(0.5)                     this_group.next_to(mobs_3[i][cc])                      mob_list_2_lvl.append(mob_list_3_lvl)                     cc += 1             mob_list_1_lvl.append(mob_list_2_lvl)             c += 1          c = 0         for i in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u044f             cc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u043e\u0435             for n in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043b\u043e\u044f                 if (n != i):                     ccc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u043c \u0441\u043b\u043e\u0435                     for k in range(0,4): # \u041f\u0435\u0440\u0435\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f                         if (k != i) and (k != n):                             path = Line(mob_list_1_lvl[c][cc][ccc].get_center(), mobs_3[i][cc].get_center(),stroke_opacity=0.5).set_opacity(0.5)                             self.add(path)                             self.play(TransformFromCopy(mobs_i[k], mob_list_1_lvl[c][cc][ccc]), run_time = 0.3)                             ccc += 1                     cc += 1             c += 1  #============================================================================================================ # \u0427\u0435\u0442\u0432\u0435\u0440\u0442\u044b\u0439 \u0441\u043b\u043e\u0439 #============================================================================================================         mob_list_1_lvl_4 = [] #\u041a\u043e\u043b-\u0432\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 4         c = 0         for i in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u044f             cc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u043e\u0435             mob_list_2_lvl_4 = [] #\u041a\u043e\u043b-\u0432\u043e \u0432\u0442\u043e\u0440\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 3             for n in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043b\u043e\u044f                 if (n != i):                     ccc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u043c \u0441\u043b\u043e\u0435                     mob_list_3_lvl_4 = [] #\u041a\u043e\u043b-\u0432\u043e \u0442\u0440\u0435\u0442\u044c\u0438\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 2                     for k in range(0,4): # \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0441\u043b\u043e\u044f                         if (k != i) and (k != n):                             cccc = 0                             mob_list_4_lvl_4 = [] #\u041a\u043e\u043b-\u0432\u043e \u0442\u0440\u0435\u0442\u044c\u0438\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 2                             for p in range(0, 4):                                 mobs_i = make_mobs(mob_type) #\u043d\u0430\u0431\u043e\u0440-\u0434\u043e\u043d\u043e\u0440                                 if (p != i) and (p != n) and (p != k):                                     mob_list_4_lvl_4.append(mobs_i[p])                                     cccc += 1                             placeInLine(mob_list_4_lvl_4, 2, 1, 0, 2)                             this_group = VGroup(*mob_list_4_lvl_4).scale(0.5)                             this_group.next_to(mob_list_1_lvl[c][cc][ccc])                             mob_list_3_lvl_4.append(mob_list_4_lvl_4)                             # self.add(this_group)                             # self.wait(0.1)                             ccc += 1                     mob_list_2_lvl_4.append(mob_list_3_lvl_4)                     cc += 1             mob_list_1_lvl_4.append(mob_list_2_lvl_4)             c += 1          c = 0         for i in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u044f             cc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u043e\u0435             for n in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043b\u043e\u044f                 if (n != i):                     ccc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u043c \u0441\u043b\u043e\u0435                     for k in range(0,4): # \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0441\u043b\u043e\u044f                         if (k != i) and (k != n):                             cccc = 0                             for p in range(0, 4):                                 if (p != i) and (p != n) and (p != k):                                     path = Line(mob_list_1_lvl_4[c][cc][ccc][cccc].get_center(), mob_list_1_lvl[c][cc][ccc].get_center(),stroke_opacity=0.5).set_opacity(0.5)                                     self.add(path)                                     self.play(TransformFromCopy(mobs_1[p], mob_list_1_lvl_4[c][cc][ccc][cccc]), run_time = 0.3)                                     self.wait(0.1)                                     cccc += 1                             ccc += 1                     cc += 1             c += 1   #============================================================================================================ ############################################################################################################# ############################################################################################################# #============================================================================================================ class Permutations_3(MovingCameraScene):     def construct(self):         self.camera.background_color = GREY_BROWN          placeGrid(self)          # \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432         list_of_grids = list() #\u0441\u043f\u0438\u0441\u043e\u043a grids'\u043e\u0432           mob_type = np.array([0, 1, 2, 3])         mobs_1 = make_mobs(mob_type)         mobs_2 = make_mobs(mob_type)          # \u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0444\u0440\u0443\u043a\u0442\u044b-\u043e\u0432\u043e\u0449\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e         placeInLine(mobs_1, 4, 1, 0, 1.5)         grid_1 = VGroup(*mobs_1).scale(0.5)         list_of_grids.append(grid_1)                  # \u0421\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u044d\u043a\u0440\u0430\u043d         self.play(self.camera.frame.animate.move_to(grid_1).set(height = grid_1.height * 1.1))         self.play(Create(grid_1))         # self.add(grid_1)          # \u041f\u0435\u0440\u0432\u044b\u0439 \u0441\u043b\u043e\u0439         placeInLine(mobs_2, 4, 1, 0, 8)         grid_2 = VGroup(*mobs_2).scale(1).next_to(grid_1, RIGHT * 5)         list_of_grids.append(grid_2)          showEverithing(VGroup(*list_of_grids), self)          # \u0420\u0430\u0441\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u043b\u043e\u0439         self.play(             AnimationGroup(                 TransformFromCopy(mobs_1[0], mobs_2[0]),                 TransformFromCopy(mobs_1[1], mobs_2[1]),                 TransformFromCopy(mobs_1[2], mobs_2[2]),                 TransformFromCopy(mobs_1[3], mobs_2[3]),                 run_time = 1             )         )          self.wait(0.3)  #============================================================================================================ # \u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u043b\u043e\u0439 #============================================================================================================         mobs_3 = []         for i in range(0,4):             mobs_i = make_mobs(mob_type)             inner_mob_list = []             for n in range(0,4):                 if n != i:                     inner_mob_list.append(mobs_i[n])             mobs_3.append(inner_mob_list)              placeInLine(mobs_3[i], 4, 1, 0, 3)             list_of_grids.append(VGroup(*mobs_3[i]).scale(0.75).next_to(mobs_2[i]))          showEverithing(VGroup(*list_of_grids), self)          for i in range(0,4):             c = 0             for n in range(0,4):                 if n != i:                     self.play(TransformFromCopy(mobs_1[n], mobs_3[i][c]), run_time = 0.5)                     # self.add(mobs_3[i][c])                     path = Line(mobs_2[i].get_center(), mobs_3[i][c].get_center(),stroke_opacity=0.5).set_opacity(0.5)                     self.play(Create(path), run_time = 0.1)                     # self.add(path)                     c += 1         self.wait(0.3)  #============================================================================================================ # \u0422\u0440\u0435\u0442\u0438\u0439 \u0441\u043b\u043e\u0439 #============================================================================================================         mobs_4 = [[[]]]                  mob_list_1_lvl = [] #\u041a\u043e\u043b-\u0432\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 4         c = 0         for i in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u044f             cc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u043e\u0435             mob_list_2_lvl = [] #\u041a\u043e\u043b-\u0432\u043e \u0432\u0442\u043e\u0440\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 3             for n in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043b\u043e\u044f                 if (n != i):                     ccc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u043c \u0441\u043b\u043e\u0435                     mob_list_3_lvl = [] #\u041a\u043e\u043b-\u0432\u043e \u0442\u0440\u0435\u0442\u044c\u0438\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 2                     for k in range(0,4): # \u041f\u0435\u0440\u0435\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f                         mobs_i = make_mobs(mob_type) #\u043d\u0430\u0431\u043e\u0440-\u0434\u043e\u043d\u043e\u0440                         if (k != i) and (k != n):                             mob_list_3_lvl.append(mobs_i[k])                             ccc += 1                     placeInLine(mob_list_3_lvl, 3, 1, 0, 2)                     this_group = VGroup(*mob_list_3_lvl).scale(0.5)                     this_group.next_to(mobs_3[i][cc])                      mob_list_2_lvl.append(mob_list_3_lvl)                     cc += 1             mob_list_1_lvl.append(mob_list_2_lvl)             c += 1          c = 0         for i in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u044f             cc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u043e\u0435             for n in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043b\u043e\u044f                 if (n != i):                     ccc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u043c \u0441\u043b\u043e\u0435                     for k in range(0,4): # \u041f\u0435\u0440\u0435\u0431\u0440\u0430\u0442\u044c \u043a\u0430\u0436\u0434\u044b\u0439 \u044d\u043b\u0435\u043c\u0435\u043d\u0442 \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0443\u0440\u043e\u0432\u043d\u044f                         if (k != i) and (k != n):                             path = Line(mob_list_1_lvl[c][cc][ccc].get_center(), mobs_3[i][cc].get_center(),stroke_opacity=0.5).set_opacity(0.5)                             self.add(path)                             self.play(TransformFromCopy(mobs_i[k], mob_list_1_lvl[c][cc][ccc]), run_time = 0.3)                             # self.add(mob_list_1_lvl[c][cc][ccc])                             ccc += 1                     cc += 1             c += 1  #============================================================================================================ # \u0427\u0435\u0442\u0432\u0435\u0440\u0442\u044b\u0439 \u0441\u043b\u043e\u0439 #============================================================================================================         mob_list_1_lvl_4 = [] #\u041a\u043e\u043b-\u0432\u043e \u043f\u0435\u0440\u0432\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 4         c = 0         for i in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u044f             cc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u043e\u0435             mob_list_2_lvl_4 = [] #\u041a\u043e\u043b-\u0432\u043e \u0432\u0442\u043e\u0440\u044b\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 3             for n in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043b\u043e\u044f                 if (n != i):                     ccc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u043c \u0441\u043b\u043e\u0435                     mob_list_3_lvl_4 = [] #\u041a\u043e\u043b-\u0432\u043e \u0442\u0440\u0435\u0442\u044c\u0438\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 2                     for k in range(0,4): # \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0441\u043b\u043e\u044f                         if (k != i) and (k != n):                             cccc = 0                             mob_list_4_lvl_4 = [] #\u041a\u043e\u043b-\u0432\u043e \u0442\u0440\u0435\u0442\u044c\u0438\u0445 \u0443\u0440\u043e\u0432\u043d\u0435\u0439 = 2                             for p in range(0, 4):                                 mobs_i = make_mobs(mob_type) #\u043d\u0430\u0431\u043e\u0440-\u0434\u043e\u043d\u043e\u0440                                 if (p != i) and (p != n) and (p != k):                                     mob_list_4_lvl_4.append(mobs_i[p])                                     cccc += 1                             placeInLine(mob_list_4_lvl_4, 2, 1, 0, 2)                             this_group = VGroup(*mob_list_4_lvl_4).scale(0.5)                             this_group.next_to(mob_list_1_lvl[c][cc][ccc])                             mob_list_3_lvl_4.append(mob_list_4_lvl_4)                             ccc += 1                     mob_list_2_lvl_4.append(mob_list_3_lvl_4)                     cc += 1             mob_list_1_lvl_4.append(mob_list_2_lvl_4)             c += 1          c = 0         for i in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u043f\u0435\u0440\u0432\u043e\u0433\u043e \u0441\u043b\u043e\u044f             cc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432\u043e \u0432\u0442\u043e\u0440\u043e\u043c \u0441\u043b\u043e\u0435             for n in range(0,4): #\u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0432\u0442\u043e\u0440\u043e\u0433\u043e \u0441\u043b\u043e\u044f                 if (n != i):                     ccc = 0 # \u0441\u0447\u0435\u0442\u0447\u0438\u043a \u0434\u043e\u0431\u0430\u0432\u043b\u0435\u043d\u043d\u044b\u0445 \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u043e\u0432 \u0432 \u0442\u0440\u0435\u0442\u044c\u0435\u043c \u0441\u043b\u043e\u0435                     for k in range(0,4): # \u0437\u0430\u043f\u043e\u043b\u043d\u0438\u0442\u044c \u044d\u043b\u0435\u043c\u0435\u043d\u0442\u044b \u0442\u0440\u0435\u0442\u044c\u0435\u0433\u043e \u0441\u043b\u043e\u044f                         if (k != i) and (k != n):                             cccc = 0                             for p in range(0, 4):                                 if (p != i) and (p != n) and (p != k):                                     path = Line(mob_list_1_lvl_4[c][cc][ccc][cccc].get_center(), mob_list_1_lvl[c][cc][ccc].get_center(),stroke_opacity=0.5).set_opacity(0.5)                                     self.add(path)                                     self.play(TransformFromCopy(mobs_1[p], mob_list_1_lvl_4[c][cc][ccc][cccc]), run_time = 0.3)                                     # self.add(mob_list_1_lvl_4[c][cc][ccc][cccc])                                     self.wait(0.1)                                     cccc += 1                             ccc += 1                     cc += 1             c += 1  #============================================================================================================ # \u0424\u043e\u043a\u0443\u0441 \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0432\u0435\u0442\u043a\u0435 #============================================================================================================         mobs_to_show = []         mobs_to_show.append(mobs_2[0])         for i in range(0, 3):             mobs_to_show.append(mobs_3[0][i])             for n in range(0, 2):                 mobs_to_show.append(mob_list_1_lvl[0][i][n])                 for p in range(0, 1):                     mobs_to_show.append(mob_list_1_lvl_4[0][i][n][p])          focus_group = VGroup(*mobs_to_show)         self.play(self.camera.frame.animate.move_to(focus_group).set(width = focus_group.width * 1.3))         # self.wait(0.3)          # \u0412\u044b\u0434\u0435\u043b\u0438\u0442\u044c \u0444\u0440\u0443\u043a\u0442\u044b \u043d\u0430 \u043e\u0434\u043d\u043e\u0439 \u0432\u0435\u0442\u043a\u0435         framebox_1 = SurroundingRectangle(mobs_2[0], buff = .05, corner_radius=0.2)         framebox_2 = SurroundingRectangle(mobs_3[0][0], buff = .05, corner_radius=0.2)         framebox_3 = SurroundingRectangle(mob_list_1_lvl[0][0][0], buff = .05, corner_radius=0.2)         framebox_4 = SurroundingRectangle(mob_list_1_lvl_4[0][0][0][0], buff = .05, corner_radius=0.2)          self.add(framebox_1,framebox_2,framebox_3,framebox_4)         self.wait(0.3)  #============================================================================================================ # \u041e\u0442\u0434\u0435\u043b\u044c\u043d\u043e \u043a\u0430\u0436\u0434\u0430\u044f \u0432\u0435\u0442\u043a\u0430 #============================================================================================================         mobs_to_show_by_4_all = VGroup()         mobs_to_show_by_4 = []         mobs_to_show_by_4_lvl_1 = mobs_to_show_by_4.copy()         mobs_to_show_by_4_lvl_1.append((mobs_2[0]).copy())          for i in range(0, 3):             mobs_to_show_by_4_lvl_2 = []             mobs_to_show_by_4_lvl_2 = copy.deepcopy(mobs_to_show_by_4_lvl_1)             mobs_to_show_by_4_lvl_2.append(mobs_3[0][i].copy())              for n in range(0, 2):                 mobs_to_show_by_4_lvl_3 = []                 mobs_to_show_by_4_lvl_3 = copy.deepcopy(mobs_to_show_by_4_lvl_2)                 mobs_to_show_by_4_lvl_3.append(mob_list_1_lvl[0][i][n].copy())                  for p in range(0, 1):                     mobs_to_show_by_4_lvl_4 = []                     mobs_to_show_by_4_lvl_4 = copy.deepcopy(mobs_to_show_by_4_lvl_3)                     mobs_to_show_by_4_lvl_4.append(mob_list_1_lvl_4[0][i][n][p].copy())                      placeInLine(mobs_to_show_by_4_lvl_4, 1, 4, 2, 0)                     group_mobs_to_show_by_4 = VGroup(*(mobs_to_show_by_4_lvl_4)).scale(0.5)                     group_mobs_to_show_by_4.next_to(mob_list_1_lvl_4[0][i][n][p], RIGHT * 2)                      mobs_to_show_by_4_all.add(group_mobs_to_show_by_4)           focus_group.add(mobs_to_show_by_4_all)         self.play(self.camera.frame.animate.move_to(focus_group).set(width = focus_group.width * 1.3))         self.wait(1)          c = 0         for i in range(0, 3):              for n in range(0, 2):                  for p in range(0, 1):                     self.play(TransformFromCopy(mobs_2[0], mobs_to_show_by_4_all[c][0]))                     self.play(TransformFromCopy(mobs_3[0][i], mobs_to_show_by_4_all[c][1]))                     self.play(TransformFromCopy(mob_list_1_lvl[0][i][n], mobs_to_show_by_4_all[c][2]))                     self.play(TransformFromCopy(mob_list_1_lvl_4[0][i][n][p], mobs_to_show_by_4_all[c][3]))                     if c == 0:                         self.remove(framebox_1,framebox_2,framebox_3,framebox_4)                         self.wait(0.3)                     c += 1  #============================================================================================================ ############################################################################################################# ############################################################################################################# #============================================================================================================ class Permutations_4_Equations(MovingCameraScene):     def construct(self):         self.camera.background_color = GREY_BROWN          placeGrid(self)          text_1 = MarkupText(             \"Number of permutations \u2013 &lt;span color = 'Yellow' font_family = 'CMU Serif' font_style='italic'>N&lt;\/span>\", font_size= 250, font = 'Marker Felt', color = 'White'         )          self.play(self.camera.frame.animate.move_to(text_1).set(width = text_1.width * 1.5))          self.play(Create(text_1))          # self.add(index_labels(text_1))          self.wait(0.2)          matex_1 = MathTex(             r\"N = 4 \\times 3 \\times 2 \\times 1\",             font_size = 400         ).next_to(text_1, DOWN * 10)         matex_1[0][0].set_color(YELLOW)          self.play(self.camera.frame.animate.move_to(matex_1).set(width = matex_1.width * 1.5))         self.wait(0.2)          n_copy = copy.deepcopy(text_1[24])                  # Transform the copy and fade out the original         self.play(             AnimationGroup(                 Transform(n_copy, matex_1[0][0]),                 FadeOut(text_1[22:25]),                 run_time = 0.5             )         )          self.play(Create(matex_1[0][1]))         self.wait(0.2)          self.play(Create(matex_1[0][2:4]))         self.wait(0.2)          self.play(Create(matex_1[0][4:6]))         self.wait(0.2)          self.play(Create(matex_1[0][6:8]))         self.wait(0.2)          self.play(Create(matex_1[0][8:10]))         self.wait(0.2)          matex_2 = MathTex(             r\"N = 4!\",             font_size = 400         )          self.wait(0.2)          # \u041d\u0430\u0445\u043e\u0436\u0434\u0435\u043d\u0438\u0435 \u0442\u043e\u0447\u0435\u043a \u043f\u0440\u0438\u0432\u044f\u0437\u043a\u0438 (\u0432 \u0434\u0430\u043d\u043d\u043e\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0434\u043b\u044f \u0441\u0438\u043c\u0432\u043e\u043b\u0430 'a')         point_a_formula1 = matex_1[0][1].get_center()         point_a_formula2 = matex_2[0][1].get_center()                  # \u0421\u043c\u0435\u0449\u0435\u043d\u0438\u0435 \u0444\u043e\u0440\u043c\u0443\u043b\u044b 2 \u0442\u0430\u043a, \u0447\u0442\u043e\u0431\u044b 'N' \u0441\u043e\u0432\u043f\u0430\u043b \u0441 'N'         shift_vector = point_a_formula1 - point_a_formula2         matex_2.shift(shift_vector)          self.wait(0.2)         self.play(Transform(matex_1[0][2:10],matex_2[0][2:4]))         self.wait(0.2)          self.remove(n_copy)         self.play(matex_1.animate.shift(RIGHT * 9))         self.wait(0.2)<\/code><\/pre>\n<\/p>\n<\/div>\n<\/details>\n<p>\u0417\u0430\u043f\u0443\u0441\u043a \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043f\u0440\u043e\u0438\u0441\u0445\u043e\u0434\u0438\u0442 \u0441 \u043f\u043e\u043c\u043e\u0449\u044c\u044e \u043a\u043e\u043c\u0430\u043d\u0434\u044b:<\/p>\n<pre><code>manim -pqh manim_cnm.py Permutations_3 -r 1920,1080<\/code><\/pre>\n<ul>\n<li>\n<p>&#8212;<em>pqh<\/em> \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0433\u0440\u0430\u0444\u0438\u043a\u0443 \u0432\u044b\u0441\u043e\u043a\u043e\u0439 \u0447\u0435\u0442\u043a\u043e\u0441\u0442\u0438 (\u043c\u043e\u0436\u043d\u043e \u0443\u043a\u0430\u0437\u044b\u0432\u0430\u0442\u044c \u0438 &#8212;<em>pql<\/em>)<\/p>\n<\/li>\n<li>\n<p>\u0444\u043b\u0430\u0433 &#8212;<em>r<\/em> \u043e\u0431\u043e\u0437\u043d\u0430\u0447\u0430\u0435\u0442 \u0432\u044b\u0431\u043e\u0440 \u0440\u0430\u0437\u0440\u0435\u0448\u0435\u043d\u0438\u044f<\/p>\n<\/li>\n<\/ul>\n<p>\u0412 \u0441\u043a\u0440\u0438\u043f\u0442\u0435 \u043c\u043e\u0436\u043d\u043e \u0432\u044b\u0434\u0435\u043b\u0438\u0442\u044c 4 \u0431\u043b\u043e\u043a\u0430:<\/p>\n<ol>\n<li>\n<p>\u0438\u043c\u043f\u043e\u0440\u0442\u044b<\/p>\n<\/li>\n<li>\n<p>\u043e\u0447\u0438\u0441\u0442\u043a\u0430 \u043a\u0430\u0442\u0430\u043b\u043e\u0433\u0430 \u043e\u0442 \u0440\u0435\u0437\u0443\u043b\u044c\u0442\u0430\u0442\u043e\u0432 \u043f\u0440\u0435\u0434\u044b\u0434\u0443\u0449\u0438\u0445 \u0437\u0430\u043f\u0443\u0441\u043a\u043e\u0432<\/p>\n<\/li>\n<li>\n<p>\u0444\u0443\u043d\u043a\u0446\u0438\u0438<\/p>\n<\/li>\n<li>\n<p>\u043a\u043b\u0430\u0441\u0441\u044b \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0439, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u043c\u043e\u0451\u043c \u0441\u043b\u0443\u0447\u0430\u0435 \u0443\u043d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u044b \u043e\u0442 <em>movingCameraScene<\/em><\/p>\n<\/li>\n<\/ol>\n<p>\u0421\u043a\u0440\u0438\u043f\u0442 \u0438\u0441\u043f\u043e\u043b\u044c\u0437\u0443\u0435\u0442 <em>SVG<\/em> \u043e\u0431\u044a\u0435\u043a\u0442\u044b, \u043a\u043e\u0442\u043e\u0440\u044b\u0435 \u0432 \u0448\u0438\u0440\u043e\u043a\u043e\u043c \u0430\u0441\u0441\u043e\u0440\u0442\u0438\u043c\u0435\u043d\u0442\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u0435\u043d\u044b \u043d\u0430 \u0431\u0435\u0441\u043f\u043b\u0430\u0442\u043d\u044b\u0445 \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u0430\u0445. \u041d\u0443\u0436\u043d\u044b\u0435 \u043a\u0430\u0440\u0442\u0438\u043d\u043a\u0438 \u0434\u043b\u044f \u0440\u0430\u0431\u043e\u0442\u044b \u0441\u043a\u0440\u0438\u043f\u0442\u0430 \u043b\u0435\u0436\u0430\u0442 \u0442\u0430\u043c \u0436\u0435 \u0432 <a href=\"https:\/\/github.com\/RomanBashmakov\/Manim_Permutations_Habr.git\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>.<\/p>\n<p>\u041d\u0430\u0441\u043b\u0435\u0434\u043e\u0432\u0430\u043d\u0438\u0435 <em>movingCameraScene <\/em>\u043e\u0431\u043e\u0441\u043d\u043e\u0432\u0430\u043d\u043d\u043e \u043d\u0435\u043c\u043d\u043e\u0433\u043e \u0431\u043e\u043b\u0435\u0435 \u0448\u0438\u0440\u043e\u043a\u0438\u043c \u0444\u0443\u043d\u043a\u0446\u0438\u043e\u043d\u0430\u043b\u043e\u043c, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0434\u0432\u0438\u0433\u0430\u0442\u044c \u043a\u0430\u043c\u0435\u0440\u0443 \u0438 \u0440\u0430\u0441\u0441\u0442\u0430\u0432\u043b\u044f\u0442\u044c \u0430\u043a\u0446\u0435\u043d\u0442\u044b \u043d\u0430 \u043e\u0431\u044a\u0435\u043a\u0442\u0430\u0445.<\/p>\n<p>\u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u0440\u0430\u0437\u0431\u0438\u0442\u0430 \u043d\u0430 \u0447\u0435\u0442\u044b\u0440\u0435 \u043a\u043b\u0430\u0441\u0441\u0430. \u042d\u0442\u043e \u043f\u043e\u0437\u0432\u043e\u043b\u044f\u0435\u0442 \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u043e\u0442\u043b\u0430\u0436\u0438\u0432\u0430\u0442\u044c, \u043d\u043e \u043f\u0440\u0438 \u043d\u0435\u043e\u0431\u0445\u043e\u0434\u0438\u043c\u043e\u0441\u0442\u0438 \u043c\u043e\u0436\u043d\u043e \u043e\u0431\u044a\u0435\u0434\u0438\u043d\u0438\u0442\u044c. \u041d\u0443\u0436\u043d\u043e \u0443\u0447\u0438\u0442\u044b\u0432\u0430\u0442\u044c, \u0447\u0442\u043e \u0432\u0438\u0434\u0435\u043e \u0432 \u043f\u0430\u043f\u043a\u0435 <em>media\/videos<\/em> \u043a\u0430\u0436\u0434\u044b\u0439 \u0440\u0430\u0437 \u043f\u0435\u0440\u0435\u0442\u0438\u0440\u0430\u0435\u0442\u0441\u044f.<\/p>\n<p>\u0418\u0442\u043e\u0433\u043e\u0432\u044b\u0439 \u0432\u0430\u0440\u0438\u0430\u043d\u0442 \u043f\u043e\u043b\u0443\u0447\u0438\u0432\u0448\u0435\u0433\u043e\u0441\u044f \u0432\u0438\u0434\u0435\u043e \u0441 \u043e\u0431\u044a\u044f\u0441\u043d\u0435\u043d\u0438\u0435\u043c \u043f\u0435\u0440\u0435\u0441\u0442\u0430\u043d\u043e\u0432\u043e\u043a:<\/p>\n<div class=\"tm-iframe_temp\" data-src=\"https:\/\/embedd.srv.habr.com\/iframe\/669938daee339fd48b368065\" data-style=\"\" id=\"669938daee339fd48b368065\" width=\"\"><\/div>\n<p><strong><em>\u041c\u0438\u043d\u0443\u0441\u044b<\/em><\/strong><\/p>\n<ul>\n<li>\n<p><em>\u0412\u0440\u0435\u043c\u044f<\/em>. \u0414\u0430\u0436\u0435 \u043d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u0441\u043e\u0431\u0438\u0440\u0430\u0435\u0442\u0441\u044f \u0434\u043e\u0432\u043e\u043b\u044c\u043d\u043e \u0434\u043e\u043b\u0433\u043e. \u0421\u00a0\u0443\u0447\u0435\u0442\u043e\u043c \u043e\u0442\u043b\u0430\u0434\u043a\u0438, \u043d\u0430\u00a0\u043f\u0435\u0440\u0435\u0441\u0431\u043e\u0440\u043a\u0443 \u0430\u043d\u0438\u043c\u0430\u0446\u0438\u0438 \u0432\u00a0\u043e\u0431\u0449\u0435\u0439 \u0441\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u0438 \u0443\u0445\u043e\u0434\u044f\u0442 \u0446\u0435\u043b\u044b\u0435 \u0447\u0430\u0441\u044b. <strong>\u0415\u0421\u041b\u0418 \u041a\u0422\u041e\u2011\u0422\u041e \u0417\u041d\u0410\u0415\u0422 \u041a\u0410\u041a\u00a0\u0423\u0421\u041a\u041e\u0420\u0418\u0422\u042c, \u041f\u041e\u0416\u0410\u041b\u0423\u0419\u0421\u0422\u0410, \u0420\u0410\u0421\u0421\u041a\u0410\u0416\u0418\u0422\u0415<\/strong>. <\/p>\n<\/li>\n<li>\n<p><em>\u0421\u043b\u043e\u0436\u043d\u043e\u0441\u0442\u044c \u0434\u043b\u044f\u00a0\u043e\u0431\u044b\u0432\u0430\u0442\u0435\u043b\u044f<\/em>. \u0414\u0430\u0436\u0435 \u0442\u0430\u043a\u0443\u044e \u043f\u0440\u043e\u0441\u0442\u0443\u044e \u0442\u0435\u043c\u0443, \u043c\u043d\u0435 \u043a\u0430\u0436\u0435\u0442\u0441\u044f, \u044f \u0441\u043c\u043e\u0433 \u0440\u0430\u0441\u043a\u0440\u044b\u0442\u044c \u043d\u0430\u00a0\u0442\u0440\u043e\u0435\u0447\u043a\u0443, \u0430\u00a0\u0432\u0435\u0434\u044c \u0440\u0435\u0430\u043b\u044c\u043d\u043e \u0441\u0442\u0430\u0440\u0430\u043b\u0441\u044f. \u041f\u0440\u0438\u00a0\u044d\u0442\u043e\u043c \u0443\u00a0\u043c\u0435\u043d\u044f\u00a0\u0431\u044b\u043b\u0430 \u0434\u043e\u043f\u043e\u043b\u043d\u0438\u0442\u0435\u043b\u044c\u043d\u0430\u044f (\u0441\u043a\u043e\u0440\u0435\u0435 \u043e\u0441\u043d\u043e\u0432\u043d\u0430\u044f) \u043c\u043e\u0442\u0438\u0432\u0430\u0446\u0438\u044f \u043f\u043e\u0434\u0443\u0447\u0438\u0442\u044c <em>python<\/em>. \u0420\u044f\u0434\u043e\u0432\u043e\u0439 \u0443\u0447\u0438\u0442\u0435\u043b\u044c \u043e\u0434\u043d\u043e\u0437\u043d\u0430\u0447\u043d\u043e \u0432\u044b\u0431\u0435\u0440\u0435\u0442 \u043c\u0435\u043b \u0438 \u0434\u043e\u0441\u043a\u0443, \u0447\u0442\u043e\u0431\u044b \u0437\u0430\u00a0\u043c\u0438\u043d\u0443\u0442\u0443 \u043d\u0430\u0440\u0438\u0441\u043e\u0432\u0430\u0442\u044c \u0444\u043e\u0440\u043c\u0443\u043b\u0443, \u0430\u00a0\u043d\u0435\u00a0\u043a\u043e\u043b\u0431\u0430\u0441\u0438\u0442\u044c\u0441\u044f \u0441\u00a0\u043a\u043e\u0434\u043e\u043c \u0447\u0430\u0441\u0430\u043c\u0438 \u043d\u0430\u00a0\u043f\u0440\u043e\u043b\u0451\u0442.<\/p>\n<\/li>\n<li>\n<p><em>\u041d\u0435\u0431\u043e\u043b\u044c\u0448\u0430\u044f \u0430\u0443\u0434\u0438\u0442\u043e\u0440\u0438\u044f<\/em>. \u00ab\u0412\u0430\u0448\u0443 \u043f\u0443\u0431\u043b\u0438\u043a\u0430\u0446\u0438\u044e \u043e\u0447\u0435\u043d\u044c \u0436\u0434\u0443\u0442 \u0432\u043e\u00a0\u0432\u0441\u0435\u043c \u043c\u0438\u0440\u0435. \u0414\u0432\u0430 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u0430.\u00bb \u042d\u0442\u0438\u043c \u0430\u0444\u043e\u0440\u0438\u0437\u043c\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u043e\u043f\u0438\u0441\u0430\u0442\u044c \u043f\u043e\u043f\u044b\u0442\u043a\u0438 \u0440\u0430\u0431\u043e\u0442\u0430\u0442\u044c \u0432\u00a0\u0434\u0430\u043d\u043d\u043e\u043c \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438. \u0414\u043b\u044f\u00a0\u0443\u043f\u0440\u0430\u0436\u043d\u0435\u043d\u0438\u044f\u00a0\u2014 \u043e\u0442\u043b\u0438\u0447\u043d\u043e, \u0434\u043b\u044f\u00a0\u043a\u0430\u043a\u043e\u0439\u2011\u0442\u043e \u0431\u043e\u043b\u0435\u0435 \u043a\u043e\u043d\u043a\u0440\u0435\u0442\u043d\u043e\u0439 \u0446\u0435\u043b\u0438\u00a0\u2014 \u043d\u0435\u00a0\u0441\u0442\u043e\u0438\u0442(\u0443\u0434\u0430\u0440\u0435\u043d\u0438\u0435 \u0441\u0430\u043c\u0438 \u043f\u043e\u0441\u0442\u0430\u0432\u044c\u0442\u0435).<\/p>\n<\/li>\n<li>\n<p><em>\u041a\u043e\u043d\u043a\u0443\u0440\u0435\u043d\u0442\u043d\u044b<\/em>. \u0421\u043b\u044b\u0448\u0430\u043b \u043c\u043d\u0435\u043d\u0438\u0435, \u0447\u0442\u043e\u00a0\u0442\u0430\u043a\u043e\u0435 \u0433\u043e\u0440\u0430\u0437\u0434\u043e \u0431\u044b\u0441\u0442\u0440\u0435\u0435 \u0441\u0434\u0435\u043b\u0430\u0442\u044c \u0432 <em>After Effects. \u041d\u0435 \u0437\u043d\u0430\u044e, \u043d\u0435 \u043f\u0440\u043e\u0431\u043e\u0432\u0430\u043b, \u043d\u043e \u0432\u0435\u0440\u044e.<\/em><\/p>\n<\/li>\n<\/ul>\n<p><strong><em> \u0412\u044b\u0432\u043e\u0434<\/em><\/strong> <\/p>\n<p>\u041f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u0435<em> Manim<\/em> \u043c\u043d\u0435 \u043f\u0440\u0435\u0434\u0441\u0442\u0430\u0432\u043b\u044f\u0435\u0442\u0441\u044f \u043e\u0434\u043d\u0438\u043c \u0438\u0437\u00a0\u043a\u043b\u044e\u0447\u0435\u0432\u044b\u0445 \u0448\u0430\u0433\u043e\u0432 \u043d\u0430\u00a0\u043f\u0443\u0442\u0438 \u0441\u043e\u0437\u0434\u0430\u043d\u0438\u044f \u043a\u043e\u043b\u043b\u0435\u043a\u0442\u0438\u0432\u043d\u043e\u0433\u043e \u0443\u0447\u0435\u0431\u043d\u0438\u043a\u0430 \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0438, \u043a\u043e\u0442\u043e\u0440\u044b\u0439 \u043f\u043e\u0437\u0432\u043e\u043b\u0438\u043b\u00a0\u0431\u044b \u0431\u0443\u0434\u0443\u0449\u0438\u043c \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u044f\u043c \u043e\u0447\u0435\u043d\u044c \u043e\u043f\u0442\u0438\u043c\u0438\u0437\u0438\u0440\u043e\u0432\u0430\u0442\u044c \u0441\u0432\u043e\u0438 \u0443\u0441\u0438\u043b\u0438\u044f \u043d\u0430 \u00ab\u0432\u043a\u0430\u0442\u044b\u0432\u0430\u043d\u0438\u0435\u00bb \u0432\u00a0\u043f\u0440\u0435\u0434\u043c\u0435\u0442. \u041d\u043e\u00a0\u0441\u0435\u0439\u0447\u0430\u0441 \u0440\u044f\u0434\u043e\u0432\u043e\u0439 \u0443\u0447\u0438\u0442\u0435\u043b\u044c \u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0438 \u043d\u0435\u00a0\u0441\u043c\u043e\u0436\u0435\u0442 \u0438 \u043d\u0435\u00a0\u0441\u0442\u0430\u043d\u0435\u0442 \u0434\u0435\u043b\u0430\u0442\u044c \u0442\u0430\u043a\u043e\u0435 \u043d\u0430\u00a0\u043f\u043e\u0441\u0442\u043e\u044f\u043d\u043d\u043e\u0439 \u043e\u0441\u043d\u043e\u0432\u0435, \u043f\u043e\u0442\u043e\u043c\u0443 \u0447\u0442\u043e\u00a0\u043d\u043e\u0440\u043c\u0430\u043b\u044c\u043d\u044b\u0439 \u0432\u0438\u0434\u0435\u043e \u0443\u0440\u043e\u043a \u0442\u043e\u0433\u0434\u0430 \u043f\u043e\u0442\u0440\u0435\u0431\u0443\u0435\u0442 \u0441\u043e\u0442\u043d\u0438 \u0447\u0435\u043b\u043e\u0432\u0435\u043a\u043e\u2011\u0447\u0430\u0441\u043e\u0432 \u043d\u0435\u043e\u043f\u043b\u0430\u0447\u0438\u0432\u0430\u0435\u043c\u044b\u0445 \u0442\u0440\u0443\u0434\u043e\u0437\u0430\u0442\u0440\u0430\u0442. \u0427\u0442\u043e\u0431\u044b, \u043d\u0430\u043f\u0440\u0438\u043c\u0435\u0440, \u043f\u0435\u0440\u0435\u0434\u0435\u043b\u0430\u0442\u044c \u00ab<a href=\"https:\/\/www.youtube.com\/playlist?list=PLqBfxn8OBMGrsA_YynaQWqHKhL7kEvL4X\" rel=\"noopener noreferrer nofollow\">\u0441\u0442\u043e \u0443\u0440\u043e\u043a\u043e\u0432 \u043f\u043e\u00a0\u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0435<\/a>\u00bb \u043f\u043e\u00a0\u0442\u0430\u043a\u043e\u0439 \u0442\u0435\u0445\u043d\u043e\u043b\u043e\u0433\u0438\u0438 \u043d\u0443\u0436\u043d\u044b \u043d\u0435\u0447\u0435\u043b\u043e\u0432\u0435\u0447\u0435\u0441\u043a\u0438\u0435 \u0438\u043d\u0432\u0435\u0441\u0442\u0438\u0446\u0438\u0438, \u0445\u043e\u0442\u044c \u044d\u0442\u043e \u0438 \u0441\u0442\u0430\u043b\u043e \u0431\u044b \u0440\u0435\u0430\u043b\u044c\u043d\u044b\u043c \u0448\u0430\u0433\u043e\u043c \u0432 \u043e\u0431\u0440\u0430\u0437\u043e\u0432\u0430\u043d\u0438\u0438.<\/p>\n<\/p>\n<\/div>\n<\/div>\n<\/div>\n<p><!----><!----><\/div>\n<p><!----><!----><br \/> \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430 \u043e\u0440\u0438\u0433\u0438\u043d\u0430\u043b \u0441\u0442\u0430\u0442\u044c\u0438 <a href=\"https:\/\/habr.com\/ru\/articles\/829834\/\"> https:\/\/habr.com\/ru\/articles\/829834\/<\/a><\/p>\n","protected":false},"excerpt":{"rendered":"<div><!--[--><!--]--><\/div>\n<div id=\"post-content-body\">\n<div>\n<div class=\"article-formatted-body article-formatted-body article-formatted-body_version-2\">\n<div xmlns=\"http:\/\/www.w3.org\/1999\/xhtml\">\n<p><strong><em>\u0412\u043c\u0435\u0441\u0442\u043e \u0432\u0432\u0435\u0434\u0435\u043d\u0438\u044f<\/em><\/strong><\/p>\n<p>\u041d\u0435\u0441\u043c\u043e\u0442\u0440\u044f \u043d\u0430\u00a0\u0442\u043e, \u0447\u0442\u043e\u00a0\u043c\u0430\u0442\u0435\u043c\u0430\u0442\u0438\u043a\u0430 \u0441\u0435\u0433\u043e\u0434\u043d\u044f\u00a0\u2014 \u044d\u0442\u043e \u0433\u043b\u0443\u0431\u043e\u043a\u0438\u0439 \u0430\u043d\u0434\u0435\u0440\u0433\u0440\u0430\u0443\u043d\u0434, \u0440\u0430\u0431\u043e\u0442\u044b 3Blue1Brown \u0432\u0434\u043e\u0445\u043d\u043e\u0432\u043b\u044f\u044e\u0442 \u0438 \u043f\u0440\u043e\u0431\u0443\u0436\u0434\u0430\u044e\u0442 \u0432\u043d\u0443\u0442\u0440\u0438 \u0447\u0442\u043e\u2011\u0442\u043e \u0438\u0437\u00a0\u0434\u0430\u043b\u0451\u043a\u043e\u0433\u043e \u0434\u0435\u0442\u0441\u0442\u0432\u0430, \u0433\u0434\u0435 \u0432\u0435\u0441\u044c \u043c\u0438\u0440\u00a0\u0431\u044b\u043b \u043d\u0435\u043f\u043e\u0441\u0442\u0438\u0436\u0438\u043c\u043e\u0439 \u0438\u0433\u0440\u043e\u0432\u043e\u0439 \u043f\u043b\u043e\u0449\u0430\u0434\u043a\u043e\u0439, \u0430\u00a0\u0438\u0437\u00a0\u043a\u0438\u0441\u043b\u043e\u0433\u043e\u00a0\u0431\u044b\u043b\u0438 \u0442\u043e\u043b\u044c\u043a\u043e \u043c\u0443\u0440\u0430\u0432\u044c\u0438\u043d\u044b\u0435 \u0436\u043e\u043f\u043a\u0438. \u041a\u043e\u043d\u0435\u0447\u043d\u043e, \u043e\u0447\u0435\u043d\u044c \u0445\u043e\u0447\u0435\u0442\u0441\u044f \u043a\u0430\u043a\u2011\u0442\u043e \u043f\u0440\u0438\u043a\u043e\u0441\u043d\u0443\u0442\u044c\u0441\u044f \u043a\u00a0\u043f\u0440\u0435\u043a\u0440\u0430\u0441\u043d\u043e\u043c\u0443. \u0422\u0435\u043c \u0431\u043e\u043b\u0435\u0435, \u0447\u0442\u043e <a href=\"https:\/\/habr.com\/ru\/companies\/ruvds\/news\/591147\/\" rel=\"noopener noreferrer nofollow\"><strong>\u0413\u0440\u0430\u043d\u0442 \u0421\u0430\u043d\u0434\u0435\u0440\u0441\u043e\u043d<\/strong><\/a> \u0440\u0430\u0437\u0440\u0430\u0431\u043e\u0442\u0430\u043b \u0434\u043b\u044f\u00a0\u044d\u0442\u043e\u0433\u043e \u0446\u0435\u043b\u0443\u044e \u0431\u0438\u0431\u043b\u0438\u043e\u0442\u0435\u043a\u0443 \u0438 \u0431\u0435\u0437\u0432\u043e\u0437\u043c\u0435\u0437\u0434\u043d\u043e \u043f\u0435\u0440\u0435\u0434\u0430\u043b \u0435\u0451 \u043d\u0430\u043c, \u0431\u0435\u0437\u044b\u043c\u044f\u043d\u043d\u044b\u043c \u043a\u043e\u0434\u0435\u0440\u0430\u043c \u0441\u043e \u0432\u0441\u0435\u0433\u043e \u043c\u0438\u0440\u0430.<\/p>\n<p><strong><em>\u0417\u043d\u0430\u043a\u043e\u043c\u0441\u0442\u0432\u043e \u0441 Manim<\/em><\/strong><\/p>\n<p>\u0415\u0441\u0442\u044c \u043e\u0442\u043b\u0438\u0447\u043d\u044b\u0439 <a href=\"https:\/\/www.manim.community\" rel=\"noopener noreferrer nofollow\">\u0441\u0430\u0439\u0442 \u0441 \u0434\u043e\u043a\u0443\u043c\u0435\u043d\u0442\u0430\u0446\u0438\u0435\u0439 \u0438 \u043f\u0440\u0438\u043c\u0435\u0440\u0430\u043c\u0438<\/a> \u043e\u0442 \u0441\u043e\u043e\u0431\u0449\u0435\u0441\u0442\u0432\u0430. \u0418 \u0432 \u0440\u0443-\u0441\u0435\u0433\u043c\u0435\u043d\u0442\u0435, \u0432 \u0447\u0430\u0441\u0442\u043d\u043e\u0441\u0442\u0438 \u043d\u0430 \u0425\u0430\u0431\u0440\u0435, \u0442\u0430\u043a\u0436\u0435 \u043c\u043e\u0436\u043d\u043e \u043d\u0430\u0439\u0442\u0438 \u0431\u0430\u0437\u043e\u0432\u044b\u0435 \u0442\u0443\u0442\u043e\u0440\u0438\u0430\u043b\u044b [<a href=\"https:\/\/habr.com\/ru\/articles\/821743\/\" rel=\"noopener noreferrer nofollow\">1<\/a>, <a href=\"https:\/\/habr.com\/ru\/companies\/yandex_praktikum\/articles\/578910\/\" rel=\"noopener noreferrer nofollow\">2<\/a>, <a href=\"https:\/\/habr.com\/ru\/companies\/skillfactory\/articles\/556944\/\" rel=\"noopener noreferrer nofollow\">3<\/a>]. \u041e\u0434\u043d\u0430\u043a\u043e, \u043f\u0440\u0438 \u043f\u0435\u0440\u0432\u043e\u043c \u0436\u0435 \u0432\u0437\u0430\u0438\u043c\u043e\u0434\u0435\u0439\u0441\u0442\u0432\u0438\u0438 \u043f\u043e\u043d\u0438\u043c\u0430\u0435\u0448\u044c, \u0447\u0442\u043e \u043c\u0430\u043b\u043e \u043e\u0431\u0443\u0447\u0430\u043b\u043e\u043a \u0434\u043b\u044f \u043f\u0440\u043e\u0435\u043a\u0442\u0430, \u0443 \u043a\u043e\u0442\u043e\u0440\u043e\u0433\u043e 39 \u0442\u044b\u0441\u044f\u0447 \u0437\u0432\u0451\u0437\u0434 <em>Github<\/em>. \u0421 \u0432\u044f\u0437\u0438 \u0441 \u0447\u0435\u043c, \u043e-\u043e-\u043e\u0447\u0435\u043d\u044c \u0440\u0430\u0434\u0443\u0435\u0442, \u0447\u0442\u043e <em>chatGPT<\/em> \u043e\u0442\u043b\u0438\u0447\u043d\u043e \u0443\u043c\u0435\u0435\u0442 \u0432 <em>Manim<\/em> \u0438 \u0441\u043c\u043e\u0436\u0435\u0442 \u0432\u0430\u043c \u043f\u043e\u043c\u043e\u0447\u044c \u043f\u043e\u0447\u0442\u0438 \u0441 \u043b\u044e\u0431\u044b\u043c \u0432\u043e\u043f\u0440\u043e\u0441\u043e\u043c.<\/p>\n<p><strong><em>\u0412\u044b\u0431\u043e\u0440 \u0442\u0435\u043c\u044b<\/em><\/strong><\/p>\n<p>\u0426\u0435\u043b\u044c \u0440\u0430\u0431\u043e\u0442\u044b\u00a0\u2014 \u0441\u044d\u043a\u043e\u043d\u043e\u043c\u0438\u0442\u044c \u0432\u0440\u0435\u043c\u044f \u0441\u043b\u0435\u0434\u0443\u044e\u0449\u0435\u043c\u0443 \u043f\u043e\u043a\u043e\u043b\u0435\u043d\u0438\u044e \u043d\u0430\u00a0\u0438\u0437\u0443\u0447\u0435\u043d\u0438\u0435 \u0432\u044b\u0431\u0440\u0430\u043d\u043d\u043e\u0433\u043e \u0442\u043e\u043f\u0438\u043a\u0430. \u0412\u00a0\u043f\u0435\u0440\u0432\u0443\u044e \u043e\u0447\u0435\u0440\u0435\u0434\u044c \u0445\u043e\u0442\u0435\u043b\u043e\u0441\u044c \u0447\u0442\u043e\u2011\u0442\u043e \u0436\u0438\u0437\u043d\u0435\u043d\u043d\u043e\u0435 \u0434\u043b\u044f <s>\u043f\u0430\u0446\u0430\u043d\u043e\u0432 \u0441\u00a0\u0440\u0430\u0439\u043e\u043d\u0430<\/s> \u0441\u0440\u0435\u0434\u043d\u0435\u0433\u043e \u0441\u0442\u0443\u0434\u0435\u043d\u0442\u0430. \u0410\u00a0\u0442\u0430\u043a \u043a\u0430\u043a\u00a0\u044f \u0438 \u0441\u0430\u043c \u0441\u0435\u0439\u0447\u0430\u0441 \u0440\u0430\u0437\u0431\u0438\u0440\u0430\u044e\u0441\u044c \u0441\u00a0\u043c\u0430\u0442\u0441\u0442\u0430\u0442\u043e\u043c, \u0442\u043e \u043a\u043e\u043c\u0431\u0438\u043d\u0430\u0442\u043e\u0440\u0438\u043a\u0430 \u043f\u0440\u0438\u0448\u043b\u0430 \u0432\u00a0\u0433\u043e\u043b\u043e\u0432\u0443 \u043f\u043e\u0447\u0442\u0438 \u043c\u043e\u043c\u0435\u043d\u0442\u0430\u043b\u044c\u043d\u043e. \u0422\u0430\u043c, \u043a\u043e\u043d\u0435\u0447\u043d\u043e, \u043f\u043e\u043b\u0435 \u043d\u0435\u043f\u0430\u0445\u0430\u043d\u043e\u0435 \u0432\u00a0\u043f\u043b\u0430\u043d\u0435 \u0432\u0438\u0437\u0443\u0430\u043b\u0438\u0437\u0430\u0446\u0438\u0438, \u043f\u043e\u044d\u0442\u043e\u043c\u0443 \u044f \u0432\u0437\u044f\u043b \u0441\u0430\u043c\u043e\u0435 \u0431\u0430\u0437\u043e\u0432\u043e\u0435. \u0415\u0441\u043b\u0438 \u0442\u0435\u043c\u0430 \u0437\u0430\u0439\u0434\u0451\u0442, \u0442\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0443 \u0432\u00a0\u0442\u043e\u043c\u00a0\u0436\u0435 \u043d\u0430\u043f\u0440\u0430\u0432\u043b\u0435\u043d\u0438\u0438, \u0430\u00a0\u0435\u0441\u043b\u0438 \u043d\u0435\u00a0\u0437\u0430\u0439\u0434\u0451\u0442.. \u0432\u0441\u0451 \u0440\u0430\u0432\u043d\u043e \u043f\u0440\u043e\u0434\u043e\u043b\u0436\u0443, \u043d\u043e\u00a0\u0443\u0436\u0435 \u0433\u0440\u0443\u0441\u0442\u043d\u0435\u0435.<\/p>\n<p><strong><em>\u041a\u043e\u0434<\/em><\/strong><\/p>\n<p>\u0412\u0435\u0441\u044c \u0441\u043a\u0440\u0438\u043f\u0442 \u0446\u0435\u043b\u0438\u043a\u043e\u043c \u043c\u043e\u0436\u043d\u043e \u0437\u0430\u0431\u0440\u0430\u0442\u044c \u0432 <a href=\"https:\/\/github.com\/RomanBashmakov\/Manim_Permutations_Habr.git\" rel=\"noopener noreferrer nofollow\">\u0440\u0435\u043f\u043e\u0437\u0438\u0442\u043e\u0440\u0438\u0438<\/a>. \u0422\u0430\u043a \u0436\u0435 \u043d\u0430 \u0432\u0441\u044f\u043a\u0438\u0439 \u0441\u043b\u0443\u0447\u0430\u0439 \u0441\u0441\u044b\u043b\u043a\u0430 \u043d\u0430  <a href=\"https:\/\/drive.google.com\/drive\/folders\/1j0EM7nMGM1K_BHbN04ACtWfzl4K_e_7W?usp=share_link\" rel=\"noopener noreferrer nofollow\">\u0432\u0438\u0440\u0442\u0443\u0430\u043b\u044c\u043d\u043e\u0435 \u043e\u043a\u0440\u0443\u0436\u0435\u043d\u0438\u0435<\/a> \u0434\u043b\u044f <em>python&#8217;\u0430<\/em>.<\/p>\n<details class=\"spoiler\">\n<summary>\u0421\u043a\u0440\u0438\u043f\u0442 \u0446\u0435\u043b\u0438\u043a\u043e\u043c<\/summary>\n<div class=\"spoiler__content\">\n<pre><code class=\"python\">import os import shutil from manim import * import copy  shutil.rmtree(os.path.join('media')) os.mkdir('media')  def make_mobs (mob_type) -> list:     mobs = list()     for x in np.nditer(mob_type):         if x == 0:              mobs.append(SVGMobject(\"cucumber.svg\"))         elif x == 1:             mobs.append(SVGMobject(\"plum.svg\"))         elif x == 2:             mobs.append(SVGMobject(\"lemo.svg\"))         elif x == 3:             mobs.append(SVGMobject(\"apple_red.svg\"))     return mobs   def moveAlongPath(mobject_1, mobject_2, movingCameraScene, f_up_down) -> Dot:     dot = Dot().move_to(mobject_1)     path = Line(mobject_1.get_center(), mobject_2.get_center(),stroke_opacity=0.5).set_opacity(0)     if f_up_down:         path.points[1:3] += UP*2     else:         path.points[1:3] -= UP*2      mobject_1.save_state()     def update_rotate_move(mob,alpha):         mobject_1.restore()         mobject_1.move_to(path.point_from_proportion(alpha))         mobject_1.rotate(2*PI*alpha)      movingCameraScene.play(             UpdateFromAlphaFunc(mobject_1,update_rotate_move),             run_time = 1         )     return dot  def swapMobs(mobject_1, mobject_2, movingCameraScene):      mobject_1.save_state()     mobject_2.save_state()      dot_1 = Dot().move_to(mobject_1)     dot_2 = Dot().move_to(mobject_2)      def update_rotate_move_up(mob,alpha):         mob.restore()         path = Line(dot_1.get_center(), dot_2.get_center(),stroke_opacity=0.5).set_opacity(0)         path.points[1:3] += UP*2         mob.move_to(path.point_from_proportion(alpha))         mob.rotate(2*PI*alpha)      def update_rotate_move_down(mob,alpha):         mob.restore()         path = Line(dot_2.get_center(), dot_1.get_center(),stroke_opacity=0.5).set_opacity(0)         path.points[1:3] -= UP*2         mob.move_to(path.point_from_proportion(alpha))         mob.rotate(2*PI*alpha)      movingCameraScene.play(             AnimationGroup(                 UpdateFromAlphaFunc(mobject_1, update_rotate_move_up),                 UpdateFromAlphaFunc(mobject_2, update_rotate_move_down),                 run_time = 1             )         )  def placeInLine (mobs, rows, cols, x_step, y_step):     for i, mob in enumerate(mobs):         row = i \/\/ cols         col = i % cols         mob.move_to(np.array([col * x_step - (cols-1) * x_step \/ 2,                                  -(row * y_step) + (rows-1) * y_step \/ 2, 0]))          def playReplaceMobs (movingCameraScene, mobs_1, mobs_2):     for i, mob_1 in enumerate(mobs_1):         movingCameraScene.play(Transform(mobs_1[i], mobs_2[i]))  def placeGrid(movingCameraScene):     # \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u0441\u0435\u0442\u043a\u0443 \u0441 \u043d\u0430\u0441\u0442\u0440\u043e\u0439\u043a\u0430\u043c\u0438     grid = NumberPlane(         x_range=[-100, 100, 1],   # \u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u043f\u043e \u043e\u0441\u0438 X: \u043e\u0442 -10 \u0434\u043e 10 \u0441 \u0448\u0430\u0433\u043e\u043c 1         y_range=[-100, 100, 1],   # \u0414\u0438\u0430\u043f\u0430\u0437\u043e\u043d \u043f\u043e \u043e\u0441\u0438 Y: \u043e\u0442 -10 \u0434\u043e 10 \u0441 \u0448\u0430\u0433\u043e\u043c 1         background_line_style = {             \"stroke_color\": BLUE,     # \u0426\u0432\u0435\u0442 \u043b\u0438\u043d\u0438\u0439 \u0441\u0435\u0442\u043a\u0438             \"stroke_width\": 1,        # \u0422\u043e\u043b\u0449\u0438\u043d\u0430 \u043b\u0438\u043d\u0438\u0439 \u0441\u0435\u0442\u043a\u0438             \"stroke_opacity\": 0.6     # \u041f\u0440\u043e\u0437\u0440\u0430\u0447\u043d\u043e\u0441\u0442\u044c \u043b\u0438\u043d\u0438\u0439 \u0441\u0435\u0442\u043a\u0438         }     )     # \u041d\u0430\u0441\u0442\u0440\u043e\u0438\u0442\u044c \u043e\u0441\u0438     grid.axes.set_color(BLUE).set(stroke_width = 0.5, stroke_opacity = 0.6)  # \u0426\u0432\u0435\u0442 \u043e\u0441\u0435\u0439      # \u0414\u043e\u0431\u0430\u0432\u043b\u044f\u0435\u043c \u0441\u0435\u0442\u043a\u0443 \u043d\u0430 \u0441\u0446\u0435\u043d\u0443     movingCameraScene.add(grid)     grid.remove(grid.x_axis, grid.y_axis)  def showEverithing(group, movingCameraScene):     # \u041e\u043f\u0440\u0435\u0434\u0435\u043b\u0435\u043d\u0438\u0435 \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430 \u043a\u0430\u043c\u0435\u0440\u044b \u043f\u043e \u0448\u0438\u0440\u0438\u043d\u0435 \u0438 \u0432\u044b\u0441\u043e\u0442\u0435     scale_width = movingCameraScene.camera.frame_width \/ group.width     scale_height = movingCameraScene.camera.frame_height \/ group.height      # \u0412\u044b\u0431\u043e\u0440 \u043d\u0430\u0438\u043c\u0435\u043d\u044c\u0448\u0435\u0433\u043e \u043c\u0430\u0441\u0448\u0442\u0430\u0431\u0430 \u0434\u043b\u044f \u0433\u0430\u0440\u0430\u043d\u0442\u0438\u0438, \u0447\u0442\u043e \u0432\u0441\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b \u043f\u043e\u043f\u0430\u0434\u0443\u0442 \u0432 \u043a\u0430\u0434\u0440     optimal_scale = min(scale_width, scale_height)      # \u0423\u0441\u0442\u0430\u043d\u043e\u0432\u043a\u0430 \u0448\u0438\u0440\u0438\u043d\u044b \u0438 \u0432\u044b\u0441\u043e\u0442\u044b \u043a\u0430\u0434\u0440\u0430 \u043a\u0430\u043c\u0435\u0440\u044b     movingCameraScene.play(movingCameraScene.camera.frame.animate.set(width = movingCameraScene.camera.frame_width \/ optimal_scale * 1.3))     movingCameraScene.play(movingCameraScene.camera.frame.animate.move_to(group))       #============================================================================================================ ############################################################################################################# ############################################################################################################# #============================================================================================================ class Permutations(MovingCameraScene):     def construct(self):         self.camera.background_color = GREY_BROWN          placeGrid(self)          # \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432         mob_type = np.array([0, 1, 2, 3])         mobs = make_mobs(mob_type)         mobs_2 = make_mobs(mob_type)          # \u0420\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c mobs \u043f\u043e \u0441\u0435\u0442\u043a\u0435 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e         placeInLine(mobs, 5, 1, 0, 2.1)                      # \u0420\u0430\u0441\u043f\u043e\u043b\u0430\u0433\u0430\u0435\u043c mobs_2 \u043f\u043e \u0441\u0435\u0442\u043a\u0435 \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u043e         placeInLine(mobs_2, 1, 5, 1.3, 0)          # \u0413\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u043c \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b         grid = VGroup(*mobs).scale(0.5)         # \u0413\u0440\u0443\u043f\u043f\u0438\u0440\u0443\u0435\u043c \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043e\u0431\u044a\u0435\u043a\u0442\u044b         grid_2 = VGroup(*mobs_2).next_to(grid.get_top(), UP).scale(0.5)          # \u0410\u043d\u0438\u043c\u0430\u0446\u0438\u044f \u043f\u043e\u044f\u0432\u043b\u0435\u043d\u0438\u044f \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432         self.play(self.camera.frame.animate.move_to(grid).set(height = grid.height * 1.1))         self.play(Create(grid))                  group = VGroup(grid, grid_2)          showEverithing(group, self)          # \u0417\u0430\u043c\u0435\u043d\u0438\u0442\u044c \u0433\u043e\u0440\u0438\u0437\u043e\u043d\u0442\u0430\u043b\u044c\u043d\u044b\u0435 \u043d\u0430 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u044b\u0435         playReplaceMobs(self, mobs, mobs_2)          self.remove(grid)         self.play(grid_2.animate.move_to(self.camera.frame.get_top()))          self.play(self.camera.frame.animate.move_to(grid_2))         self.play(self.camera.frame.animate.set(width = grid_2.width * 2.0))          swapMobs(grid_2[0], grid_2[3], self)         swapMobs(grid_2[1], grid_2[2], self)         swapMobs(grid_2[0], grid_2[1], self)         swapMobs(grid_2[2], grid_2[3], self)         swapMobs(grid_2[1], grid_2[2], self)         swapMobs(grid_2[0], grid_2[1], self)         swapMobs(grid_2[2], grid_2[3], self)          self.wait(2) #============================================================================================================ ############################################################################################################# ############################################################################################################# #============================================================================================================ class Permutations_2(MovingCameraScene):     def construct(self):         self.camera.background_color = GREY_BROWN          placeGrid(self)          # \u0421\u043e\u0437\u0434\u0430\u0435\u043c \u043d\u0435\u0441\u043a\u043e\u043b\u044c\u043a\u043e \u043e\u0431\u044a\u0435\u043a\u0442\u043e\u0432         list_of_grids = list() #\u0441\u043f\u0438\u0441\u043e\u043a grids'\u043e\u0432           mob_type = np.array([0, 1, 2, 3])         mobs_1 = make_mobs(mob_type)         mobs_2 = make_mobs(mob_type)          # \u0418\u0441\u0445\u043e\u0434\u043d\u044b\u0435 \u0444\u0440\u0443\u043a\u0442\u044b-\u043e\u0432\u043e\u0449\u0438 \u0432\u0435\u0440\u0442\u0438\u043a\u0430\u043b\u044c\u043d\u043e         placeInLine(mobs_1, 4, 1, 0, 1.5)         grid_1 = VGroup(*mobs_1).scale(0.5)         list_of_grids.append(grid_1)                  # \u0421\u0442\u0430\u0440\u0442\u043e\u0432\u044b\u0439 \u044d\u043a\u0440\u0430\u043d         self.play(self.camera.frame.animate.move_to(grid_1).set(height = grid_1.height * 1.1))         self.play(Create(grid_1))          # \u041f\u0435\u0440\u0432\u044b\u0439 \u0441\u043b\u043e\u0439         placeInLine(mobs_2, 4, 1, 0, 8)         grid_2 = VGroup(*mobs_2).scale(1).next_to(grid_1, RIGHT * 5)         list_of_grids.append(grid_2)          showEverithing(VGroup(*list_of_grids), self)          # \u0420\u0430\u0441\u0441\u0442\u0430\u0432\u0438\u0442\u044c \u043f\u0435\u0440\u0432\u044b\u0439 \u0441\u043b\u043e\u0439         self.play(             AnimationGroup(                 TransformFromCopy(mobs_1[0], mobs_2[0]),                 TransformFromCopy(mobs_1[1], mobs_2[1]),                 TransformFromCopy(mobs_1[2], mobs_2[2]),                 TransformFromCopy(mobs_1[3], mobs_2[3]),                 run_time = 1             )         )          self.wait(0.3)  #============================================================================================================ # \u0412\u0442\u043e\u0440\u043e\u0439 \u0441\u043b\u043e\u0439 #============================================================================================================  <\/code><\/pre>\n<\/div>\n<\/details>\n<\/div>\n<\/div>\n<\/div>\n<\/div>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[],"tags":[],"class_list":["post-426615","post","type-post","status-publish","format-standard","hentry"],"_links":{"self":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/426615","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=426615"}],"version-history":[{"count":0,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=\/wp\/v2\/posts\/426615\/revisions"}],"wp:attachment":[{"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=426615"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=426615"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/savepearlharbor.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=426615"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}