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.

#### 748 lines 22 KiB Raw Permalink Blame History

 `{` ` "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ředtím jsme používali path.points]), vysvětlení viz výše\n",` ` " path_points = VGroup(*[Dot().move_to(point) for point in path.get_important_points()])\n",` ` " \n",` ` " self.play(Write(path_points))\n",` ` " \n",` ` " path2 = path.copy()\n",` ` " path3 = path.copy()\n",` ` "\n",` ` " self.play(\n",` ` " path2.animate.next_to(path, LEFT, buff=1),\n",` ` " path3.animate.next_to(path, RIGHT, buff=1),\n",` ` " )\n",` ` " \n",` ` " # pozor, tohle není úplně intuitivní\n",` ` " # LEFT flipne dolů, jelikož určuje osu, přes kterou se objekt přetočí\n",` ` " self.play(\n",` ` " path2.animate.flip(),\n",` ` " path3.animate.flip(LEFT),\n",` ` " )"` ` ]` ` }` ` ],` ` "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` ```} ``` ``` ```