Zdrojové kódy k příkladům a úlohám 34. série KSP (Manim).
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

#### 329 lines 11 KiB Raw Permalink Blame History

 `{` ` "cells": [` ` {` ` "cell_type": "markdown",` ` "id": "36cee816",` ` "metadata": {},` ` "source": [` ` "# Řešení 2. série"` ` ]` ` },` ` {` ` "cell_type": "code",` ` "execution_count": null,` ` "id": "efe16561",` ` "metadata": {},` ` "outputs": [],` ` "source": [` ` "from manim import *"` ` ]` ` },` ` {` ` "cell_type": "markdown",` ` "id": "36ec08cc",` ` "metadata": {},` ` "source": [` ` "## Trojúhelník"` ` ]` ` },` ` {` ` "cell_type": "code",` ` "execution_count": null,` ` "id": "e7a3da39",` ` "metadata": {},` ` "outputs": [],` ` "source": [` ` "%%manim -v WARNING -qh Triangle\n",` ` "\n",` ` "from random import *\n",` ` "\n",` ` "\n",` ` "class Triangle(Scene):\n",` ` " def construct(self):\n",` ` " seed(0xDEADBEEF)\n",` ` "\n",` ` " # vše trochu zvětšíme\n",` ` " c = 2\n",` ` "\n",` ` " p1 = Dot().scale(c).shift(UP * c)\n",` ` " p2 = Dot().scale(c).shift(DOWN * c + LEFT * c)\n",` ` " p3 = Dot().scale(c).shift(DOWN * c + RIGHT * c)\n",` ` "\n",` ` " points = VGroup(p1, p2, p3)\n",` ` " \n",` ` " self.play(Write(points, lag_ratio=0.5), run_time=1.5)\n",` ` "\n",` ` " l1 = Line()\n",` ` " l2 = Line()\n",` ` " l3 = Line()\n",` ` "\n",` ` " lines = VGroup(l1, l2, l3)\n",` ` "\n",` ` " def create_line_updater(a, b):\n",` ` " \"\"\"Vrátí funkci, která se chová jako updater nějaké úsečky.\"\"\"\n",` ` " return lambda x: x.become(Line(start=a.get_center(), end=b.get_center()))\n",` ` "\n",` ` " l1.add_updater(create_line_updater(p1, p2))\n",` ` " l2.add_updater(create_line_updater(p2, p3))\n",` ` " l3.add_updater(create_line_updater(p3, p1))\n",` ` "\n",` ` " self.play(Write(lines, lag_ratio=0.5), run_time=1.5)\n",` ` "\n",` ` " x = Tex(\"x\")\n",` ` " y = Tex(\"y\")\n",` ` " z = Tex(\"z\")\n",` ` "\n",` ` " x.add_updater(lambda x: x.next_to(p1, UP))\n",` ` " y.add_updater(lambda x: x.next_to(p2, DOWN + LEFT))\n",` ` " z.add_updater(lambda x: x.next_to(p3, DOWN + RIGHT))\n",` ` "\n",` ` " labels = VGroup(x, y, z).scale(c * 0.8)\n",` ` "\n",` ` " self.play(FadeIn(labels, shift=UP * 0.2))\n",` ` "\n",` ` " circle = Circle()\n",` ` " circle.add_updater(\n",` ` " lambda c: c.become(\n",` ` " Circle.from_three_points(\n",` ` " p1.get_center(), p2.get_center(), p3.get_center()\n",` ` " )\n",` ` " )\n",` ` " )\n",` ` "\n",` ` " self.play(Write(circle))\n",` ` "\n",` ` " self.play(\n",` ` " p2.animate.shift(LEFT + UP),\n",` ` " p1.animate.shift(RIGHT),\n",` ` " )"` ` ]` ` },` ` {` ` "cell_type": "markdown",` ` "id": "171e8840",` ` "metadata": {},` ` "source": [` ` "## Vlna"` ` ]` ` },` ` {` ` "cell_type": "code",` ` "execution_count": null,` ` "id": "252d64a3",` ` "metadata": {},` ` "outputs": [],` ` "source": [` ` "%%manim -v WARNING -qh Wave\n",` ` "\n",` ` "from random import *\n",` ` "\n",` ` "\n",` ` "class Wave(Scene):\n",` ` " def construct(self):\n",` ` " seed(0xDEADBEEF)\n",` ` "\n",` ` " maze_string = \"\"\"\n",` ` "#######################################################\n",` ` "# ################# ## #\n",` ` "# ################## #### #\n",` ` "# ################# #### #\n",` ` "# ############### ##### # ##\n",` ` "# ######### ##### ####\n",` ` "# ### ###### ######\n",` ` "# ### ## ##### ### #####\n",` ` "# #### ######## #### ##### ## #\n",` ` "# ##### ########## ### ######## # #\n",` ` "# ##### ########### ######## #\n",` ` "# #### ########### ########## #\n",` ` "# ## ########### ########## #\n",` ` "# #### ############ ############# #\n",` ` "# ###### ############ ############# #\n",` ` "# ######### ## ########### ######### # #\n",` ` "# ############### ######### ####### #\n",` ` "# ############### ###### ###### #\n",` ` "# ############### ##### #### #\n",` ` "# ############# # ## #\n",` ` "# # ####### ########### ####\n",` ` "# ### # #################\n",` ` "# ## #### #################\n",` ` "##### ###### ##################\n",` ` "###### ###### ##################\n",` ` "# ### ### ####### ### ############### #\n",` ` "# #### ############ #### ####### #\n",` ` "# ##### ############ ### #\n",` ` "# ### ########## #\n",` ` "#######################################################\n",` ` "\"\"\"\n",` ` "\n",` ` " maze = [] # 2D pole čtverců tak, jak ho vidíme\n",` ` " maze_bool = [] # 2D pole True/False\n",` ` " all_squares = VGroup()\n",` ` "\n",` ` " # parsujeme vstup, řádek po řádku\n",` ` " for row in maze_string.strip().splitlines():\n",` ` " maze.append([])\n",` ` " maze_bool.append([])\n",` ` "\n",` ` " for char in row:\n",` ` " square = Square(\n",` ` " side_length=0.23,\n",` ` " stroke_width=1,\n",` ` " fill_color=WHITE if char == \"#\" else BLACK,\n",` ` " fill_opacity=1,\n",` ` " )\n",` ` "\n",` ` " maze[-1].append(square)\n",` ` " maze_bool[-1].append(char == \" \")\n",` ` " all_squares.add(square)\n",` ` "\n",` ` " # rozměry bludiště\n",` ` " w = len(maze[0])\n",` ` " h = len(maze)\n",` ` "\n",` ` " # rozmístění do gridu\n",` ` " all_squares.arrange_in_grid(rows=h, buff=0)\n",` ` "\n",` ` " self.play(FadeIn(all_squares), run_time=2)\n",` ` "\n",` ` " # startovní pozice\n",` ` " x, y = 1, 1\n",` ` "\n",` ` " colors = [\"#ef476f\", \"#ffd166\", \"#06d6a0\", \"#118ab2\"]\n",` ` "\n",` ` " # vytvoříme si slovník se vzdálenostmi od startu\n",` ` " distances = {(x, y): 0}\n",` ` " stack = [(x, y, 0)]\n",` ` "\n",` ` " while len(stack) != 0:\n",` ` " x, y, d = stack.pop(0)\n",` ` "\n",` ` " for dx, dy in ((0, 1), (1, 0), (-1, 0), (0, -1)):\n",` ` " nx, ny = dx + x, dy + y\n",` ` "\n",` ` " # není potřeba, jelikož vstup je ohraničený a nikde nevyběhneme :)\n",` ` " #if nx < 0 or nx >= w or ny < 0 or ny >= h:\n",` ` " # continue\n",` ` "\n",` ` " if maze_bool[ny][nx] and (nx, ny) not in distances:\n",` ` " stack.append((nx, ny, d + 1))\n",` ` " distances[(nx, ny)] = d + 1\n",` ` "\n",` ` " max_distance = max([d for d in distances.values()])\n",` ` "\n",` ` " all_colors = color_gradient(colors, max_distance + 1)\n",` ` "\n",` ` " # vytvoříme skupiny podle vzdálenosti od startu\n",` ` " groups = []\n",` ` " for d in range(max_distance + 1):\n",` ` " groups.append(\n",` ` " AnimationGroup(\n",` ` " *[\n",` ` " maze[y][x].animate.set_fill(all_colors[d])\n",` ` " for x, y in distances\n",` ` " if distances[x, y] == d\n",` ` " ]\n",` ` " )\n",` ` " )\n",` ` "\n",` ` " self.play(AnimationGroup(*groups, lag_ratio=0.08))\n"` ` ]` ` },` ` {` ` "cell_type": "markdown",` ` "id": "e6f13b54",` ` "metadata": {},` ` "source": [` ` "## Hilbert"` ` ]` ` },` ` {` ` "cell_type": "code",` ` "execution_count": null,` ` "id": "06ed2d5c",` ` "metadata": {},` ` "outputs": [],` ` "source": [` ` "%%manim -v WARNING -qh Hilbert\n",` ` "\n",` ` "\n",` ` "class Path(VMobject):\n",` ` " def __init__(self, points, *args, **kwargs):\n",` ` " super().__init__(self, *args, **kwargs)\n",` ` " self.set_points_as_corners(points)\n",` ` "\n",` ` " def get_important_points(self):\n",` ` " \"\"\"Vrátí důležité body křivky.\"\"\"\n",` ` " return list(self.get_start_anchors()) + [self.get_end_anchors()[-1]]\n",` ` "\n",` ` "\n",` ` "class Hilbert(Scene):\n",` ` " def construct(self):\n",` ` " directions = [LEFT + DOWN, LEFT + UP, RIGHT + UP, RIGHT + DOWN]\n",` ` "\n",` ` " hilbert = Path(directions).scale(3)\n",` ` "\n",` ` " self.play(Write(hilbert, lag_ratio=0.5))\n",` ` "\n",` ` " for i in range(1, 4):\n",` ` " # délka jedné úsečky\n",` ` " new_segment_length = 1 / (2 ** (i + 1) - 1)\n",` ` "\n",` ` " # škálování částí křivky tak, aby byla vycentrovaná\n",` ` " new_scale = (1 - new_segment_length) / 2\n",` ` "\n",` ` " # chceme si uchovat původní křivku, abychom pomocí ní vyrovnávali ostatní\n",` ` " lu = hilbert.copy()\n",` ` " lu, hilbert = hilbert, lu\n",` ` "\n",` ` " self.play(\n",` ` " lu.animate.scale(new_scale)\n",` ` " .set_color(DARK_GRAY)\n",` ` " .align_to(hilbert, directions[1])\n",` ` " )\n",` ` "\n",` ` " ru = lu.copy()\n",` ` " self.play(ru.animate.align_to(hilbert, directions[2]))\n",` ` "\n",` ` " ld, rd = lu.copy(), ru.copy()\n",` ` " self.play(\n",` ` " ld.animate.align_to(hilbert, directions[0]).rotate(-PI / 2),\n",` ` " rd.animate.align_to(hilbert, directions[3]).rotate(PI / 2),\n",` ` " )\n",` ` "\n",` ` " new_hilbert = Path(\n",` ` " list(ld.flip(LEFT).get_important_points())\n",` ` " + list(lu.get_important_points())\n",` ` " + list(ru.get_important_points())\n",` ` " + list(rd.flip(LEFT).get_important_points())\n",` ` " )\n",` ` "\n",` ` " self.play(Write(new_hilbert, run_time=2 ** i))\n",` ` "\n",` ` " self.remove(lu, ru, ld, rd)\n",` ` "\n",` ` " hilbert = new_hilbert"` ` ]` ` }` ` ],` ` "metadata": {` ` "kernelspec": {` ` "display_name": "Python 3 (ipykernel)",` ` "language": "python",` ` "name": "python3"` ` },` ` "language_info": {` ` "codemirror_mode": {` ` "name": "ipython",` ` "version": 3` ` },` ` "file_extension": ".py",` ` "mimetype": "text/x-python",` ` "name": "python",` ` "nbconvert_exporter": "python",` ` "pygments_lexer": "ipython3",` ` "version": "3.10.1"` ` }` ` },` ` "nbformat": 4,` ` "nbformat_minor": 5` ```} ``` ``` ```