
    
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
            
{"version":"https:\/\/jsonfeed.org\/version\/1","title":"mathspp.com feed","home_page_url":"https:\/\/mathspp.com\/blog\/tags\/pygame","feed_url":"https:\/\/mathspp.com\/blog\/tags\/pygame.json","description":"Stay up-to-date with the articles on mathematics and programming that get published to mathspp.com.","author":{"name":"Rodrigo Gir\u00e3o Serr\u00e3o"},"items":[{"title":"Using an LLM to write a countdown timer","date_published":"2025-01-22T19:50:00+01:00","id":"https:\/\/mathspp.com\/blog\/using-an-llm-to-write-a-countdown-timer","url":"https:\/\/mathspp.com\/blog\/using-an-llm-to-write-a-countdown-timer","content_html":"<p>I used an LLM to write a countdown timer and I have mixed feelings about the result.<\/p>\n\n<h2 id=\"using-an-llm-to-write-a-countdown-timer\">Using an LLM to write a countdown timer<a href=\"#using-an-llm-to-write-a-countdown-timer\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>In this article I will tell you the short story of how I used an LLM to write a simple countdown timer for me.\nI will show you the code, what went well, and what went wrong.<\/p>\n<p>The timer we will be building will accept the number of minutes as a command argument:<\/p>\n<pre><code class=\"language-bash\">python cd.py 3<\/code><\/pre>\n<p>And it will then display a countdown timer like the GIF below shows:<\/p>\n<figure class=\"image-caption\"><img title=\"The countdown timer.\" alt=\"A GIF showing a countdown timer from 02:59 to 02:56. The background is white and the time is shown in black.\" src=\"\/user\/pages\/02.blog\/using-an-llm-to-write-a-countdown-timer\/_timer_demo.gif?decoding=auto&amp;fetchpriority=auto\"><figcaption class=\"\">The countdown timer.<\/figcaption><\/figure><h3 id=\"first-iteration\">First iteration<a href=\"#first-iteration\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>To get the first iteration of the code, here is the prompt I gave to GPT-4o:<\/p>\n<blockquote>\n<p>&ldquo;Write a pygame script that accepts a number of minutes using sys.argv and creates a basic countdown timer displaying the time as 10:00, 09:59, etc, all the way to 00:00.\nThe background should be white and the numbers should be black. Use basic event handling to allow quitting the countdown and pressing space should add another minute to the timer.&rdquo;<\/p>\n<\/blockquote>\n<details><summary>Full code of the first iteration.<\/summary><pre><code class=\"language-py\">import sys\nimport pygame\nfrom pygame.locals import QUIT, KEYDOWN, K_SPACE\n\n## Initialize pygame\npygame.init()\n\n## Screen dimensions and colors\nSCREEN_WIDTH, SCREEN_HEIGHT = 400, 200\nWHITE = (255, 255, 255)\nBLACK = (0, 0, 0)\n\n## Fonts and other settings\nFONT = pygame.font.Font(None, 80)\nFPS = 60\n\n## Parse command-line argument for the timer duration\nif len(sys.argv) != 2 or not sys.argv[1].isdigit():\n    print(\"Usage: python countdown.py &lt;minutes&gt;\")\n    sys.exit(1)\n\nminutes = int(sys.argv[1])\nseconds = minutes * 60\n\n## Set up the display\nscreen = pygame.display.set_mode((SCREEN_WIDTH, SCREEN_HEIGHT))\npygame.display.set_caption(\"Countdown Timer\")\n\n## Clock for controlling the frame rate\nclock = pygame.time.Clock()\n\nrunning = True\nwhile running:\n    # Event handling\n    for event in pygame.event.get():\n        if event.type == QUIT:\n            running = False\n        elif event.type == KEYDOWN:\n            if event.key == K_SPACE:\n                seconds += 60\n\n    # Timer logic\n    if seconds &amp;gt; 0:\n        seconds -= 1 \/ FPS\n\n    # Render the timer\n    screen.fill(WHITE)\n    minutes_display = int(seconds \/\/ 60)\n    seconds_display = int(seconds % 60)\n    time_text = f\"{minutes_display:02}:{seconds_display:02}\"\n    text_surface = FONT.render(time_text, True, BLACK)\n    text_rect = text_surface.get_rect(center=(SCREEN_WIDTH \/\/ 2, SCREEN_HEIGHT \/\/ 2))\n    screen.blit(text_surface, text_rect)\n\n    # Update the display\n    pygame.display.flip()\n\n    # Cap the frame rate\n    clock.tick(FPS)\n\n## Quit pygame\npygame.quit()<\/code><\/pre>\n<p><\/p>\n<\/details><p>I know a bit of pygame so I glanced through the code and it look promising enough, so I ran it with <code>python cd.py 3<\/code> and the countdown started.\nI pressed <kbd>SPACE<\/kbd> and the countdown increased by 1 minute.\nEverything looked fine.<\/p>\n<h3 id=\"adding-a-new-feature\">Adding a new feature<a href=\"#adding-a-new-feature\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>After this first iteration I wanted to change the code so that, after the countdown was finished, the background and foreground colours flipped each second.\nThis is what I typed:<\/p>\n<blockquote>\n<p>&ldquo;Change the code so that when the timer hits 0, the background and foreground colours reverse each second.&rdquo;<\/p>\n<\/blockquote>\n<p>GPT-4o promptly replied with some edited code.<\/p>\n<details><summary>Full code of the second iteration.<\/summary><pre><code class=\"language-py\">\nimport sys\nimport pygame\nfrom pygame.locals import QUIT, KEYDOWN, K_SPACE\n\n## Initialize pygame\npygame.init()\n\n## Screen dimensions and colors\nSCREEN_WIDTH, SCREEN_HEIGHT = 400, 200\nWHITE = (255,...<\/code><\/pre><\/details>","summary":"I used an LLM to write a countdown timer and I have mixed feelings about the result.","date_modified":"2025-07-23T16:49:02+02:00","tags":["llm","opinion","productivity","programming","pygame","python","scripting"],"image":"\/user\/pages\/02.blog\/using-an-llm-to-write-a-countdown-timer\/thumbnail.webp"},{"title":"Animating a tree fractal","date_published":"2025-01-12T19:10:00+01:00","id":"https:\/\/mathspp.com\/blog\/animating-a-tree-fractal","url":"https:\/\/mathspp.com\/blog\/animating-a-tree-fractal","content_html":"<p>This article walks through the code used to animate a tree fractal.<\/p>\n\n<p>I really enjoy fractals and for the longest time I've been meaning to draw the classical tree fractal that starts with the main trunk which then successively splits into two branches, that themselves can be seen as the full tree.<\/p>\n<p>Today I quickly put together the code to do this and then I animated the rotation of the tree to make sure it's easy to see the self-similarity of the tree.<\/p>\n<p>This is the animated GIF that I produced:<\/p>\n<p><img alt=\"Animated GIF of a tree fractal rotating and zooming in, so that the end position is the same as the starting position, displaying the self-similarity properties of the fractal.\" src=\"\/user\/pages\/02.blog\/animating-a-tree-fractal\/_tree.gif?decoding=auto&amp;fetchpriority=auto\"><\/p>\n<h2 id=\"drawing-the-tree\">Drawing the tree<a href=\"#drawing-the-tree\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>To draw the tree I wrote a recursive function (obviously!) that draws a trunk and then recursively draws the remainder of the tree.\nTo &ldquo;recursively draw the remainder of the tree&rdquo; I needed to compute the two trunks that stem from the trunk I just drew, so to do that I:<\/p>\n<ul><li>computed the direction of the trunk I just drew as a numpy vector;<\/li>\n<li>rotated this vector by 60 degrees (clockwise and counter-clockwise);<\/li>\n<li>scaled down this vector; and<\/li>\n<li>used it to compute the two new trunks.<\/li>\n<\/ul><p>The recursive function looks like this:<\/p>\n<pre><code class=\"language-py\">def tree(screen, start, to, depth=0):\n    if depth &gt;= 15:\n        return\n    sx, sy = start\n    tx, ty = to\n    pygame.draw.line(\n        screen,\n        BLACK,\n        (WIDTH \/\/ 2 + sx, HEIGHT \/\/ 2 - sy),\n        (WIDTH \/\/ 2 + tx, HEIGHT \/\/ 2 - ty),\n        1,\n    )\n    direction = np.array([[tx - sx], [ty - sy]])\n    for angle in [pi \/ 3, -pi \/ 3]:\n        rot = np.array(\n            [\n                [cos(angle), -sin(angle)],\n                [sin(angle), cos(angle)],\n            ]\n        )\n        new_direction = ((rot @ ((direction) \/ 1.7))).reshape((2,))\n        tree(screen, to, to + new_direction, depth + 1)<\/code><\/pre>\n<p>One important thing that I ended up doing, and that explains the weird calculations inside the call to <code>pygame.draw.line<\/code>, is that I decided to do all calculations as if the coordinate system were the standard one from maths class: the origin is at the centre of the pygame window and the values of the coordinate y increase by going up, not by going down.\nThen, I need to convert from this sytem to the pygame system right before drawing, which is why I add <code>(WIDTH \/\/ 2, HEIGHT \/\/ 2)<\/code> to the points we're drawing and then for the y coordinate I need to use the symmetric value (<code>-y<\/code> instead of <code>y<\/code>) to compensate for the fact that the y axis is flipped.<\/p>\n<p>The full script to draw the tree looks like this:<\/p>\n<pre><code class=\"language-py\">from math import sin, cos, pi\nimport sys\n\nimport numpy as np\nimport pygame\nimport pygame.locals\n\nWIDTH, HEIGHT = 600, 400\n\nWHITE = (255, 255, 255)\nBLACK = (0, 0, 0)\n\nscreen = pygame.display.set_mode((WIDTH, HEIGHT))\n\ndef tree(screen, start, to, depth=0):\n    ...\n\ndef main() -&gt; None:\n    screen.fill(WHITE)\n    tree(screen, np.array((0, -200)), np.array((0, 0)))\n    pygame.display.flip()\n    pygame.image.save(screen, \"tree.png\")\n\n    while True:\n        for event in pygame.event.get():\n            if event.type == pygame.locals.QUIT:\n                pygame.quit()\n                sys.exit(0)\n\nif __name__ == \"__main__\":\n    main()<\/code><\/pre>\n<h2 id=\"animating-the-tree\">Animating the tree<a href=\"#animating-the-tree\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>To make it easier to animate the tree I first started by splitting the function <code>tree<\/code> in two:<\/p>\n<ol><li>a...<\/li><\/ol>","summary":"This article walks through the code used to animate a tree fractal.","date_modified":"2025-07-23T16:49:02+02:00","tags":["fractals","mathematics","programming","pygame","python","recursion","visualisation"],"image":"\/user\/pages\/02.blog\/animating-a-tree-fractal\/thumbnail.webp"},{"title":"Animating a rotating spiral","date_published":"2024-07-10T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/animating-a-rotating-spiral","url":"https:\/\/mathspp.com\/blog\/animating-a-rotating-spiral","content_html":"<p>With a couple of loops and a bit of maths you can create a rotating spiral.<\/p>\n\n<video width=\"400\" height=\"400\" poster=\"\/blog\/animating-a-rotating-spiral\/_rotating.mp4.thumb.png\" controls><source src=\"\/blog\/animating-a-rotating-spiral\/_rotating.mp4\" type=\"video\/mp4\">\n  A video animation of a colourful rotating spiral that keeps expanding and contracting and changing colour.\n<\/source><\/video><p>Following up on the concepts covered in my previous article <a href=\"\/blog\/animations-from-first-principles-in-5-minutes\">&ldquo;Animations from first principles in 5 minutes&rdquo;<\/a> and <a href=\"\/blog\/more-animations-from-first-principles-in-5-minutes\">&ldquo;More animations from first principles in 5 minutes&rdquo;<\/a>, in this article we will create the animation you can see above.<\/p>\n<p>We start by modifying the parametrisation of the circle to create a spiral:<\/p>\n<pre><code class=\"language-py\">SIDE = 600\n\ndef spiral(percentage):\n    return (\n        SIDE \/\/ 2\n        * percentage\n        * cos(10 * pi * percentage),\n        SIDE \/\/ 2\n        * percentage\n        * sin(10 * pi * percentage),\n    )<\/code><\/pre>\n<p>The <code>10<\/code> inside <code>cos<\/code>\/<code>sin<\/code> dictate how many turns the spiral does, all you have to do is divide that number by <code>2<\/code>, so a <code>10<\/code> means we do <code>5<\/code> turns around the centre of the spiral.<\/p>\n<p>You can &ldquo;easily&rdquo; put the spiral on the screen:<\/p>\n<pre><code class=\"language-py\">from itertools import product\nfrom math import sin, cos, pi\n\nimport pygame\n\nSIDE = 600\nWHITE = (255, 255, 255)\nBLACK = (0, 0, 0)\n\nscreen = pygame.display.set_mode((SIDE, SIDE))\nscreen.fill(WHITE)\n\ndef draw_pixel(screen, x, y, colour):\n    x, y = round(x), round(y)\n    for dx, dy in product(range(-1, 2), repeat=2):\n        screen.set_at((x + dx, y + dy), colour)\n\ndef spiral(percentage):\n    return (\n        SIDE \/\/ 2 * percentage * cos(10 * pi * percentage),\n        SIDE \/\/ 2 * percentage * sin(10 * pi * percentage),\n    )\n\nSTEPS = 3000\nfor step in range(STEPS + 1):\n    percentage = step \/ STEPS\n    x, y = rotating_spiral(percentage, tick \/ 10)\n    draw_pixel(screen, x, y, BLACK)\npygame.display.flip()\ninput()<\/code><\/pre>\n<p>By modifying the function <code>spiral<\/code> to accept an argument that represents time and by creating an outer loop that emulates ticking of time, we can rotate this spiral:<\/p>\n<pre><code class=\"language-py\"># ...\n\ndef spiral(percentage, time):\n    return (\n        SIDE \/\/ 2 * percentage * cos(10 * pi * percentage + time),\n        SIDE \/\/ 2 * percentage * sin(10 * pi * percentage + time),\n    )\n\n# ...\n\nSTEPS = 3000\nfor tick in count():\n    screen.fill(WHITE)\n    for step in range(STEPS + 1):\n        percentage = step \/ STEPS\n        x, y = rotating_spiral(percentage, tick \/ 10)\n        draw_pixel(screen, x, y, BLACK)\n    pygame.display.flip()<\/code><\/pre>\n<p>To make the spiral expand and contract, we must make it so that the radius has to change as time ticks:<\/p>\n<pre><code class=\"language-py\">def rotating_spiral(percentage, time):\n    return (\n        SIDE \/\/ 2\n        + (1 + sin(time) \/ 10)  # &lt;-- new\n        * percentage * (SIDE \/\/ 3) * cos(10 * pi * percentage + time),\n        SIDE \/\/ 2\n        + (1 + sin(time) \/ 10)  # &lt;-- new\n        * percentage * (SIDE \/\/ 3) * sin(10 * pi * percentage + time),\n    )<\/code><\/pre>\n<p>Finally, to add colour, we create two functions that generate the background and foreground colours for each frame instead of using the constants <code>WHITE<\/code> \/ <code>BLACK<\/code>:<\/p>\n<pre><code class=\"language-py\"># ...\n\ndef bg(time):\n    return (\n        40 + int(abs(30 * sin(0.05 * time))),\n        40 + int(abs(30 * sin(0.05 * time))),\n        40 + int(abs(30 * sin(0.05 * time))),\n    )\n\ndef...<\/code><\/pre>","summary":"With a couple of loops and a bit of maths you can create a rotating spiral.","date_modified":"2025-07-23T16:49:02+02:00","tags":["geometry","mathematics","programming","pygame","python","visualisation"],"image":"\/user\/pages\/02.blog\/animating-a-rotating-spiral\/thumbnail.webp"},{"title":"(More) Animations from first principles","date_published":"2023-09-08T12:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/more-animations-from-first-principles-in-5-minutes","url":"https:\/\/mathspp.com\/blog\/more-animations-from-first-principles-in-5-minutes","content_html":"<p>Create a zooming animation from first principles in Python. In 5 minutes. Kind of.<\/p>\n\n<video width=\"400\" height=\"400\" poster=\"\/blog\/more-animations-from-first-principles-in-5-minutes\/_zoom_triangle.mp4.thumb.png\" controls><source src=\"\/blog\/more-animations-from-first-principles-in-5-minutes\/_zoom_triangle.mp4\" type=\"video\/mp4\">\n  You can't watch the video animation of a recursive triangular structure, zooming in and rotating, animated with a Python and pygame script.\n<\/source><\/video><p>This is a follow-up to my recent article called <a href=\"\/blog\/animations-from-first-principles-in-5-minutes\">&ldquo;Animations from first principles (in 5 minutes)&rdquo;<\/a>.\nIn that article, we created a simple animation with Python and pygame.<\/p>\n<p>In <em>this<\/em> article, we will create a different type of animation, where we will draw a recursive triangular structure that can be zoomed in indefinitely.\nWe'll be using Python and <code>pygame<\/code>, so make sure you install it in your preferred way, and make sure it was installed properly:<\/p>\n<pre><code class=\"language-pycon\">&gt;&gt;&gt; import pygame\npygame 2.5.1 (SDL 2.28.2, Python 3.11.4)\nHello from the pygame community. https:\/\/www.pygame.org\/contribute.html<\/code><\/pre>\n<p>The code in this article was written with Python 3.11 and <code>pygame<\/code> 2.5.1.\nHowever, it should run well on older versions of Python\/<code>pygame<\/code> because we're only using fundamental features that have been around for a while and that are unlikely to go anywhere.<\/p>\n<h2 id=\"in-5-minutes\">In 5 minutes?<a href=\"#in-5-minutes\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>I have no idea if you can go through this in 5 minutes.\nYou'll likely need more time if these ideas are new to you and you're typing the code yourself.\nHowever, I did present most of this material in 5 minutes in <a href=\"\/talks\">a lightning talk at PyCon Portugal<\/a>.<\/p>\n<h2 id=\"i-ll-cheat-a-bit\">I'll cheat a bit<a href=\"#i-ll-cheat-a-bit\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>For this demo, I'll cheat a bit and I will add a little bit of boilerplate for free.\nThis is a class <code>Point<\/code> that I'm using to represent 2D points.\nThe idea is to make it easier to add and subtract points, and to multiply and divide points by numbers.<\/p>\n<p>The class <code>Point<\/code> looks like this:<\/p>\n<pre><code class=\"language-py\">class Point:\n    def __init__(self, x, y):\n        self.values = (x, y)\n\n    def __add__(self, other):\n        x, y = self.values\n        x_, y_ = other.values\n        return Point(x + x_, y + y_)\n\n    def __sub__(self, other):\n        x, y = self.values\n        x_, y_ = other.values\n        return Point(x - x_, y - y_)\n\n    def __mul__(self, other):\n        return Point(self.values[0] * other, self.values[1] * other)\n\n    __rmul__ = __mul__\n\n    def __truediv__(self, other):\n        return Point(self.values[0] \/ other, self.values[1] \/ other)\n\n    @property\n    def length(self):\n        return self.values[0] ** 2 + self.values[1] ** 2<\/code><\/pre>\n<p>It uses <a href=\"\/blog\/pydonts\/overloading-arithmetic-operators-with-dunder-methods\">arithmetic dunder methods<\/a> and a <a href=\"\/blog\/pydonts\/properties\">property<\/a>, but it is just so I can do operations like <code>Point(1, 2) + Point(3, 4)<\/code> or <code>3 * Point(1, 0)<\/code>.<\/p>\n<p>With this out of the way, let us start!<\/p>\n<h2 id=\"creating-the-canvas-to-draw-on\">Creating the canvas to draw on<a href=\"#creating-the-canvas-to-draw-on\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Just like last time, we'll start by making sure we can get a black screen in front of us:<\/p>\n<pre><code class=\"language-py\">import pygame\n\nWHITE = (255, 255, 255)\nBLACK = (0, 0, 0)\n\nscreen = pygame.display.set_mode((400, 400))\nscreen.fill(BLACK)\n\nwhile True:\n    pygame.display.flip()<\/code><\/pre>\n<p>The code above fills a 400 by 400 screen with black and then it refreshes it forever.\nIf you run this program, you'll see a black screen:<\/p>\n<figure class=\"image-caption\"><img title=\"A black screen.\" alt=\"\" src=\"\/user\/pages\/02.blog\/more-animations-from-first-principles-in-5-minutes\/_black_screen.webp\"><figcaption class=\"\">A black screen.<\/figcaption><\/figure><p>To close this window, you'll need to interrupt <em>the Python shell where you ran your program<\/em>.<\/p>\n<h2 id=\"drawing-a-triangle\">Drawing a triangle<\/h2>...","summary":"Create a zooming animation from first principles in Python. In 5 minutes. Kind of.","date_modified":"2025-07-23T16:49:02+02:00","tags":["fractals","geometry","mathematics","programming","pygame","python","recursion","visualisation"],"image":"\/user\/pages\/02.blog\/more-animations-from-first-principles-in-5-minutes\/thumbnail.webp"},{"title":"Animations from first principles","date_published":"2023-09-07T12:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/animations-from-first-principles-in-5-minutes","url":"https:\/\/mathspp.com\/blog\/animations-from-first-principles-in-5-minutes","content_html":"<p>Create animations from first principles and morph between different figures with Python. In 5 minutes. Kind of.<\/p>\n\n<video width=\"400\" height=\"400\" poster=\"\/blog\/animations-from-first-principles-in-5-minutes\/_morph.mp4.thumb.png\" controls><source src=\"\/blog\/animations-from-first-principles-in-5-minutes\/_morph.mp4\" type=\"video\/mp4\">\n  A video animation of a colourful circle morphing into a figure eight and back, animated with a Python and pygame script.\n<\/source><\/video><p>Let me guide you through creating your first animation.\nWe'll be using Python and <code>pygame<\/code>, so make sure you install it in your preferred way, and make sure it was installed properly:<\/p>\n<pre><code class=\"language-pycon\">&gt;&gt;&gt; import pygame\npygame 2.5.1 (SDL 2.28.2, Python 3.11.4)\nHello from the pygame community. https:\/\/www.pygame.org\/contribute.html<\/code><\/pre>\n<p>The code in this article was written with Python 3.11 and <code>pygame<\/code> 2.5.1.\nHowever, it should run well on older versions of Python\/<code>pygame<\/code> because we're only using fundamental features that have been around for a while and that are unlikely to go anywhere.<\/p>\n<h2 id=\"in-5-minutes\">In 5 minutes?<a href=\"#in-5-minutes\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>I have no idea if you can go through this in 5 minutes.\nYou surely can't if these ideas are new to you and you're typing the code yourself.\nHowever, I did present most of this material in 5 minutes in <a href=\"\/talks\">a lightning talk at PyCon Portugal<\/a>.<\/p>\n<h2 id=\"creating-the-canvas-to-draw-on\">Creating the canvas to draw on<a href=\"#creating-the-canvas-to-draw-on\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>The first thing we need is a canvas to draw on, so we'll import <code>pygame<\/code>, create a small canvas, and fill it with black.\nSince we'll be drawing in white, we can also set that up already:<\/p>\n<pre><code class=\"language-py\">import pygame\n\nWHITE = (255, 255, 255)\nBLACK = (0, 0, 0)\n\nWIDTH = 400\nHEIGHT = 400\n\nscreen = pygame.display.set_mode((WIDTH, HEIGHT))\nscreen.fill(BLACK)\n\nwhile True:\n    pygame.display.flip()<\/code><\/pre>\n<p>The code above fills a 400 by 400 screen with black and then it refreshes it forever.\nIf you run this program, you'll see a black screen:<\/p>\n<figure class=\"image-caption\"><img title=\"A black screen.\" alt=\"\" src=\"\/user\/pages\/02.blog\/animations-from-first-principles-in-5-minutes\/_black_screen.webp\"><figcaption class=\"\">A black screen.<\/figcaption><\/figure><p>To close this, you'll need to interrupt <em>the Python shell where you ran your program<\/em>.<\/p>\n<h2 id=\"drawing-a-circle\">Drawing a circle<a href=\"#drawing-a-circle\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>We'll start by animating the drawing of a circle, so we need to be able to draw a circle.\nIn order to do this, we'll write a function <code>circle<\/code> that accepts a single argument <code>progress<\/code> that is a float between 0 and 1:<\/p>\n<pre><code class=\"language-py\">def circle(progress):\n    ...<\/code><\/pre>\n<p>This function <code>circle<\/code> will return a point &ndash; a tuple with two floats &ndash; that will represent a position on the screen that belongs to the circle...\nBut what position?<\/p>\n<p>Think of yourself drawing a circle.\nAs the pen moves around the piece of paper, you can think of the \"progress\" you've made in drawing the circle.\nIf you have put the pen down on the paper, you've drawn 0% of the circle, so the progress is <code>0<\/code>.<\/p>\n<p>After you've drawn half a circle, you've drawn 50% of the circle, so that's <code>progress=0.5<\/code>.\nAnd as soon as you finish the circle, when your pen has gone around the paper and it touches the line you started drawing, at that time, your progress is <code>1<\/code>.<\/p>\n<p>So, the function <code>circle<\/code> is supposed to return the position your pen was in when your drawing was at a given percentage of progress.<\/p>\n<p>If you know...<\/p>","summary":"Create animations from first principles and morph between different figures with Python. In 5 minutes. Kind of.","date_modified":"2025-07-23T16:49:02+02:00","tags":["geometry","mathematics","programming","pygame","python","visualisation"],"image":"\/user\/pages\/02.blog\/animations-from-first-principles-in-5-minutes\/thumbnail.webp"},{"title":"TIL #080 \u2013 how to draw a B\u00e9zier curve","date_published":"2023-09-04T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/til\/how-to-draw-a-bezier-curve","url":"https:\/\/mathspp.com\/blog\/til\/how-to-draw-a-bezier-curve","content_html":"<p>Today I learned how to draw a B&eacute;zier curve with the De Casteljau's algorithm.<\/p>\n\n<figure class=\"image-caption\"><img title=\"An animated B&eacute;zier curve.\" alt=\"A GIF animation of a B&eacute;zier curve being drawn in a Python program that uses pygame to draw the curve and provide user interaction.\" src=\"\/user\/pages\/02.blog\/04.til\/080.how-to-draw-a-bezier-curve\/_bezier.gif?decoding=auto&amp;fetchpriority=auto\"><figcaption class=\"\">An animated B&eacute;zier curve.<\/figcaption><\/figure><h2 id=\"how-to-draw-a-bezier-curve\">How to draw a B&eacute;zier curve<a href=\"#how-to-draw-a-bezier-curve\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Today I learned that there is a straightforward way to draw B&eacute;zier curves and I wrote a small Python program to test this out.<\/p>\n<p>The code uses <code>pygame<\/code> and it creates a window with the two endpoints for the curve and a control point (so, we're drawing a quadratic B&eacute;zier curve).<\/p>\n<p>The animation above shows the program running and the code has been included below.<\/p>\n<p>The main part of that program is the little bit of maths that actually computes the points of the curve itself.\nFor a given <span class=\"mathjax mathjax--inline\">\\(t \\in [0, 1]\\)<\/span>, if <span class=\"mathjax mathjax--inline\">\\(s\\)<\/span>, <span class=\"mathjax mathjax--inline\">\\(e\\)<\/span>, and <span class=\"mathjax mathjax--inline\">\\(c\\)<\/span> and the start, end, and control points, respectively, then the point <span class=\"mathjax mathjax--inline\">\\(p(t)\\)<\/span> of the curve is<\/p>\n<p class=\"mathjax mathjax--block\">\\[\n\\begin{cases}\np_1(t) = s + (c - s) \\times t \\\\\np_2(t) = c + (e - c) \\times t \\\\\np(t) = p_1(t) + (p_2(t) - p_1(t)) \\times t\n\\end{cases}\\]<\/p>\n<p>This formula is the application of the De Casteljau's algorithm to quadratic B&eacute;zier curves.<\/p>\n<p>What the code does, inside the function <code>draw_curve<\/code>, is use a <code>for<\/code> loop to sample multiple values of <code>t<\/code> to approximate the curve by drawing a bunch of points.<\/p>\n<p>The code below ran on Python 3.11 and pygame 2.5.1.\nIt shouldn't have major compatibility issues with other version of Python\/pygame, though, as I'm only using fairly basic functionality.<\/p>\n<pre><code class=\"language-py\">import dataclasses\nfrom dataclasses import dataclass\nimport sys\n\nimport pygame\nimport pygame.locals\n\nWIDTH = 800\nHEIGHT = 600\nENDPOINT_COLOUR = (248, 248, 242)\nBACKGROUND = (40, 42, 54)\nCONTROL_POINT_COLOUR = (255, 85, 85)\nCURVE_COLOUR = (189, 147, 249)\nGUIDELINE_COLOUR = (139, 233, 253)\nPOINT_RADIUS = 10\n\nscreen = pygame.display.set_mode((WIDTH, HEIGHT))\nscreen.fill(BACKGROUND)\n\n@dataclass\nclass Curve:\n    start: tuple[int, int]\n    end: tuple[int, int]\n    control_point: tuple[int, int]\n\ndef dist_squared(p1, p2):\n    x1, y1 = p1\n    x2, y2 = p2\n    return (x2 - x1) ** 2 + (y2 - y1) ** 2\n\ndef draw_endpoint(screen, point):\n    pygame.draw.circle(\n        screen,\n        ENDPOINT_COLOUR,\n        point,\n        radius=POINT_RADIUS,\n    )\n\ndef draw_control_point(screen, point):\n    pygame.draw.circle(\n        screen,\n        CONTROL_POINT_COLOUR,\n        point,\n        radius=POINT_RADIUS,\n    )\n\ndef draw_curve(screen, curve):\n    pygame.draw.line(screen, GUIDELINE_COLOUR, curve.start, curve.control_point)\n    pygame.draw.line(screen, GUIDELINE_COLOUR, curve.end, curve.control_point)\n\n    sx, sy = curve.start\n    ex, ey = curve.end\n    cx, cy = curve.control_point\n\n    iters = 1000\n    for iter in range(0, iters + 1):\n        delta = iter \/ iters\n        m1x = sx + (cx - sx) * delta\n        m2x = cx + (ex - cx) * delta\n        m1y = sy + (cy - sy) * delta\n        m2y = cy + (ey - cy) * delta\n        px = m1x + (m2x - m1x) * delta\n        py = m1y + (m2y - m1y) * delta\n        pygame.draw.circle(screen, CURVE_COLOUR, (px, py), radius=1)\n\n    draw_endpoint(screen, curve.start)\n    draw_endpoint(screen, curve.end)\n    draw_control_point(screen, curve.control_point)\n\nprevious_curve = None\ncurve = Curve((100, 100), (WIDTH - 100, 100), (WIDTH \/\/ 2, HEIGHT \/\/ 2))\ndragging = False\npoint_being_dragged = None\n\nprint(\"Click a point to &ldquo;pick it up&rdquo; and click again to drop it.\")\n\nwhile True:\n    for event in pygame.event.get():\n        if (\n            event.type == pygame.locals.QUIT...<\/code><\/pre>","summary":"Today I learned how to draw a B\u00e9zier curve with the De Casteljau&#039;s algorithm.","date_modified":"2025-07-23T16:49:02+02:00","tags":["mathematics","programming","pygame","python","visualisation"],"image":"\/user\/pages\/02.blog\/04.til\/080.how-to-draw-a-bezier-curve\/thumbnail.webp"},{"title":"The formula that plots itself","date_published":"2019-04-24T15:32:00+02:00","id":"https:\/\/mathspp.com\/blog\/the-formula-that-plots-itself","url":"https:\/\/mathspp.com\/blog\/the-formula-that-plots-itself","content_html":"<p>This post gives you the code to mess around with \"Tupper's self-referential formula\", a formula that plots itself.<\/p>\n\n<p>By the end of this blog post, I hope that you know how to make mathematical drawings and why the number<\/p>\n<p class=\"mathjax mathjax--block\">\\[\nN \\approx 4.85845063618971342358209596 \\times 10^{543}\\]<\/p>\n<p>is so special.<\/p>\n<p>Given a function <span class=\"mathjax mathjax--inline\">\\(f(x, y)\\)<\/span>, how can you use it to make a drawing? Well, we just imagine the whole plane as a white, clean grid, and then we fill with black the squares at the positions <span class=\"mathjax mathjax--inline\">\\((x,y)\\)<\/span> such that <span class=\"mathjax mathjax--inline\">\\(f(x,y) &gt; \\frac{1}{2}\\)<\/span>. In a way, it is as if the function <span class=\"mathjax mathjax--inline\">\\(f\\)<\/span> is telling us whether to use white or black, i.e., to leave the square empty (<span class=\"mathjax mathjax--inline\">\\(0\\)<\/span>) or filled in (<span class=\"mathjax mathjax--inline\">\\(1\\)<\/span>).<\/p>\n<p>(More rigorously, we divide the plane into unit squares and assign each square the coordinates of its lower-left corner.)<\/p>\n<p>If we take, for example, <span class=\"mathjax mathjax--inline\">\\(f(x, y) = x + y\\)<\/span>, then square <span class=\"mathjax mathjax--inline\">\\((0,0)\\)<\/span> would be white because <span class=\"mathjax mathjax--inline\">\\(f(0, 0) = 0 &lt; \\frac{1}{2}\\)<\/span> but the squares <span class=\"mathjax mathjax--inline\">\\((0, 1)\\)<\/span> and <span class=\"mathjax mathjax--inline\">\\((1, 0)\\)<\/span> would be black because <span class=\"mathjax mathjax--inline\">\\(f(0, 1) = f(1, 0) = 1 &gt; \\frac{1}{2}\\)<\/span>.<\/p>\n<p>As another example, take <span class=\"mathjax mathjax--inline\">\\(f\\)<\/span> to be this function:<\/p>\n<p class=\"mathjax mathjax--block\">\\[\nf(x, y) = \\left\\lfloor \\text{mod}\\left(\\left\\lfloor\\frac{y}{17} \\right\\rfloor 2^{-17\\lfloor x \\rfloor -  \\text{mod}(\\lfloor y \\rfloor, 17)}, 2\\right) \\right\\rfloor\\]<\/p>\n<p>where <span class=\"mathjax mathjax--inline\">\\(\\lfloor n \\rfloor\\)<\/span> denotes the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Floor_and_ceiling_functions\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">floor function<\/a> and <span class=\"mathjax mathjax--inline\">\\(\\text{mod}(a, b)\\)<\/span> denotes the <a href=\"https:\/\/en.wikipedia.org\/wiki\/Modulo_operation\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">modulo operator<\/a>. This function looks way more interesting, doesn't it? Yes, it does! And if you look in the right place, this is what is plotted by this function:<\/p>\n<figure class=\"image-caption\"><img title=\"The formula, drawn.\" alt=\"A plot showing the Tupper formula written in black in a pixelated font.\" src=\"\/user\/pages\/02.blog\/the-formula-that-plots-itself\/_tupper_formula.webp\"><figcaption class=\"\">The formula, drawn.<\/figcaption><\/figure><p>What is going on here..? The function I just showed you, called <a href=\"https:\/\/en.wikipedia.org\/wiki\/Tupper's_self-referential_formula\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Tupper's self-referential formula<\/a>, is a formula that plots itself! But you might be suspicious because I said <em>if you look in the <strong>right<\/strong> place<\/em>. What is this <em>place<\/em> then?<\/p>\n<p>Quite simply, define<\/p>\n<p class=\"mathjax mathjax--block\">\\[\nN=4858450636189713423582095962494202044581400587983244549483093085061934704708809928450644769865524364849997247024915119110411605739177407856919754326571855442057210445735883681829823754139634338225199452191651284348332905131193199953502413758765239264874613394906870130562295813219481113685339535565290850023875092856892694555974281546386510730049106723058933586052544096664351265349363643957125565695936815184334857605626529915320311182856118951164066401426579727262440270286409619368825536815027849325692956320299303330714849102058741137034502,\\]<\/p>\n<p>(a 544-digit-long number). Then, the image I showed you is the rectangular area with the lower-left corner <span class=\"mathjax mathjax--inline\">\\((0, N)\\)<\/span> and the upper-right corner <span class=\"mathjax mathjax--inline\">\\((105, N + 16)\\)<\/span> (so it is a <span class=\"mathjax mathjax--inline\">\\(106 \\times 17\\)<\/span> rectangle). Quite impressive, right? Self-references are always fun!<\/p>\n<p>But that is not all... If you look hard enough, you can find literally anything inside that <span class=\"mathjax mathjax--inline\">\\(106\\times17\\)<\/span> rectangle! For example, taking<\/p>\n<p class=\"mathjax mathjax--block\">\\[\nN=677269797063266389145771001639366162904443300634759368354244105189144417475687924080590138582401925400953401198762670070868017028632609067495842127259345485889052110555312844858658969250766978033911456684637024394115209279287448522343527514061700072005928325124098808483476326307953390156875355289624192978628506335125351370018499785193486797521350328711540234844414805471938182060305235921541912512179523099720166772353828125144439537587189530425493554812515912471900753848603802337280,\\]<\/p>\n<p>you can find the name of this site \"mathspp\" and a winking face \";)\":<\/p>\n<figure class=\"image-caption\"><img title=\"mathspp ;)\" alt='The text \"mathspp ;)\" drawn in black in a pixelated font.' src=\"\/user\/pages\/02.blog\/the-formula-that-plots-itself\/_tupper_mathspp.webp\"><figcaption class=\"\">mathspp ;)<\/figcaption><\/figure><p>Now the really important question is... How does one find such values for <span class=\"mathjax mathjax--inline\">\\(N\\)<\/span>? Well, you can watch <a href=\"https:\/\/www.youtube.com\/watch?v=_s5RFgd59ao\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">this Numberphile YouTube video<\/a>, or I can tell you all about it...<\/p>\n<p>You start with a <span class=\"mathjax mathjax--inline\">\\(106\\times17\\)<\/span> grid and you colour it (with black\/white) the way you want. Then you will construct a bit sequence: you start on the top-right corner, and write down a <span class=\"mathjax mathjax--inline\">\\(1\\)<\/span> if that square is black, <span class=\"mathjax mathjax--inline\">\\(0\\)<\/span> if that square is white. Then you go down one square, and repeat. You do this column by column, top to bottom, right to left. When you finish, you convert your bit sequence...<\/p>","summary":"This post gives you the code to mess around with \u201cTupper&#039;s self-referential formula\u201d, a formula that plots itself.","date_modified":"2025-07-23T16:49:02+02:00","tags":["binary","mathematics","modular arithmetic","programming","pygame","python","recursion","visualisation"],"image":"\/user\/pages\/02.blog\/the-formula-that-plots-itself\/thumbnail.webp"},{"title":"Solving mazes with programming","date_published":"2017-11-29T00:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/solving-mazes-with-programming","url":"https:\/\/mathspp.com\/blog\/solving-mazes-with-programming","content_html":"<p>I have always loved solving mazes... so naturally I had to write a program to solve mazes for me!<\/p>\n\n<p><img alt=\"a black and white maze\" src=\"\/images\/3\/6\/e\/f\/c\/36efc6bd4eb9df9c15ae0f3af26f4b153a125eed-maze2.jpg\"><\/p>\n<p>Take a look at this maze; can you find a path from the upper left entrance in the maze to the lower right exit? Probably you can, and so does the program I wrote!<\/p>\n<p>I wrote a program in Python (making use of <code>pygame<\/code> and <code>Pillow<\/code>) to solve any maze given. I did this project several years ago, after learning about <a href=\"https:\/\/en.wikipedia.org\/wiki\/Dijkstra's_algorithm\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Dijkstra's algorithm<\/a>. I read about the algorithm and decided to implement it, to get a feel for it. I realized that I could apply it to a maze in a picture, if I took each pixel of the image to be a vertex in the graph where I'd apply the method.<\/p>\n<p>I wanted to make my program fairly general, in terms of the mazes that could be given, and so I dwelled with a problem: how to tell if two adjacent pixels should be connected in the graph or not. I knew I only wanted to connect pixels that referred to the path, and not to the walls, so my idea was simple: I supposed that a picture of a maze would have mainly two colours, one for the walls and another for the paths. I leveraged on that to preprocess the image and turn it to a black and white picture, where each pixel would be either completely white or completely black (I did this by finding the average luminosity of a pixel in the image and used that as a threshold; a pixel with luminosity below the average becomes black, otherwise it becomes white). After processing, ask the user for the two points we want to connect; if they have the same colour (say it was white) then it must have been because the paths have been changed into white and thus I need only to consider white pixels.<\/p>\n<p>After we know where to start, where to end, and which colour we care about (either black or white) I apply Dijkstra's algorithm on the graph of the vertices of that colour, where two vertices are connected if the two corresponding pixels are adjacent. Of course I didn't have to explicitly build the graph, as it was given by the pixels in the picture. After a path is found, a red line is drawn. The first version of the script would draw the absolute shortest path, and so it would mainly be adjacent to walls and I found it aesthetically unpleasing. To try and counter that I added a slight element of randomness when drawing the red path. Using my script to solve the maze above we get this drawing:<\/p>\n<p><img alt=\"the maze above but solved with a red line showing the path\" src=\"\/user\/pages\/02.blog\/solving-mazes-with-programming\/maze2_solved.webp\"><\/p>\n<p>which looks like a line I could draw with my pencil, if I managed to not overlap my line with the walls of the maze by accident. The code can be found in <a href=\"https:\/\/github.com\/RodrigoGiraoSerrao\/projects\/tree\/master\/MazeSolver\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">this GitHub repo<\/a> and a downloadable executable can be found <a href=\"https:\/\/drive.google.com\/open\" id=\"1L7Ell-R4hUlN8Tutp10ycKyUq8kp5_c-\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">here<\/a>. In both...<\/p>","summary":"In this blog post I will be showing how I wrote a program to solve mazes for me.","date_modified":"2024-08-14T19:34:45+02:00","tags":["algorithms","graphs","image processing","programming","pygame","python","visualisation"],"image":"\/user\/pages\/02.blog\/solving-mazes-with-programming\/maze2.jpg"},{"title":"HueHue: a colourful game","date_published":"2017-11-24T00:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/huehue","url":"https:\/\/mathspp.com\/blog\/huehue","content_html":"<p>HueHue is a very colourful game I wrote with my colleague <a href=\"https:\/\/github.com\/inesfmarques\/\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">@inesfmarques<\/a>.<\/p>\n\n<p><img alt=\"a screenshot of an initial scrambled degradee from the game\" src=\"\/images\/4\/c\/f\/d\/a\/4cfda6d73573a752d17bce5ec37c6b3c848a23f2-astart.webp\"><\/p>\n<p>We programmed a small puzzle game, based solely on colours, that we called HueHue (please mind that the idea for how the game works is not ours). The way the game works is pretty straightforward: you start with a bunch of coloured tiles all mixed up, like in the image above, and then you want to organize them to create a degradee like the one below! The only thing you can take for granted is that the four corners are already correctly placed (and you can't move them, just to prevent accidents).<\/p>\n<p><img alt=\"a screenshot of the corresponding final state with the degradee in place\" src=\"\/user\/pages\/02.blog\/huehue\/end.webp\"><\/p>\n<p>The instructions are also quite simple: you use left and right clicks to swap tiles. Whenever you left-click a tile, you are telling the game that you will want to swap that tile. Whenever you right-click a tile, that tile gets swapped with the last tile you left-clicked! Simple, right?<\/p>\n<p>Or you can just drag the tiles around, that is even simpler.<\/p>\n<p>When you finish the puzzle and rearrange the degradee, the window caption changes and you can't swap any more tiles. To change the number of tiles in the puzzle or their sizes edit the file <code>HueHueConfig.py<\/code>.<\/p>\n<p>When we had the game logic already implemented but were still testing the way we would create the degradee, I created another small script that just populates the screen with a random degradee like the one below. <\/p>\n<p><img alt='a \"continuous\" degradee from the helper script' src=\"\/user\/pages\/02.blog\/huehue\/degradee.webp\"><\/p>\n<p>You can find the code for the game and for the random degradee generator in <a href=\"https:\/\/github.com\/RodrigoGiraoSerrao\/minigames\/tree\/master\/huehue\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">this GitHub folder<\/a>. Enjoy!<\/p>\n<p>How would you improve this game? Let me know in the comments below.<\/p>","summary":"In this post I show you a colourful game I wrote with a friend of mine.","date_modified":"2024-08-13T12:47:46+02:00","tags":["game","programming","pygame","python"],"image":"\/user\/pages\/02.blog\/huehue\/a_start.webp"},{"title":"Random walk simulations in 2D","date_published":"2017-10-26T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/random-walk-simulations","url":"https:\/\/mathspp.com\/blog\/random-walk-simulations","content_html":"<p>Think of a drunk man that continuously tumbles left and right, back and forth, with no final destination.<\/p>\n\n<p><img alt=\"A blue 2D random walk on a green background\" src=\"\/images\/e\/f\/d\/f\/2\/efdf2de1162ef1c66911c2dba75dd7f9e81cc52a-2drandomwalk.webp\"><\/p>\n<p>This drunk man walking around can be thought of as a <a href=\"https:\/\/en.wikipedia.org\/wiki\/Random_walk\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">random walk<\/a> on the plane... Now imagine that the drunk man has a shorter leg and tumbles more to one of the sides: that is a biased random walk. Now imagine the drunk man can teleport to a nearby location. That is (kind of) a <a href=\"https:\/\/en.wikipedia.org\/wiki\/L%C3%A9vy_flight\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">L\u00e8vy flight<\/a>! All those are quite interesting to observe in motion and I implemented them in Python. (the code can be found <a href=\"https:\/\/github.com\/RodrigoGiraoSerrao\/projects\/tree\/master\/randomWalks\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">here<\/a>). From those, only the tilted walks and the one with the trail are such that the particle's movement wraps around the borders (leaving the green area makes the particle appear in the opposite side, just like the snake from the game Snake).<\/p>\n<p>The image above is a screenshot of the execution of the random walk that leaves a coloured trail.<\/p>\n<p>I also implemented an animation where the screen gets progressively filled with circles of different colours, as if being splattered with paint. Not sure why... But it looks interesting:<\/p>\n<p><img alt=\"A black background with several randomly-coloured circles\" src=\"\/user\/pages\/02.blog\/random-walk-simulations\/splatter.webp\"><\/p>\n<p>The implementation is in the same directory as the walks.<\/p>\n<p>For all these, I got windows executables. <a href=\"https:\/\/drive.google.com\/open\" id=\"0ByBeLS6ciLYVX1k0M2Z2Z2RjYkU\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">Here<\/a> you can find all the executables for the random walks and <a href=\"https:\/\/drive.google.com\/open\" id=\"0ByBeLS6ciLYVcDh0a051T3plRlk\" target=\"_blank\" rel=\"nofollow noopener noreferrer\" class=\"external-link no-image\">here<\/a> for the paint splatter.<\/p>","summary":"Check what a 2D random walk really is and how it looks like.","date_modified":"2024-08-13T12:47:46+02:00","tags":["mathematics","programming","random walks","simulation","visualisation","pygame","python"],"image":"\/user\/pages\/02.blog\/random-walk-simulations\/2d_random_walk.webp"}]}
