{ "cells": [ { "cell_type": "markdown", "id": "7c29fa9c", "metadata": {}, "source": [ "# Manim (optional)" ] }, { "cell_type": "markdown", "id": "70a27f0e", "metadata": { "slideshow": { "slide_type": "-" }, "tags": [ "remove-cell" ] }, "source": [ "**CS1302 Introduction to Computer Programming**\n", "___" ] }, { "cell_type": "code", "execution_count": 1, "id": "d77a4c80", "metadata": {}, "outputs": [ { "data": { "text/html": [ "
Manim Community v0.7.0\n",
       "\n",
       "
\n" ], "text/plain": [ "Manim Community \u001b[32mv0.\u001b[0m\u001b[32m7.0\u001b[0m\n", "\n" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "import math\n", "\n", "from manim import *\n", "\n", "%reload_ext mytutor" ] }, { "cell_type": "markdown", "id": "d1f98ec3", "metadata": {}, "source": [ "[Manim](https://github.com/3b1b/manim) is a powerful **anim**ation engine for **ma**themetics developed by [3Blue1Brown](https://www.youtube.com/channel/UCYO_jab_esuFRV4b17AJtAw). We will use manim to domenstrate how object-oriented programming uses classes and objects to make it create complex animation." ] }, { "cell_type": "markdown", "id": "38162710", "metadata": {}, "source": [ "## Creating a scene" ] }, { "cell_type": "markdown", "id": "99df536c", "metadata": {}, "source": [ "**How to create an animation with `manim`?**" ] }, { "cell_type": "markdown", "id": "98c4819e", "metadata": {}, "source": [ "In jupyter notebook, we can use `%%manim` cell magic:" ] }, { "cell_type": "code", "execution_count": 2, "id": "00d1bc79", "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%manim -qm --progress_bar=none --disable_caching --flush_cache -v ERROR HelloWorld\n", "class HelloWorld(Scene):\n", " def construct(self):\n", " self.play(Write(Text(\"Hello, World!\")))" ] }, { "cell_type": "markdown", "id": "dc04a396", "metadata": {}, "source": [ "In the line starting with `%%`:\n", "- `-qm` is the alias for `--quality=m`, which means the video is rendered in medium quality. Change it to `-ql` (`-qh`) for low (high) quality.\n", "- `--progress_bar=none --disable_caching --flush_cache -v ERROR` are [additional configurations](https://docs.manim.community/en/stable/tutorials/configuration.html) to turn off some features. \n", "- `HelloWorld` is the class to render, which is defined in the body:\n", " ```Python \n", " class HelloWorld(Scene):\n", " def construct(self):\n", " ...\n", " ```" ] }, { "cell_type": "markdown", "id": "edc99705", "metadata": {}, "source": [ "**How to define a class?**" ] }, { "cell_type": "markdown", "id": "b31f0b80", "metadata": {}, "source": [ "As a toy example, the following [defines a class](https://docs.python.org/3/tutorial/classes.html?highlight=inheritance#class-definition-syntax) `Pet` and its [subclasses](https://docs.python.org/3/tutorial/classes.html?highlight=inheritance#inheritance) `Cat` and `Dog`:" ] }, { "cell_type": "code", "execution_count": 3, "id": "5cd94afb", "metadata": {}, "outputs": [ { "data": { "text/html": [ "\n", "\n" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%mytutor -h 700\n", "class Pet:\n", " kind = \"Pet\"\n", "\n", " def __init__(self, name):\n", " self.name = name\n", "\n", " def __str__(self):\n", " return f\"{self.kind} {self.name}\"\n", "\n", "\n", "class Cat(Pet):\n", " kind = \"Cat\"\n", "\n", "\n", "class Dog(Pet):\n", " kind = \"Dog\"\n", "\n", "\n", "p1 = Pet(\"Alfie\")\n", "p2 = Dog(\"Bobbie\")\n", "p3, p4 = Cat(\"Bella\"), Cat(\"Kelly\")\n", "print(p1, p2, p3, p4, sep=\", \")" ] }, { "cell_type": "markdown", "id": "9ee2b31e", "metadata": {}, "source": [ "- Each pet has its own `name` but they share `kind` from their class without duplicating it.\n", "- Subclasses can reuse (inherit) code from their superclass but produce different results:\n", " - Line 19-21 calls `Pet.__init__` implicitly to create pets with different `name`s.\n", " - Line 22 calls `Pet.__str__` implicitly to return a string containing pets' specific `kind` in addition to its `name`." ] }, { "cell_type": "markdown", "id": "c4ad1455", "metadata": {}, "source": [ "## Animating an Object" ] }, { "cell_type": "markdown", "id": "33651750", "metadata": {}, "source": [ "**How to add objects to a `Scene`?**" ] }, { "cell_type": "markdown", "id": "619c1445", "metadata": {}, "source": [ "We can create a square and add it to the scene as follows:" ] }, { "cell_type": "code", "execution_count": 4, "id": "eb4ea570", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAAAU/ElEQVR4nO3bsY0bMRRFUa6x0XTCeNSOqlM7k7OTTdfZwk4FCxSuz6ngBYwu+D/GGN8DAAAAAEj6tXsAAAAAAPA6AiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABD2uXsAAMDj8Rhzzt0z4J9ba437/b57BgDwnxMAAYDt5pzjPM/dMwAAIMkJMAAAAACE+QEIALyVr6+vsdbaPQOeNuccx3HsngEA8EMABADeylpr3G633TPgadd1OWkHAN6KE2AAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAICwz90DAAD+NOcc13XtngFPm3PungAA8BcBEAB4K8dxjPM8d88AAIAMJ8AAAAAAEOYHIACw3Vpr9wR4CW8bAHgHH2OM790jAAAAAIDXcAIMAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAEPYbmRgj+BtliV8AAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "metadata": { "filenames": { "image/png": "/home/cs1302/www/cs1302book/_build/jupyter_execute/Lab5/Manim_16_0.png" } }, "output_type": "display_data" } ], "source": [ "%%manim -qm --progress_bar=none --disable_caching --flush_cache -v ERROR BlueSquare1\n", "class BlueSquare1(Scene):\n", " def construct(self):\n", " s = Square(fill_color=BLUE, color=WHITE)\n", " self.add(s)" ] }, { "cell_type": "markdown", "id": "e8d289bf", "metadata": {}, "source": [ "- The square object is create using `Square`, `BLUE` and `WHITE` imported from `manim`.\n", "- It is then placed to to the scene using `self.add` inherited from `Scene`." ] }, { "cell_type": "markdown", "id": "2436236e", "metadata": {}, "source": [ "**How to animate an object?**" ] }, { "cell_type": "markdown", "id": "534007af", "metadata": {}, "source": [ "The following shows the creation of a square:" ] }, { "cell_type": "code", "execution_count": 5, "id": "b97931f2", "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%manim -qm --progress_bar=none --disable_caching --flush_cache -v ERROR BlueSquare2\n", "class BlueSquare2(Scene):\n", " def construct(self):\n", " s = Square(color=WHITE, fill_color=BLUE, fill_opacity=0.8)\n", " self.play(Create(s))\n", " self.wait()" ] }, { "cell_type": "markdown", "id": "3f8a4921", "metadata": {}, "source": [ "- `self.play` plays the animation `Create(s)`.\n", "- `self.wait()` creates a pause \"animation\"." ] }, { "cell_type": "markdown", "id": "05bf3623", "metadata": {}, "source": [ "**How to transform an object?**" ] }, { "cell_type": "markdown", "id": "4c802536", "metadata": {}, "source": [ "To scale, move, or rotate the shape:" ] }, { "cell_type": "code", "execution_count": 6, "id": "e3dcc8c5", "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%manim -qm --progress_bar=none --disable_caching --flush_cache -v ERROR BlueSquare3\n", "class BlueSquare3(Scene):\n", " def construct(self):\n", " s = Square(color=WHITE, fill_color=BLUE, fill_opacity=0.8)\n", " self.play(Create(s))\n", " self.play(s.animate.scale(1.5).rotate(PI / 4))\n", " self.play(s.animate.move_to([-3, 0, 0]))\n", " self.play(s.animate.move_to([3, 0, 0]))\n", " self.play(s.animate.scale(0.5).move_to(ORIGIN).rotate(-PI / 4))\n", " self.wait()" ] }, { "cell_type": "markdown", "id": "a69d1b2b", "metadata": {}, "source": [ "**Exercise** (Optional) The attribute `s.animate` is an object that provides the methods `scale`, `move_to`, and `rotate`. Note that the methods can be called successively as in `s.animate.scale(0.5).move_to(ORIGIN).rotate(-PI/4)`. Why?" ] }, { "cell_type": "markdown", "id": "acc3db6b", "metadata": {}, "source": [ "## Animating multiple objects" ] }, { "cell_type": "markdown", "id": "9b6fd1c1", "metadata": {}, "source": [ "**Tessellation with regular polygons**" ] }, { "cell_type": "markdown", "id": "78119544", "metadata": {}, "source": [ "Consider tiling a 12-by-6 plane using squares:" ] }, { "cell_type": "code", "execution_count": 7, "id": "46750a0f", "metadata": {}, "outputs": [ { "data": { "image/png": "iVBORw0KGgoAAAANSUhEUgAABQAAAALQCAYAAADPfd1WAAAVlUlEQVR4nO3csYlcVxiG4SNrQDCwsIHizRSceDZWCepgOlA56mA6cAmOJ7+5KhAIFgwWcuDMFsi7K3FmXj1PBR83fDn/fTHG+DoAAAAAgKTfVg8AAAAAAH4eARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAjbrR7AP06n05hzrp4BAAAA8ENs2zaOx+PqGQwB8GLMOcfhcFg9AwAAAIAYJ8AAAAAAEOYF4AV6eHgY27atngEAAADwKHPOsd/vV8/gXwTAC7Rt27i/v189AwAAAOBRzuezX5xdICfAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABhAiAAAAAAhAmAAAAAABAmAAIAAABAmAAIAAAAAGECIAAAAACECYAAAAAAECYAAgAAAECYAAgAAAAAYQIgAAAAAIQJgAAAAAAQJgACAAAAQJgACAAAAABh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AAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCdqsH8F9zznE+n1fPAAAAAHiUOefqCXyDAHiB9vv9OBwOq2cAAAAAEOAEGAAAAADCvAC8ENu2rZ4AAAAA8MNoHZfjxRjj6+oRAAAAAMDP4QQYAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIEwABAAAAIAwARAAAAAAwgRAAAAAAAgTAAEAAAAgTAAEAAAAgDABEAAAAADCBEAAAAAACBMAAQAAACBMAAQAAACAMAEQAAAAAMIEQAAAAAAIEwABAAAAIOxvR+g/OHXCocwAAAAASUVORK5CYII=\n", "text/plain": [ "" ] }, "metadata": { "filenames": { "image/png": "/home/cs1302/www/cs1302book/_build/jupyter_execute/Lab5/Manim_29_0.png" } }, "output_type": "display_data" } ], "source": [ "%%manim -qm --progress_bar=none --disable_caching --flush_cache -v ERROR SquareTiling1\n", "class SquareTiling1(Scene):\n", " WIDTH = 12\n", " HEIGHT = 6\n", " EDGE = 1\n", "\n", " def construct(self):\n", " plane = Rectangle(width=self.WIDTH, height=self.HEIGHT)\n", " unit = Square(color=WHITE, fill_color=BLUE, fill_opacity=0.8).scale(\n", " self.EDGE / 2\n", " )\n", " self.add(plane, unit)" ] }, { "cell_type": "markdown", "id": "e91f774b", "metadata": {}, "source": [ "The first line of squares can be animated as follows:" ] }, { "cell_type": "code", "execution_count": 8, "id": "d1ce63b9", "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%manim -qm --progress_bar=none --disable_caching --flush_cache -v ERROR SquareTiling2\n", "class SquareTiling2(Scene):\n", " WIDTH = 12\n", " HEIGHT = 6\n", " EDGE = 1\n", "\n", " def construct(self):\n", "\n", " plane = Rectangle(width=self.WIDTH, height=self.HEIGHT)\n", " self.add(plane)\n", "\n", " unit = Square(color=WHITE, fill_color=BLUE, fill_opacity=0.8).scale(\n", " self.EDGE / 2\n", " )\n", " self.play(Create(unit))\n", " self.play(\n", " unit.animate.move_to(\n", " [-self.WIDTH / 2 + self.EDGE / 2, self.HEIGHT / 2 - self.EDGE / 2, 0]\n", " )\n", " )\n", "\n", " for i in range(1, self.WIDTH // self.EDGE):\n", " self.play(unit.copy().animate.shift([i, 0, 0]), run_time=1 / i)\n", " self.wait()" ] }, { "cell_type": "markdown", "id": "473b21a5", "metadata": {}, "source": [ "We can use `VGroup` method to create a group of shapes." ] }, { "cell_type": "code", "execution_count": 9, "id": "7b73fa6d", "metadata": {}, "outputs": [ { "data": { "text/html": [ "" ], "text/plain": [ "" ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "%%manim -qm --progress_bar=none --disable_caching --flush_cache -v ERROR SquareTiling3\n", "class SquareTiling3(Scene):\n", " WIDTH = 12\n", " HEIGHT = 6\n", " EDGE = 1\n", "\n", " def construct(self):\n", "\n", " plane = Rectangle(width=self.WIDTH, height=self.HEIGHT)\n", " self.add(plane)\n", "\n", " unit = Square(color=WHITE, fill_color=BLUE, fill_opacity=0.8).scale(\n", " self.EDGE / 2\n", " )\n", " self.play(Create(unit))\n", " self.play(\n", " unit.animate.move_to(\n", " [-self.WIDTH / 2 + self.EDGE / 2, self.HEIGHT / 2 - self.EDGE / 2, 0]\n", " )\n", " )\n", "\n", " for i in range(1, math.floor(self.WIDTH / self.EDGE)):\n", " self.play(unit.copy().animate.shift([i * self.EDGE, 0, 0]), run_time=1 / i)\n", "\n", " line = VGroup(\n", " *[\n", " unit.copy().shift([i * self.EDGE, 0, 0])\n", " for i in range(math.floor(self.WIDTH / self.EDGE))\n", " ]\n", " )\n", " for i in range(1, math.floor(self.HEIGHT / self.EDGE)):\n", " self.play(line.copy().animate.shift([0, -i * self.EDGE, 0]), run_time=1 / i)\n", "\n", " self.wait()" ] }, { "cell_type": "markdown", "id": "38403de2", "metadata": {}, "source": [ "**Exercise** (Optional) Use manim to show the other two ways of tiling with regular polygons (triangle and hexagon). (see [tiling with regular polygons](https://en.wikipedia.org/wiki/Euclidean_tilings_by_convex_regular_polygons))" ] } ], "metadata": { "jupytext": { "text_representation": { "extension": ".md", "format_name": "myst", "format_version": 0.13, "jupytext_version": "1.10.3" } }, "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.8.8" }, "source_map": [ 12, 16, 21, 27, 31, 35, 39, 43, 48, 60, 64, 68, 92, 99, 103, 107, 111, 117, 122, 126, 130, 137, 142, 146, 150, 161, 165, 169, 173, 177, 190, 194, 219, 223, 258 ] }, "nbformat": 4, "nbformat_minor": 5 }