commit
5325eaa0b3
11 changed files with 4745 additions and 0 deletions
@ -0,0 +1,3 @@ |
|||
media/ |
|||
.ipynb_checkpoints/ |
|||
ignored/ |
After Width: | Height: | Size: 8.2 KiB |
@ -0,0 +1,429 @@ |
|||
{ |
|||
"cells": [ |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "36cee816", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"# Řešení 1. série" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 1, |
|||
"id": "efe16561", |
|||
"metadata": {}, |
|||
"outputs": [ |
|||
{ |
|||
"data": { |
|||
"text/html": [ |
|||
"<pre style=\"white-space:pre;overflow-x:auto;line-height:normal;font-family:Menlo,'DejaVu Sans Mono',consolas,'Courier New',monospace\">Manim Community <span style=\"color: #008000\">v0.12.0</span>\n", |
|||
"\n", |
|||
"</pre>\n" |
|||
], |
|||
"text/plain": [ |
|||
"<rich.jupyter.JupyterRenderable at 0x7f2157da0e80>" |
|||
] |
|||
}, |
|||
"metadata": {}, |
|||
"output_type": "display_data" |
|||
} |
|||
], |
|||
"source": [ |
|||
"from manim import *" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "24037488", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Míchání" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 2, |
|||
"id": "252d64a3", |
|||
"metadata": {}, |
|||
"outputs": [ |
|||
{ |
|||
"name": "stderr", |
|||
"output_type": "stream", |
|||
"text": [ |
|||
" \r" |
|||
] |
|||
}, |
|||
{ |
|||
"data": { |
|||
"text/html": [ |
|||
"<video src=\"media/jupyter/Shuffle@2021-12-03@16-30-04.mp4\" controls autoplay loop style=\"max-width: 60%;\" >\n", |
|||
" Your browser does not support the <code>video</code> element.\n", |
|||
" </video>" |
|||
], |
|||
"text/plain": [ |
|||
"<IPython.core.display.Video object>" |
|||
] |
|||
}, |
|||
"metadata": {}, |
|||
"output_type": "display_data" |
|||
} |
|||
], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh Shuffle\n", |
|||
"\n", |
|||
"from random import *\n", |
|||
"\n", |
|||
"\n", |
|||
"class Shuffle(Scene):\n", |
|||
" def construct(self):\n", |
|||
" seed(0xdeadbeef)\n", |
|||
" \n", |
|||
" # počet hodnot k míchání\n", |
|||
" n = 5\n", |
|||
"\n", |
|||
" circles = [\n", |
|||
" Circle(color=WHITE, fill_opacity=0.8, fill_color=WHITE).scale(0.6)\n", |
|||
" for _ in range(n)\n", |
|||
" ]\n", |
|||
"\n", |
|||
" # mezery mezi kruhy\n", |
|||
" spacing = 2\n", |
|||
" for i, circle in enumerate(circles):\n", |
|||
" circle.shift(RIGHT * (i - (len(circles) - 1) / 2) * spacing)\n", |
|||
"\n", |
|||
" self.play(*[Write(circle) for circle in circles])\n", |
|||
"\n", |
|||
" # vybraný kruh\n", |
|||
" selected = randint(0, n - 1)\n", |
|||
" self.play(circles[selected].animate.set_color(RED))\n", |
|||
" self.play(circles[selected].animate.set_color(WHITE))\n", |
|||
"\n", |
|||
" # postupné zrychlování při navazujících prohozeních\n", |
|||
" swaps = 13\n", |
|||
" speed_start = 1\n", |
|||
" speed_end = 0.2\n", |
|||
"\n", |
|||
" for i in range(swaps):\n", |
|||
" speed = speed_start - abs(speed_start - speed_end) / swaps * i\n", |
|||
" \n", |
|||
" # vybrání dvou různých náhodných kruhů\n", |
|||
" a, b = sample(range(n), 2)\n", |
|||
" \n", |
|||
" # prohození s o trochu větším úhlem, jinak přes sebe kruhy procházejí, což není hezké\n", |
|||
" self.play(\n", |
|||
" Swap(circles[a], circles[b]), run_time=speed, path_arc=135 * DEGREES\n", |
|||
" )\n", |
|||
"\n", |
|||
" # zvýraznění původních kruhů\n", |
|||
" self.play(circles[selected].animate.set_color(RED))\n", |
|||
" self.play(circles[selected].animate.set_color(WHITE))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "c5b2a96d", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Třízení" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 3, |
|||
"id": "72c49f8f", |
|||
"metadata": {}, |
|||
"outputs": [ |
|||
{ |
|||
"name": "stderr", |
|||
"output_type": "stream", |
|||
"text": [ |
|||
" \r" |
|||
] |
|||
}, |
|||
{ |
|||
"data": { |
|||
"text/html": [ |
|||
"<video src=\"media/jupyter/Sort@2021-12-03@16-32-06.mp4\" controls autoplay loop style=\"max-width: 60%;\" >\n", |
|||
" Your browser does not support the <code>video</code> element.\n", |
|||
" </video>" |
|||
], |
|||
"text/plain": [ |
|||
"<IPython.core.display.Video object>" |
|||
] |
|||
}, |
|||
"metadata": {}, |
|||
"output_type": "display_data" |
|||
} |
|||
], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh Sort\n", |
|||
"\n", |
|||
"from random import *\n", |
|||
"\n", |
|||
"\n", |
|||
"class Sort(Scene):\n", |
|||
" def construct(self):\n", |
|||
" seed(0xdeadbeef)\n", |
|||
" \n", |
|||
" # počet hodnot ke třízení\n", |
|||
" n = 20\n", |
|||
"\n", |
|||
" # nejmenší a největší hodnta\n", |
|||
" value_min, value_max = 1, 20\n", |
|||
"\n", |
|||
" # hodnoty v poli\n", |
|||
" values = [randint(value_min, value_max) for _ in range(n)]\n", |
|||
"\n", |
|||
" # šířka čtverce a výška jedné hodnoty (tzn. číslo 5 má výšku 5 * unit_height)\n", |
|||
" rectangle_width = 0.2\n", |
|||
" unit_height = 0.2\n", |
|||
"\n", |
|||
" # mezera mezi obdélníky\n", |
|||
" rectangle_spacing = 2.5\n", |
|||
" \n", |
|||
" rectangles = [\n", |
|||
" Rectangle(\n", |
|||
" width=rectangle_width,\n", |
|||
" height=unit_height * v,\n", |
|||
" fill_color=WHITE,\n", |
|||
" fill_opacity=1,\n", |
|||
" )\n", |
|||
" for v in values\n", |
|||
" ]\n", |
|||
" \n", |
|||
" # bod, podle kterého budeme rovnat spodek přes funkci align_to\n", |
|||
" # aby byly čtverce vycentrované, bude odpovídat spodku nejvyšší hodnoty\n", |
|||
" alignment_point = None\n", |
|||
" max_value = 0\n", |
|||
" for i, v in enumerate(values):\n", |
|||
" if max_value < v:\n", |
|||
" max_value = v\n", |
|||
" alignment_point = Point().shift(DOWN * rectangles[i].height / 2)\n", |
|||
"\n", |
|||
" # posun obdélníků tak, aby byly rovnoměrně rozprostřené a zarovnané dolů\n", |
|||
" for i, rect in enumerate(rectangles):\n", |
|||
" rect.shift(\n", |
|||
" RIGHT\n", |
|||
" * (i - (len(rectangles) - 1) / 2)\n", |
|||
" * rectangle_width\n", |
|||
" * rectangle_spacing\n", |
|||
" ).align_to(alignment_point, DOWN)\n", |
|||
"\n", |
|||
" self.play(*[Write(r) for r in rectangles])\n", |
|||
"\n", |
|||
" def animate_at(a, b, duration):\n", |
|||
" \"\"\"Animace toho, že se aktuálně díváme na pozice a a b.\"\"\"\n", |
|||
" self.play(\n", |
|||
" *[\n", |
|||
" r.animate.set_color(WHITE if i not in (a, b) else YELLOW)\n", |
|||
" for i, r in enumerate(rectangles)\n", |
|||
" ],\n", |
|||
" run_time=duration,\n", |
|||
" )\n", |
|||
"\n", |
|||
" def animate_swap(a, b, duration):\n", |
|||
" \"\"\"Animace prohození a a b (s tím, že v poli values už jsou prohozené).\"\"\"\n", |
|||
" self.play(\n", |
|||
" # jelikož stretch_to_fit_height stretchuje z prostředku, musíme alignnout na bod\n", |
|||
" rectangles[a]\n", |
|||
" .animate.stretch_to_fit_height(values[a] * unit_height)\n", |
|||
" .align_to(alignment_point, DOWN),\n", |
|||
" rectangles[b]\n", |
|||
" .animate.stretch_to_fit_height(values[b] * unit_height)\n", |
|||
" .align_to(alignment_point, DOWN),\n", |
|||
" run_time=duration,\n", |
|||
" )\n", |
|||
"\n", |
|||
" # při prvním průchodu jsou animace pomalejší\n", |
|||
" speed_slow = 0.6\n", |
|||
" speed_fast = 0.07\n", |
|||
"\n", |
|||
" for i in range(n):\n", |
|||
" speed = speed_slow if i == 0 else speed_fast\n", |
|||
" swapped = False\n", |
|||
" for j in range(n - i - 1):\n", |
|||
" animate_at(j, j + 1, speed)\n", |
|||
"\n", |
|||
" if values[j] > values[j + 1]:\n", |
|||
" values[j], values[j + 1] = values[j + 1], values[j]\n", |
|||
"\n", |
|||
" animate_swap(j, j + 1, speed)\n", |
|||
" swapped = True\n", |
|||
"\n", |
|||
" # pokud jsme při průchodu nic neprohodili, tak už není co třídit\n", |
|||
" if not swapped:\n", |
|||
" break\n", |
|||
"\n", |
|||
" self.play(*[FadeOut(r) for r in rectangles])" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "7a4c30a9", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Vyhledávání" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": 4, |
|||
"id": "07983bb0", |
|||
"metadata": {}, |
|||
"outputs": [ |
|||
{ |
|||
"name": "stderr", |
|||
"output_type": "stream", |
|||
"text": [ |
|||
" \r" |
|||
] |
|||
}, |
|||
{ |
|||
"data": { |
|||
"text/html": [ |
|||
"<video src=\"media/jupyter/Search@2021-12-03@16-32-19.mp4\" controls autoplay loop style=\"max-width: 60%;\" >\n", |
|||
" Your browser does not support the <code>video</code> element.\n", |
|||
" </video>" |
|||
], |
|||
"text/plain": [ |
|||
"<IPython.core.display.Video object>" |
|||
] |
|||
}, |
|||
"metadata": {}, |
|||
"output_type": "display_data" |
|||
} |
|||
], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh Search\n", |
|||
"\n", |
|||
"from random import *\n", |
|||
"\n", |
|||
"\n", |
|||
"class Search(Scene):\n", |
|||
" def construct(self):\n", |
|||
" seed(0xdeadbeef4) # hezčí vstup :)\n", |
|||
" \n", |
|||
" # počet hodnot ke třízení\n", |
|||
" n = 10\n", |
|||
"\n", |
|||
" # nejmenší a největší hodnta\n", |
|||
" value_min, value_max = 1, n\n", |
|||
"\n", |
|||
" # hodnoty v poli\n", |
|||
" values = sorted([randint(value_min, value_max) for _ in range(n)])\n", |
|||
"\n", |
|||
" square_side_length = 0.75\n", |
|||
" square_spacing = 1.3\n", |
|||
"\n", |
|||
" squares = [Square(side_length=square_side_length) for v in values]\n", |
|||
" numbers = [Tex(f\"${v}$\") for v in values]\n", |
|||
"\n", |
|||
" # posun čtverců tak, aby byly uprostřed obrazovky\n", |
|||
" for i, rect in enumerate(squares):\n", |
|||
" rect.shift(\n", |
|||
" RIGHT\n", |
|||
" * (i - (len(squares) - 1) / 2)\n", |
|||
" * square_side_length\n", |
|||
" * square_spacing\n", |
|||
" )\n", |
|||
"\n", |
|||
" # posun textu tak, aby byly uvnitř čtverců\n", |
|||
" for i, number in enumerate(numbers):\n", |
|||
" number.move_to(squares[i])\n", |
|||
"\n", |
|||
" # pointery na to, kde aktuálně jsme\n", |
|||
" pointer_length = 0.4\n", |
|||
" l_arrow = Arrow(start=DOWN * pointer_length, end=UP).next_to(squares[0], DOWN)\n", |
|||
" r_arrow = Arrow(start=DOWN * pointer_length, end=UP).next_to(squares[-1], DOWN)\n", |
|||
"\n", |
|||
" self.play(*[Write(s) for s in squares], *[Write(n) for n in numbers])\n", |
|||
"\n", |
|||
" # vypsání čísla, které hledáme\n", |
|||
" target = randint(value_min, value_max)\n", |
|||
" text = Tex(f\"Hledáme: ${target}$\").shift(UP * 1.5)\n", |
|||
"\n", |
|||
" self.play(Write(text))\n", |
|||
"\n", |
|||
" self.play(Write(l_arrow), Write(r_arrow))\n", |
|||
"\n", |
|||
" lo, hi = 0, len(values) - 1\n", |
|||
"\n", |
|||
" def color_in_range(objects, color, range):\n", |
|||
" \"\"\"Vrátí seznam animací vybarvení daných objektů v daném rozmezí.\"\"\"\n", |
|||
" return [\n", |
|||
" o.animate.set_color(color) for i, o in enumerate(objects) if i in range\n", |
|||
" ]\n", |
|||
"\n", |
|||
" # samotný algoritmus\n", |
|||
" while lo < hi:\n", |
|||
" avg = (lo + hi) // 2\n", |
|||
" \n", |
|||
" # vykreslení pointeru u aktuálního prvku\n", |
|||
" current_arrow = Arrow(start=DOWN * pointer_length, end=UP) \\\n", |
|||
" .next_to(squares[avg], DOWN) \\\n", |
|||
" .set_color(ORANGE)\n", |
|||
" \n", |
|||
" self.play(Write(current_arrow))\n", |
|||
"\n", |
|||
" if values[avg] < target:\n", |
|||
" # posunutí levého pointeru\n", |
|||
" self.play(\n", |
|||
" FadeOut(current_arrow),\n", |
|||
" l_arrow.animate.next_to(squares[avg + 1], DOWN),\n", |
|||
" *color_in_range(squares, DARK_GRAY, range(lo, avg + 1)),\n", |
|||
" *color_in_range(numbers, DARK_GRAY, range(lo, avg + 1)),\n", |
|||
" )\n", |
|||
"\n", |
|||
" lo = avg + 1\n", |
|||
" elif values[avg] >= target:\n", |
|||
" # posunutí pravého pointeru\n", |
|||
" self.play(\n", |
|||
" FadeOut(current_arrow),\n", |
|||
" r_arrow.animate.next_to(squares[avg], DOWN),\n", |
|||
" *color_in_range(squares, DARK_GRAY, range(avg + 1, hi + 1)),\n", |
|||
" *color_in_range(numbers, DARK_GRAY, range(avg + 1, hi + 1)),\n", |
|||
" )\n", |
|||
"\n", |
|||
" hi = avg\n", |
|||
"\n", |
|||
" # nalezení hledané hodnoty\n", |
|||
" if values[hi] == target:\n", |
|||
" self.play(\n", |
|||
" *color_in_range(squares, DARK_GRAY, range(hi)),\n", |
|||
" *color_in_range(squares, DARK_GRAY, range(hi+1, n)),\n", |
|||
" *color_in_range(numbers, DARK_GRAY, range(hi)),\n", |
|||
" *color_in_range(numbers, DARK_GRAY, range(hi+1, n)),\n", |
|||
" numbers[hi].animate.set_color(GREEN),\n", |
|||
" squares[hi].animate.set_color(GREEN),\n", |
|||
" FadeOut(l_arrow),\n", |
|||
" )\n", |
|||
" break\n", |
|||
" \n", |
|||
" \n", |
|||
" self.play(*[FadeOut(r) for r in numbers + squares + [r_arrow, text]])" |
|||
] |
|||
} |
|||
], |
|||
"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.9.7" |
|||
} |
|||
}, |
|||
"nbformat": 4, |
|||
"nbformat_minor": 5 |
|||
} |
@ -0,0 +1,472 @@ |
|||
{ |
|||
"cells": [ |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "substantial-impact", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"# Vítej!" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "first-armenia", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"Tento dokument obsahuje zdrojové kódy animací k této sérii seriálu, které jdou upravovat a přehrávat bez toho, aby bylo potřeba cokoliv instalovat. Části dokumentu, u kterých je nalevo `In [ ]:` obsahují kód a jdou spustit - stačí je levým tlačítkem vybrat a nahoře zmáčkout `▶`." |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "badc1af7", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"Zkuste to u následujícího příkazu, který pro zbytek dokumentu importuje všechno potřebné pro spouštění Manimu (bez něho animace nepoběží)." |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "e03b150c", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"from manim import *" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "honest-cruise", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## KSP logo" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "governing-increase", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"Animace loga KSP z úvodu seriálu (je v pořádku, že některé jeho části vám ještě nedávají smysl)." |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "wound-foundation", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm KSPLogo\n", |
|||
"\n", |
|||
"\n", |
|||
"class KSPLogo(Scene):\n", |
|||
" def construct(self):\n", |
|||
" # na černém pozadí hrošík není vidět...\n", |
|||
" self.camera.background_color = WHITE\n", |
|||
"\n", |
|||
" hroch = SVGMobject(\"serial1/hroch.svg\").scale(2)\n", |
|||
" self.play(Write(hroch))\n", |
|||
"\n", |
|||
" logo = Tex(\"KSP\", color=BLACK).scale(2.5)\n", |
|||
" self.bring_to_back(logo)\n", |
|||
"\n", |
|||
" self.play(logo.animate.shift(DOWN * 2.3), hroch.animate.shift(UP * 0.6))\n", |
|||
"\n", |
|||
" logo_expanded = Tex(\"Korespondenční Seminář z Programování\", color=BLACK) \\\n", |
|||
" .scale(1.3) \\\n", |
|||
" .move_to(logo)\n", |
|||
" \n", |
|||
" self.play(TransformMatchingShapes(logo, logo_expanded))\n", |
|||
" \n", |
|||
" self.play(FadeOut(logo_expanded), FadeOut(hroch))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "e6050303", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"Příkaz `manim -v WARNING -qm KSPLogo` volá program Manim na scénu `KSPLogo`. Část `-v WARNING` tlumí výpis nedůležitých informací (zkuste pro zajímavost spustit kód bez něho) a `-qm` nastavuje kvalitu (`q`uality) videa na střední (`m`edium; další dostupné kvality jsou `l`ow, `h`igh a 4`k`)." |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "1fa02f58", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Úvod" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "d63a1c09", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm Intro\n", |
|||
"\n", |
|||
"\n", |
|||
"class Intro(Scene):\n", |
|||
" def construct(self):\n", |
|||
" # vytvoření objektů čtverce a kruhu (a jejich posunutí)\n", |
|||
" square = Square(color=RED).shift(LEFT * 2)\n", |
|||
" circle = Circle(color=BLUE).shift(RIGHT * 2)\n", |
|||
"\n", |
|||
" # napsaní čtverce a kruhu na scénu\n", |
|||
" self.play(Write(square), Write(circle))\n", |
|||
"\n", |
|||
" # schování čtverce a kruhu ze scény\n", |
|||
" self.play(FadeOut(square), FadeOut(circle), run_time=2)" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "ed91705e", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## `animate` syntax" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "870dad88", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm Animate\n", |
|||
"\n", |
|||
"\n", |
|||
"class Animate(Scene):\n", |
|||
" def construct(self):\n", |
|||
" square = Square(color=RED).shift(LEFT * 2)\n", |
|||
" circle = Circle(color=BLUE).shift(RIGHT * 2)\n", |
|||
"\n", |
|||
" self.play(Write(square), Write(circle))\n", |
|||
"\n", |
|||
" # posunutí objektů\n", |
|||
" self.play(square.animate.shift(UP * 0.5), circle.animate.shift(DOWN * 0.5))\n", |
|||
"\n", |
|||
" # otočení a vybarvení vnitřku čtverce (průhlednost 80%)\n", |
|||
" # zvětšení a vybarvení vnitřku kruhu (průhlednost 80%)\n", |
|||
" self.play(\n", |
|||
" square.animate.rotate(PI / 2).set_fill(RED, 0.8),\n", |
|||
" circle.animate.scale(2).set_fill(BLUE, 0.8),\n", |
|||
" )\n", |
|||
" \n", |
|||
" # úplné přebarvení kruhu i čtverce (obrys i výplň)\n", |
|||
" # stejné jako .set_fill() + .set_stroke()\n", |
|||
" self.play(\n", |
|||
" square.animate.set_color(GREEN),\n", |
|||
" circle.animate.set_color(ORANGE),\n", |
|||
" )\n", |
|||
" \n", |
|||
" self.play(FadeOut(square), FadeOut(circle))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "f5464852", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Posouvání objektů" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "b1973f27", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm NextTo\n", |
|||
"\n", |
|||
"\n", |
|||
"class NextTo(Scene):\n", |
|||
" def construct(self):\n", |
|||
" # vytvoření čtyřech menších kruhů\n", |
|||
" c1, c2, c3, c4 = [Circle(radius=0.5, color=WHITE) for _ in range(4)]\n", |
|||
"\n", |
|||
" # a jednoho obélníku\n", |
|||
" rectangle = Rectangle(width=5, height=3)\n", |
|||
" \n", |
|||
" # posunutí kruhů tak, aby byly okolo obdélníku\n", |
|||
" c1.next_to(rectangle, LEFT) # nalevo od\n", |
|||
" c2.next_to(rectangle, UP) # nahoře od\n", |
|||
" c3.next_to(rectangle, RIGHT) # napravo od\n", |
|||
" c4.next_to(rectangle, DOWN) # dolů od\n", |
|||
"\n", |
|||
" self.play(*[Write(o) for o in [c1, c2, c3, c4, rectangle]])" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "7f32d0db", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm MoveTo\n", |
|||
"\n", |
|||
"\n", |
|||
"class MoveTo(Scene):\n", |
|||
" def construct(self):\n", |
|||
" s1, s2, s3 = [Square() for _ in range(3)]\n", |
|||
" \n", |
|||
" self.play(*[Write(o) for o in [s1, s2, s3]])\n", |
|||
" \n", |
|||
" # posunutí čtverců vedle sebe\n", |
|||
" self.play(\n", |
|||
" s1.animate.next_to(s2, LEFT),\n", |
|||
" s3.animate.next_to(s2, RIGHT),\n", |
|||
" )\n", |
|||
" \n", |
|||
" # jim odpovídající čísla\n", |
|||
" t1, t2, t3 = [Tex(f\"${i}$\").scale(3) for i in range(3)]\n", |
|||
" \n", |
|||
" # posunutí čísel do středů čtverců\n", |
|||
" t1.move_to(s1)\n", |
|||
" t2.move_to(s2)\n", |
|||
" t3.move_to(s3)\n", |
|||
" \n", |
|||
" self.play(*[Write(o) for o in [t1, t2, t3]])" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "54dc3698", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm AlignTo\n", |
|||
"\n", |
|||
"\n", |
|||
"class AlignTo(Scene):\n", |
|||
" def construct(self):\n", |
|||
" # vytvoření tří různě velikých kruhů\n", |
|||
" c1, c2, c3 = [Circle(radius=1.5 - i / 3, color=WHITE) for i in range(3)]\n", |
|||
"\n", |
|||
" self.play(*[Write(o) for o in [c1, c2, c3]])\n", |
|||
"\n", |
|||
" # c1 a c3 vedle c2\n", |
|||
" self.play(\n", |
|||
" c1.animate.next_to(c2, LEFT),\n", |
|||
" c3.animate.next_to(c2, RIGHT),\n", |
|||
" )\n", |
|||
"\n", |
|||
" # spodek c1 a c3 je stejný jako c2\n", |
|||
" self.play(\n", |
|||
" c1.animate.align_to(c2, DOWN),\n", |
|||
" c3.animate.align_to(c2, DOWN),\n", |
|||
" )\n", |
|||
"\n", |
|||
" # vršek c1, c2 a c3 je vyrovnaný s bodem\n", |
|||
" point = Point([0, 2.5, 0])\n", |
|||
"\n", |
|||
" self.play(\n", |
|||
" c1.animate.align_to(point, UP),\n", |
|||
" c2.animate.align_to(point, UP),\n", |
|||
" c3.animate.align_to(point, UP),\n", |
|||
" )" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "53e6209b", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Sázení textu a matematiky" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "a0de016f", |
|||
"metadata": { |
|||
"scrolled": true |
|||
}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm TextAndMath\n", |
|||
"\n", |
|||
"\n", |
|||
"class TextAndMath(Scene):\n", |
|||
" def construct(self):\n", |
|||
" text = Tex(\"Tohle je text!\").shift(LEFT * 2.5)\n", |
|||
" \n", |
|||
" # ke snazšímu psaní \\ používáme r-stringy (před stringem je 'r')\n", |
|||
" # znamená to, že znaky '\\' jsou brány doslova (v normálním stringu by bylo potřeba psát \\\\)\n", |
|||
" formula = MathTex(r\"\\sum_{i = 0}^\\infty \\frac{1}{2^i} = 2\").shift(RIGHT * 2.5)\n", |
|||
"\n", |
|||
" self.play(Write(formula), Write(text))\n", |
|||
"\n", |
|||
" self.play(FadeOut(formula), FadeOut(text))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "98daca2b", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Kostry úloh" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "ec0a8c9a", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"### Míchání [4b]" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "d4d6c6e8", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm Shuffle\n", |
|||
"\n", |
|||
"\n", |
|||
"class Shuffle(Scene):\n", |
|||
" def construct(self):\n", |
|||
" pass" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "b8327d92", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh ShuffleExample\n", |
|||
"\n", |
|||
"class ShuffleExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" c11 = Circle(color=WHITE).shift(UP * 1.5 + LEFT * 2)\n", |
|||
" c12 = Circle(color=WHITE).shift(UP * 1.5 + RIGHT * 2)\n", |
|||
" c21 = Circle(color=WHITE).shift(DOWN * 1.5 + LEFT * 2)\n", |
|||
" c22 = Circle(color=WHITE).shift(DOWN * 1.5 + RIGHT * 2)\n", |
|||
"\n", |
|||
" self.play(Write(c11), Write(c12), Write(c21), Write(c22))\n", |
|||
"\n", |
|||
" self.play(Swap(c11, c21))\n", |
|||
"\n", |
|||
" self.play(Swap(c12, c22, path_arc=160 * DEGREES))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "6e2024fc", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"### Třízení [6b]" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "2736f1be", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm Sort\n", |
|||
"\n", |
|||
"\n", |
|||
"class Sort(Scene):\n", |
|||
" def construct(self):\n", |
|||
" pass" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "54e8ed05", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm StretchToFitHeightExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class StretchToFitHeightExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" s1 = Square().shift(LEFT * 2.5)\n", |
|||
" s2 = Square().shift(RIGHT * 2.5)\n", |
|||
"\n", |
|||
" self.play(Write(s1), Write(s2))\n", |
|||
"\n", |
|||
" self.play(\n", |
|||
" s1.animate.stretch_to_fit_height(3.5),\n", |
|||
" s2.animate.set_height(3.5),\n", |
|||
" )" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "5e5ac98b", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"### Vyhledávání [5b]" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "cdcf26cc", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm Search\n", |
|||
"\n", |
|||
"\n", |
|||
"class Search(Scene):\n", |
|||
" def construct(self):\n", |
|||
" pass" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "9f62d7a5", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qm ArrowExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class ArrowExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" a1 = Arrow(start=UP, end=DOWN).shift(LEFT * 2)\n", |
|||
" a2 = Arrow(start=DOWN, end=UP).shift(RIGHT * 2)\n", |
|||
"\n", |
|||
" self.play(Write(a1), Write(a2))" |
|||
] |
|||
} |
|||
], |
|||
"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.9.9" |
|||
} |
|||
}, |
|||
"nbformat": 4, |
|||
"nbformat_minor": 5 |
|||
} |
@ -0,0 +1,329 @@ |
|||
{ |
|||
"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 |
|||
} |
@ -0,0 +1,748 @@ |
|||
{ |
|||
"cells": [ |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "substantial-impact", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"# Vítej!" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "first-armenia", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"Tento dokument obsahuje zdrojové kódy animací ke druhé sérii seriálu KSP. Před spouštěním opět nezapomeň Manim importovat spuštěním následujícího řádku!" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "e03b150c", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"from manim import *" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "45897e9c", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Práce se skupinami objektů" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "wound-foundation", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh VGroupExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class VGroupExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" s1 = Square(color=RED)\n", |
|||
" s2 = Square(color=GREEN)\n", |
|||
" s3 = Square(color=BLUE)\n", |
|||
"\n", |
|||
" s1.next_to(s2, LEFT)\n", |
|||
" s3.next_to(s2, RIGHT)\n", |
|||
"\n", |
|||
" self.play(Write(s1), Write(s2), Write(s3))\n", |
|||
"\n", |
|||
" group = VGroup(s1, s2, s3)\n", |
|||
"\n", |
|||
" # aplikace škálování na celou skupinu\n", |
|||
" self.play(group.animate.scale(1.5).shift(UP))\n", |
|||
"\n", |
|||
" # na skupině můžeme indexovat\n", |
|||
" self.play(group[1].animate.shift(DOWN * 2))\n", |
|||
"\n", |
|||
" # změna barvy se aplikuje na všechny objekty\n", |
|||
" self.play(group.animate.set_color(WHITE))\n", |
|||
" self.play(group.animate.set_fill(WHITE, 1))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "659287fa", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh ArrangeExample\n", |
|||
"\n", |
|||
"from random import seed, uniform\n", |
|||
"\n", |
|||
"\n", |
|||
"class ArrangeExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" seed(0xDEADBEEF)\n", |
|||
"\n", |
|||
" # používáme *, protože VGroup bere samotné objekty (viz minulý příklad)\n", |
|||
" circles = VGroup(\n", |
|||
" *[\n", |
|||
" Circle(radius=0.1)\n", |
|||
" .scale(uniform(0.5, 4))\n", |
|||
" .shift(UP * uniform(-3, 3) + RIGHT * uniform(-5, 5))\n", |
|||
" for _ in range(12)\n", |
|||
" ]\n", |
|||
" )\n", |
|||
"\n", |
|||
" self.play(FadeIn(circles))\n", |
|||
"\n", |
|||
" # uspořádání vedle sebe\n", |
|||
" self.play(circles.animate.arrange())\n", |
|||
"\n", |
|||
" # různé odsazení a směry\n", |
|||
" self.play(circles.animate.arrange(direction=DOWN, buff=0.1))\n", |
|||
" self.play(circles.animate.arrange(buff=0.4))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "ff1ab3fd", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh ArrangeInGridExample\n", |
|||
"\n", |
|||
"from random import seed, uniform\n", |
|||
"\n", |
|||
"\n", |
|||
"class ArrangeInGridExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" seed(0xDEADBEEF)\n", |
|||
"\n", |
|||
" circles = VGroup(\n", |
|||
" *[\n", |
|||
" Circle(radius=0.1)\n", |
|||
" .scale(uniform(0.5, 2))\n", |
|||
" .shift(UP * uniform(-3, 3) + RIGHT * uniform(-5, 5))\n", |
|||
" for _ in range(9 ** 2)\n", |
|||
" ]\n", |
|||
" )\n", |
|||
"\n", |
|||
" self.play(FadeIn(circles))\n", |
|||
"\n", |
|||
" # uspořádání do mřížky\n", |
|||
" self.play(circles.animate.arrange_in_grid())\n", |
|||
"\n", |
|||
" # různé odsazení a počet řádků/sloupců\n", |
|||
" self.play(circles.animate.arrange_in_grid(rows=5, buff=0))\n", |
|||
" self.play(circles.animate.arrange_in_grid(cols=12, buff=0.3))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "fc6ccd7e", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Přidávání a odebírání objektů" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "68f328dd", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh AddRemoveExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class AddRemoveExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" square = Square(fill_color=WHITE, fill_opacity=1)\n", |
|||
" small_scale = 0.6\n", |
|||
"\n", |
|||
" triangle = Triangle(fill_opacity=1).scale(small_scale).move_to(square)\n", |
|||
"\n", |
|||
" self.play(Write(square))\n", |
|||
"\n", |
|||
" # přidání trojúhelníku pod čtverec\n", |
|||
" self.bring_to_back(triangle)\n", |
|||
" self.play(square.animate.shift(LEFT * 2))\n", |
|||
"\n", |
|||
" circle = Circle(fill_opacity=1).scale(small_scale).move_to(square)\n", |
|||
"\n", |
|||
" # přidání kruhu pod čtverec\n", |
|||
" self.bring_to_back(circle)\n", |
|||
" self.play(square.animate.shift(RIGHT * 2))\n", |
|||
"\n", |
|||
" square2 = (\n", |
|||
" Square(stroke_color=GREEN, fill_color=GREEN, fill_opacity=1)\n", |
|||
" .scale(small_scale)\n", |
|||
" .move_to(square)\n", |
|||
" )\n", |
|||
" \n", |
|||
" self.remove(triangle)\n", |
|||
" \n", |
|||
" # stejné jako self.add\n", |
|||
" # přidání dopředu tu spíš nechceme, ale je dobré vidět co dělá\n", |
|||
" self.bring_to_front(square2)\n", |
|||
"\n", |
|||
" self.play(square.animate.shift(RIGHT * 2))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "07e6819f", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Překrývající-se animace" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "d63a1c09", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh AnimationGroupExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class AnimationGroupExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" c1 = Square(color=RED)\n", |
|||
" c2 = Square(color=GREEN)\n", |
|||
" c3 = Square(color=BLUE)\n", |
|||
"\n", |
|||
" VGroup(c1, c2, c3).arrange(buff=1)\n", |
|||
"\n", |
|||
" # každá další animace se spustí v polovině té předchozí (0.5)\n", |
|||
" self.play(AnimationGroup(Write(c1), Write(c2), Write(c3), lag_ratio=0.5))\n", |
|||
"\n", |
|||
" # každá další animace se spustí v desetině té předchozí (0.1)\n", |
|||
" self.play(AnimationGroup(FadeOut(c1), FadeOut(c2), FadeOut(c3), lag_ratio=0.1))\n", |
|||
"\n", |
|||
" # jedna z animací může být rovněž skupina, která může mít sama o sobě zpoždění\n", |
|||
" self.play(\n", |
|||
" AnimationGroup(\n", |
|||
" AnimationGroup(Write(c1), Write(c2), lag_ratio=0.1),\n", |
|||
" Write(c3),\n", |
|||
" lag_ratio=0.5,\n", |
|||
" )\n", |
|||
" )\n", |
|||
"\n", |
|||
" # lag_ratio může být i záporné (animace se budou spouštět obráceně)\n", |
|||
" self.play(AnimationGroup(FadeOut(c1), FadeOut(c2), FadeOut(c3), lag_ratio=-0.1))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "4412a01b", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh VGroupLagRatioExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class VGroupLagRatioExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" squares = VGroup(Square(), Square(), Square()).arrange(buff=0.5).scale(1.5)\n", |
|||
" \n", |
|||
" # postupné vykreslení čtverců\n", |
|||
" self.play(Write(squares))\n", |
|||
"\n", |
|||
" # FadeOut lag_ratio má nulové, animace se vykonají najednou\n", |
|||
" self.play(FadeOut(squares))\n", |
|||
"\n", |
|||
" squares.set_color(BLUE)\n", |
|||
" \n", |
|||
" # lag_ratio můžeme manuálně nastavit tak, aby se čtverce vykreslily najednou \n", |
|||
" self.play(Write(squares, lag_ratio=0))\n", |
|||
"\n", |
|||
" self.play(FadeOut(squares, lag_ratio=0.5))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "1fa02f58", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Práce s pozorností" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "a3d83c22", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh AttentionExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class AttentionExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" c1 = Square()\n", |
|||
"\n", |
|||
" labels = [\n", |
|||
" Tex(\"Flash\"),\n", |
|||
" Tex(\"Indicate\"),\n", |
|||
" Tex(\"Wiggle\"),\n", |
|||
" Tex(\"FocusOn\"),\n", |
|||
" Tex(\"Circumscribe\"),\n", |
|||
" ]\n", |
|||
"\n", |
|||
" # labely posuneme dolů (pod čtverec)\n", |
|||
" for label in labels:\n", |
|||
" label.shift(DOWN * 1.5).scale(1.5)\n", |
|||
"\n", |
|||
" def switch_labels(i: int):\n", |
|||
" \"\"\"Animace přeměny jednoho labelu na druhého.\"\"\"\n", |
|||
" return AnimationGroup(\n", |
|||
" FadeOut(labels[i], shift=UP * 0.7),\n", |
|||
" FadeIn(labels[i + 1], shift=UP * 0.7),\n", |
|||
" )\n", |
|||
"\n", |
|||
" self.play(Write(c1))\n", |
|||
"\n", |
|||
" self.play(FadeIn(labels[0], shift=UP * 0.5), c1.animate.shift(UP))\n", |
|||
"\n", |
|||
" # Flash\n", |
|||
" self.play(Flash(c1, flash_radius=1.6, num_lines=20))\n", |
|||
"\n", |
|||
" # Indicate\n", |
|||
" self.play(AnimationGroup(switch_labels(0), Indicate(c1), lag_ratio=0.7))\n", |
|||
"\n", |
|||
" # Wiggle\n", |
|||
" self.play(AnimationGroup(switch_labels(1), Wiggle(c1), lag_ratio=0.7))\n", |
|||
"\n", |
|||
" # FocusOn\n", |
|||
" self.play(AnimationGroup(switch_labels(2), FocusOn(c1), lag_ratio=0.7))\n", |
|||
"\n", |
|||
" # Circumscribe\n", |
|||
" self.play(AnimationGroup(switch_labels(3), Circumscribe(c1), lag_ratio=0.7))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "a9d9d8db", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Transformace" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "e2510a0d", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh BasicTransformExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class BasicTransformExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" c = Circle().scale(2)\n", |
|||
" s = Square().scale(2)\n", |
|||
"\n", |
|||
" self.play(Write(c))\n", |
|||
"\n", |
|||
" self.play(Transform(c, s))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "8561d8a8", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh BadTransformExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class BadTransformExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" good = [Circle(color=GREEN), Square(color=GREEN), Triangle(color=GREEN)]\n", |
|||
" bad = [Circle(color=RED), Square(color=RED), Triangle(color=RED)]\n", |
|||
"\n", |
|||
" # uspořádání do mřížky - nahoře dobré, dole špatné\n", |
|||
" VGroup(*(good + bad)).arrange_in_grid(rows=2, buff=1)\n", |
|||
"\n", |
|||
" self.play(Write(good[0]), Write(bad[0]))\n", |
|||
"\n", |
|||
" self.play(\n", |
|||
" Transform(good[0], good[1]),\n", |
|||
" Transform(bad[0], bad[1]),\n", |
|||
" )\n", |
|||
"\n", |
|||
" self.play(\n", |
|||
" Transform(good[0], good[2]),\n", |
|||
" Transform(bad[1], bad[2]),\n", |
|||
" )" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "0eda62fe", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh TransformMatchingShapesExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class TransformMatchingShapesExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" ksp_matching = Tex(\"KSP\").scale(5)\n", |
|||
" ksp_full_matching = Tex(\"Korespondenční Seminář z Programování\")\n", |
|||
"\n", |
|||
" ksp_regular = ksp_matching.copy().set_color(BLUE)\n", |
|||
" ksp_full_regular = ksp_full_matching.copy().set_color(BLUE)\n", |
|||
"\n", |
|||
" VGroup(ksp_matching, ksp_regular).arrange(direction=DOWN, buff=1)\n", |
|||
" ksp_full_matching.move_to(ksp_matching)\n", |
|||
" ksp_full_regular.move_to(ksp_regular)\n", |
|||
"\n", |
|||
" self.play(Write(ksp_matching), Write(ksp_regular))\n", |
|||
"\n", |
|||
" self.play(\n", |
|||
" TransformMatchingShapes(ksp_matching, ksp_full_matching),\n", |
|||
" Transform(ksp_regular, ksp_full_regular),\n", |
|||
" )" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "310fdca9", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Updatery" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "84c90216", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh SimpleUpdaterExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class SimpleUpdaterExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" square = Square()\n", |
|||
" square_label = Tex(\"A neat square.\").next_to(square, UP, buff=0.5)\n", |
|||
"\n", |
|||
" self.play(Write(square))\n", |
|||
" self.play(FadeIn(square_label, shift=UP * 0.5))\n", |
|||
"\n", |
|||
" def label_updater(obj):\n", |
|||
" \"\"\"Updater, který posune objekt nad čtverec.\n", |
|||
"\n", |
|||
" První parametr (obj) je vždy objekt, na který je updater přidaný.\"\"\"\n", |
|||
" obj.next_to(square, UP, buff=0.5)\n", |
|||
"\n", |
|||
" # popisek čtverce chceme mít fixně nad čtvercem\n", |
|||
" square_label.add_updater(label_updater)\n", |
|||
"\n", |
|||
" # vždy zůstává nad čtvercem\n", |
|||
" self.play(square.animate.shift(LEFT * 3))\n", |
|||
" self.play(square.animate.scale(1 / 2))\n", |
|||
" self.play(square.animate.rotate(PI / 2).shift(RIGHT * 3 + DOWN * 0.5).scale(3))\n", |
|||
"\n", |
|||
" # odstranění updateru můžeme udělat přes remove_updater\n", |
|||
" square_label.remove_updater(label_updater)\n", |
|||
" self.play(square.animate.scale(1 / 3))\n", |
|||
" self.play(square.animate.rotate(PI / 2))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "f0a57559", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh BecomeUpdaterExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class BecomeUpdaterExample(Scene):\n", |
|||
" def format_point(self, point):\n", |
|||
" \"\"\"Formátování dané souřadnice na [x, y].\"\"\"\n", |
|||
" return f\"[{point[0]:.2f}, {point[1]:.2f}]\"\n", |
|||
"\n", |
|||
" def construct(self):\n", |
|||
" circle = Circle(color=WHITE)\n", |
|||
"\n", |
|||
" def circle_label_updater(obj):\n", |
|||
" \"\"\"Updater pro label, který jej posouvá nad bod a nastavuje jeho text.\"\"\"\n", |
|||
" obj.become(Tex(f\"p = {self.format_point(circle.get_center())}\"))\n", |
|||
" obj.next_to(circle, UP, buff=0.35)\n", |
|||
"\n", |
|||
" self.play(Write(circle))\n", |
|||
"\n", |
|||
" circle_label = Tex()\n", |
|||
"\n", |
|||
" # používáme tu trochu trik k šetření kódu - updater voláme proto,\n", |
|||
" # abychom nastavili popisek na základní hodnotu a pozici\n", |
|||
" circle_label_updater(circle_label)\n", |
|||
"\n", |
|||
" self.play(FadeIn(circle_label, shift=UP * 0.3))\n", |
|||
"\n", |
|||
" circle_label.add_updater(circle_label_updater)\n", |
|||
"\n", |
|||
" # tato animace se bude pravděpodobně renderovat dlouho, protože\n", |
|||
" # updater v každém snímku vytváří Tex objekt, což nějakou dobu trvá\n", |
|||
" self.play(circle.animate.shift(RIGHT))\n", |
|||
" self.play(circle.animate.shift(LEFT * 3 + UP))\n", |
|||
" self.play(circle.animate.shift(DOWN * 2 + RIGHT * 2))\n", |
|||
" self.play(circle.animate.shift(UP))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "98daca2b", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"## Kostry úloh" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "8746ae11", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"### Trojúhelník [3b]" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "18fb5e35", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh Triangle\n", |
|||
"\n", |
|||
"\n", |
|||
"class Triangle(Scene):\n", |
|||
" def construct(self):\n", |
|||
" pass" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "e9471651", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh LineExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class LineExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" p1 = Dot()\n", |
|||
" p2 = Dot()\n", |
|||
" \n", |
|||
" points = VGroup(p1, p2).arrange(buff=2.5)\n", |
|||
" \n", |
|||
" line = Line(start=p1.get_center(), end=p2.get_center())\n", |
|||
" \n", |
|||
" self.play(Write(p1), Write(p2))\n", |
|||
" \n", |
|||
" self.play(Write(line))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "7bddd3e5", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh CircleFromPointsExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class CircleFromPointsExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" p1 = Dot().shift(LEFT + UP)\n", |
|||
" p2 = Dot().shift(DOWN * 1.5)\n", |
|||
" p3 = Dot().shift(RIGHT + UP)\n", |
|||
" \n", |
|||
" dots = VGroup(p1, p2, p3)\n", |
|||
" \n", |
|||
" # vytvoření kruhu ze tří bodů\n", |
|||
" circle = Circle.from_three_points(p1.get_center(), p2.get_center(), p3.get_center(), color=WHITE)\n", |
|||
" \n", |
|||
" self.play(Write(dots), run_time=1.5)\n", |
|||
" self.play(Write(circle))" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "4de93509", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"### Vlna [6b]" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "49bb1f67", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh Wave\n", |
|||
"\n", |
|||
"\n", |
|||
"class Wave(Scene):\n", |
|||
" def construct(self):\n", |
|||
" pass" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "f48d3810", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh ColorGradientExample\n", |
|||
"\n", |
|||
"\n", |
|||
"class ColorGradientExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" rows = 6\n", |
|||
" square_count = rows * 9\n", |
|||
"\n", |
|||
" colors = [\"#ef476f\", \"#ffd166\", \"#06d6a0\", \"#118ab2\"]\n", |
|||
" squares = [\n", |
|||
" Square(fill_color=WHITE, fill_opacity=1).scale(0.3)\n", |
|||
" for _ in range(square_count)\n", |
|||
" ]\n", |
|||
"\n", |
|||
" group = VGroup(*squares).arrange_in_grid(rows=rows)\n", |
|||
"\n", |
|||
" self.play(Write(group, lag_ratio=0.04))\n", |
|||
"\n", |
|||
" all_colors = color_gradient(colors, square_count)\n", |
|||
"\n", |
|||
" self.play(\n", |
|||
" AnimationGroup(\n", |
|||
" *[s.animate.set_color(all_colors[i]) for i, s in enumerate(squares)],\n", |
|||
" lag_ratio=0.02,\n", |
|||
" )\n", |
|||
" )" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "markdown", |
|||
"id": "159f8abb", |
|||
"metadata": {}, |
|||
"source": [ |
|||
"### Hilbert [6b]" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "d95d2328", |
|||
"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", |
|||
"\n", |
|||
"class Hilbert(Scene):\n", |
|||
" def construct(self):\n", |
|||
" pass" |
|||
] |
|||
}, |
|||
{ |
|||
"cell_type": "code", |
|||
"execution_count": null, |
|||
"id": "1a1bfc52", |
|||
"metadata": {}, |
|||
"outputs": [], |
|||
"source": [ |
|||
"%%manim -v WARNING -qh PathExample\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", |
|||
" # drobné vysvětlení: Manim k vytváření úseček používá kvadratické Bézierovy křivky\n", |
|||
" # - každá taková křivka má čtyři body -- dva krajní a dva řidicí\n", |
|||
" # - path.points vrací *všechny* body, což po několika iteracích roste exponenciálně\n", |
|||
" # \n", |
|||
" # proto používáme funkce get_*_anchors, které vrací pouze krajní body\n", |
|||
" # pro více detailů viz https://en.wikipedia.org/wiki/Bézier_curve\n", |
|||
" return list(self.get_start_anchors()) + [self.get_end_anchors()[-1]]\n", |
|||
"\n", |
|||
"\n", |
|||
"class PathExample(Scene):\n", |
|||
" def construct(self):\n", |
|||
" path = Path([LEFT + UP, LEFT + DOWN, RIGHT + UP, RIGHT + DOWN])\n", |
|||
"\n", |
|||
" self.play(Write(path))\n", |
|||
"\n", |
|||
" # opraveno po vydání seriálu, před |