
    
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
                
        
        
        
            
{"version":"https:\/\/jsonfeed.org\/version\/1","title":"mathspp.com feed","home_page_url":"https:\/\/mathspp.com\/blog\/tags\/geometry","feed_url":"https:\/\/mathspp.com\/blog\/tags\/geometry.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":"Cyclic trapezoid animation","date_published":"2026-03-14T15:51:00+01:00","id":"https:\/\/mathspp.com\/blog\/cyclic-trapezoid-animation","url":"https:\/\/mathspp.com\/blog\/cyclic-trapezoid-animation","content_html":"<p>See an animation of a trapezoid innscribed in a circle, built with some maths and the help of an LLM.<\/p>\n\n<h2 id=\"the-animation\">The animation<a href=\"#the-animation\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>My brother asked for my help to build an animation of a trapezoid inscribed in a circle that kept changing his shape.\nWith <a href=\"\/blog\/til\/cyclic-quadrilateral\">a bit of maths<\/a> and the help of ChatGPT for the UI, I created the animation you can see below.\nUnder the animation you can find a control panel that allows you to tweak some animation parameters, and under that you can find a brief explanation of how the animation works.<\/p>\n<style>\n  .cyclic-trapezoid-embed {\n    --ctp-panel-bg: color-mix(in srgb, var(--bg, #0b1020) 88%, transparent);\n    --ctp-panel-border: color-mix(in srgb, var(--tx, #e5e7eb) 18%, transparent);\n    --ctp-text: var(--tx, #e5e7eb);\n    --ctp-muted: color-mix(in srgb, var(--tx, #e5e7eb) 65%, transparent);\n    --ctp-input-bg: color-mix(in srgb, var(--bg, #0b1020) 92%, black 8%);\n\n    width: 100%;\n    box-sizing: border-box;\n  }\n\n  .cyclic-trapezoid-embed *,\n  .cyclic-trapezoid-embed *::before,\n  .cyclic-trapezoid-embed *::after {\n    box-sizing: border-box;\n  }\n\n  .cyclic-trapezoid-embed .ctp-canvas-wrap {\n    width: 100%;\n  }\n\n  .cyclic-trapezoid-embed canvas {\n    display: block;\n    width: 100%;\n    height: min(70vh, 800px);\n    min-height: 360px;\n    background: var(--bg, #0b1020);\n    border-radius: 16px;\n  }\n\n  .cyclic-trapezoid-embed .ctp-ui {\n    margin-top: 16px;\n    width: 100%;\n    border-radius: 14px;\n    background: var(--ctp-panel-bg);\n    color: var(--ctp-text);\n    border: 1px solid var(--ctp-panel-border);\n    backdrop-filter: blur(8px);\n    box-shadow: 0 12px 30px rgba(0, 0, 0, 0.18);\n    font-family: system-ui, -apple-system, Segoe UI, Roboto, sans-serif;\n    overflow: hidden;\n  }\n\n  .cyclic-trapezoid-embed .ctp-summary {\n    list-style: none;\n    cursor: pointer;\n    padding: 14px;\n    font-size: 18px;\n    font-weight: 700;\n    user-select: none;\n    display: flex;\n    align-items: center;\n    justify-content: space-between;\n  }\n\n  .cyclic-trapezoid-embed .ctp-summary::-webkit-details-marker {\n    display: none;\n  }\n\n  .cyclic-trapezoid-embed .ctp-ui-content {\n    padding: 0 14px 14px;\n  }\n\n  .cyclic-trapezoid-embed fieldset {\n    margin: 0 0 12px;\n    padding: 10px 10px 6px;\n    border-radius: 10px;\n    border: 1px solid var(--ctp-panel-border);\n    min-width: 0;\n  }\n\n  .cyclic-trapezoid-embed legend {\n    padding: 0 6px;\n    color: var(--ctp-text);\n    font-weight: 600;\n    font-size: 14px;\n  }\n\n  .cyclic-trapezoid-embed .row {\n    display: grid;\n    grid-template-columns: 1fr auto;\n    gap: 10px;\n    align-items: center;\n    margin-bottom: 8px;\n  }\n\n  .cyclic-trapezoid-embed .row label {\n    font-size: 13px;\n    color: var(--ctp-text);\n  }\n\n  .cyclic-trapezoid-embed .row .value {\n    color: var(--ctp-muted);\n    font-size: 12px;\n    min-width: 64px;\n    text-align: right;\n    font-variant-numeric: tabular-nums;\n  }\n\n  .cyclic-trapezoid-embed .control {\n    display: grid;\n    grid-template-columns: 1fr;\n    gap: 4px;\n    margin-bottom: 10px;\n  }\n\n  .cyclic-trapezoid-embed .control label {\n    font-size: 13px;\n    color: var(--ctp-text);\n  }\n\n  .cyclic-trapezoid-embed input[type=\"range\"],\n  .cyclic-trapezoid-embed input[type=\"number\"],\n  .cyclic-trapezoid-embed input[type=\"color\"] {\n    width: 100%;\n  }\n\n  .cyclic-trapezoid-embed input[type=\"number\"] {\n    padding: 6px 8px;\n    border-radius: 8px;\n    border: 1px solid var(--ctp-panel-border);\n    background: var(--ctp-input-bg);\n    color: var(--ctp-text);\n  }\n\n  .cyclic-trapezoid-embed input[type=\"color\"] {\n    height: 36px;\n    padding: 0;\n    border: none;\n    background: transparent;\n    cursor: pointer;\n  }\n\n  .cyclic-trapezoid-embed .buttons {\n    display: flex;\n    gap: 8px;\n    flex-wrap: wrap;\n  }\n\n  .cyclic-trapezoid-embed button {\n    appearance: none;\n    border: 1px solid var(--ctp-panel-border);\n    background: color-mix(in srgb, var(--bg, #0b1020) 80%, var(--tx, #e5e7eb) 8%);\n    color: var(--ctp-text);\n    border-radius: 10px;\n    padding: 9px 12px;\n    cursor: pointer;\n    font-weight: 600;\n  }\n\n  .cyclic-trapezoid-embed button:hover {\n    background: color-mix(in srgb, var(--bg, #0b1020) 72%, var(--tx, #e5e7eb) 14%);\n  }\n\n  .cyclic-trapezoid-embed .hint {\n    font-size: 12px;\n    color: var(--ctp-muted);\n    line-height: 1.35;\n    margin-top: 6px;\n  }\n\n  .cyclic-trapezoid-embed code {\n    font-family: ui-monospace, SFMono-Regular, Menlo, Consolas, monospace;\n  }\n<\/style><div class=\"cyclic-trapezoid-embed\" id=\"cyclic-trapezoid-embed\">\n  <div class=\"ctp-canvas-wrap\">\n    <canvas id=\"ctp-canvas\"><\/canvas><\/div>\n\n  <details class=\"ctp-ui\"><summary class=\"ctp-summary\">Cyclic trapezoid controls<\/summary><div class=\"ctp-ui-content\">\n      <fieldset><legend>Colour<\/legend>\n\n        <div class=\"control\">\n          <label for=\"ctp-bgColor\">Background colour<\/label>\n          <input id=\"ctp-bgColor\" type=\"color\" value=\"#0b1020\"><\/div>\n\n        <div class=\"control\">\n          <label for=\"ctp-circleColor\">Circle colour<\/label>\n          <input id=\"ctp-circleColor\" type=\"color\" value=\"#94a3b8\"><\/div>\n\n        <div class=\"control\">\n          <label for=\"ctp-pointColor\">Points colour<\/label>\n          <input id=\"ctp-pointColor\" type=\"color\" value=\"#f8fafc\"><\/div>\n\n        <div class=\"control\">\n          <label for=\"ctp-parallelColor\">Parallel sides colour<\/label>\n          <input id=\"ctp-parallelColor\" type=\"color\" value=\"#fbbf24\"><\/div>\n\n        <div class=\"control\">\n          <label for=\"ctp-nonParallelColor\">Non-parallel sides colour<\/label>\n          <input id=\"ctp-nonParallelColor\" type=\"color\" value=\"#60a5fa\"><\/div>\n      <\/fieldset><fieldset><legend>Point A<\/legend>\n\n        <div class=\"row\">\n          <label for=\"ctp-aPeriod\">Period<\/label>\n          <div class=\"value\" id=\"ctp-aPeriodValue\"><\/div>\n        <\/div>\n        <input id=\"ctp-aPeriod\" type=\"range\" min=\"2\" max=\"60\" step=\"0.1\" value=\"11\"><\/fieldset><fieldset><legend>Point B<\/legend>\n\n        <div class=\"row\">\n          <label for=\"ctp-bMax\">Max angle<\/label>\n          <div class=\"value\" id=\"ctp-bMaxValue\"><\/div>\n        <\/div>\n        <input id=\"ctp-bMax\" type=\"range\" min=\"15\" max=\"180\" step=\"1\" value=\"165\"><div class=\"row\">\n          <label for=\"ctp-bPeriod\">Period<\/label>\n          <div class=\"value\" id=\"ctp-bPeriodValue\"><\/div>\n        <\/div>\n        <input id=\"ctp-bPeriod\" type=\"range\" min=\"2\" max=\"60\" step=\"0.1\" value=\"7\"><div class=\"row\">\n          <label for=\"ctp-bPhase\">Phase<\/label>\n          <div class=\"value\" id=\"ctp-bPhaseValue\"><\/div>\n        <\/div>\n        <input id=\"ctp-bPhase\" type=\"range\" min=\"0\" max=\"360\" step=\"1\" value=\"0\"><\/fieldset><fieldset><legend>Point D<\/legend>\n\n        <div class=\"row\">\n          <label for=\"ctp-dMax\">Max angle<\/label>\n          <div class=\"value\" id=\"ctp-dMaxValue\"><\/div>\n        <\/div>\n        <input id=\"ctp-dMax\" type=\"range\" min=\"15\" max=\"180\" step=\"1\" value=\"90\"><div class=\"row\">\n          <label for=\"ctp-dPeriod\">Period<\/label>\n          <div class=\"value\" id=\"ctp-dPeriodValue\"><\/div>\n        <\/div>\n        <input id=\"ctp-dPeriod\" type=\"range\" min=\"2\" max=\"60\" step=\"0.1\" value=\"5\"><div class=\"row\">\n          <label for=\"ctp-dPhase\">Phase<\/label>\n          <div class=\"value\" id=\"ctp-dPhaseValue\"><\/div>\n        <\/div>\n        <input id=\"ctp-dPhase\" type=\"range\" min=\"0\" max=\"360\" step=\"1\" value=\"60\"><\/fieldset><fieldset><legend>Global<\/legend>\n\n        <div class=\"row\">\n          <label for=\"ctp-radius\">Circle radius<\/label>\n          <div class=\"value\" id=\"ctp-radiusValue\"><\/div>\n        <\/div>\n        <input id=\"ctp-radius\" type=\"range\" min=\"0.1\" max=\"0.48\" step=\"0.01\" value=\"0.35\"><div class=\"row\">\n          <label for=\"ctp-speed\">Global animation speed<\/label>\n          <div class=\"value\" id=\"ctp-speedValue\"><\/div>\n        <\/div>\n        <input id=\"ctp-speed\" type=\"range\" min=\"0\" max=\"4\" step=\"0.01\" value=\"1\"><\/fieldset><div class=\"buttons\">\n        <button id=\"ctp-resetTime\" type=\"button\">Reset animation time<\/button>\n      <\/div>\n\n      <div class=\"hint\">\n        Point C is computed from the cyclic trapezoid rule:...<\/div><\/div><\/details><\/div>","summary":"See an animation of a trapezoid innscribed in a circle, built with some maths and the help of an LLM.","date_modified":"2026-03-14T17:35:14+01:00","tags":["mathematics","geometry","visualisation","llm"],"image":"\/user\/pages\/02.blog\/cyclic-trapezoid-animation\/thumbnail.webp"},{"title":"TIL #142 \u2013 Cyclic quadrilateral","date_published":"2026-03-14T14:58:00+01:00","id":"https:\/\/mathspp.com\/blog\/til\/cyclic-quadrilateral","url":"https:\/\/mathspp.com\/blog\/til\/cyclic-quadrilateral","content_html":"<p>Today I learned that cyclic quadrilaterals have supplementary opposite angles.<\/p>\n\n<p>A <strong>cyclic quadrilateral<\/strong> \u2014 a quadrilateral whose four vertices all lie on a single circle \u2014 has supplementary opposite angles.<\/p>\n<p>This means that opposite angles add to 180 degrees, or <span class=\"mathjax mathjax--inline\">\\(\\pi\\)<\/span> radians.<\/p>\n<p>As it turns out, this is actually an equivalence relation.\nIf a quadrilateral has supplementary opposite angles, it's a cyclic quadrilateral.<\/p>\n<p>This fact about supplementary opposite angles was very useful for an animation I was trying to create...\nI may share it here later!<\/p>","summary":"Today I learned that cyclic quadrilaterals have supplementary opposite angles.","date_modified":"2026-03-14T16:03:32+01:00","tags":["mathematics","geometry"],"image":"\/user\/pages\/02.blog\/04.til\/142.cyclic-quadrilateral\/thumbnail.webp"},{"title":"TIL #133 \u2013 Shoelace formula","date_published":"2025-09-25T12:16:00+02:00","id":"https:\/\/mathspp.com\/blog\/til\/shoelace-formula","url":"https:\/\/mathspp.com\/blog\/til\/shoelace-formula","content_html":"<p>Today I learned about the shoelace formula to compute the area of arbitrary simple polygons.<\/p>\n\n<p>If you have a polygon with no holes and that doesn't intersect itself you can use the shoelace formula to compute its area. If <span class=\"mathjax mathjax--inline\">\\(P_i = (x_i, y_i), i = 1, \\cdots, n\\)<\/span> are the vertices of the polygon, then the area is given by<\/p>\n<p class=\"mathjax mathjax--block\">\\[\nA = \\frac12 \\left| \\sum_{i = 1}^{n} x_iy_{i + 1} - y_i x_{i + 1} \\right|\\]<\/p>\n<p>In the formula above, <span class=\"mathjax mathjax--inline\">\\(P_{n + 1}\\)<\/span> is <span class=\"mathjax mathjax--inline\">\\(P_1\\)<\/span>.<\/p>\n<p>The formula is super practical and easy to compute, which I find amusing given that it works for any (simple) polygon!<\/p>","summary":"Today I learned about the shoelace formula to compute the area of arbitrary simple polygons.","date_modified":"2025-10-20T22:34:56+02:00","tags":["mathematics","geometry"],"image":"\/user\/pages\/02.blog\/04.til\/133.shoelace-formula\/thumbnail.webp"},{"title":"TIL #120 \u2013 Circle vs rectangle collision detection","date_published":"2025-03-06T23:45:00+01:00","id":"https:\/\/mathspp.com\/blog\/til\/circle-vs-rectangle-collision-detection","url":"https:\/\/mathspp.com\/blog\/til\/circle-vs-rectangle-collision-detection","content_html":"<p>Today I learned how to detect collisions between circles and rectangles with 100% accuracy.<\/p>\n\n<h2 id=\"circle-vs-rectangle-collision-detection\">Circle vs rectangle collision detection<a href=\"#circle-vs-rectangle-collision-detection\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>In a <a href=\"\/blog\/javascript-2d-scrolling-game-tutorial\">JavaScript tutorial I published recently<\/a>, the game that I presented included some very basic collision detection between a circle and a rectangle, and it used the circle's bounding box.\nThis meant that the collision detection sucked if the circle was close to the corners of the rectangle.<\/p>\n<p>Today I sat down to think about it for a second and figured out how to implement pixel-perfect collision detection between a rectangle and a circle, as the demo below demonstrates:<\/p>\n<canvas id=\"mainCanvas1\" style=\"background:var(--ui); margin: auto; display: block;\"><\/canvas><script>\n    const canvas1 = document.getElementById(\"mainCanvas1\");\n    const ctx1 = canvas1.getContext(\"2d\");\n\n    const WIDTH = Math.min(600, 0.95 * document.documentElement.clientWidth);\n    const HEIGHT = 400;\n    canvas1.width = WIDTH;\n    canvas1.height = HEIGHT;\n\n    var style = window.getComputedStyle(document.body);\n    const RED = style.getPropertyValue(\"--re\");\n    const GREEN = style.getPropertyValue(\"--gr\");\n    const CIRCLE_COLOUR = style.getPropertyValue(\"--tx\");\n\n    const radius = 25;\n\n    function draw1(evt) {\n        ctx1.clearRect(0, 0, canvas1.width, canvas1.height);\n\n        \/\/ Get mouse position.\n        var rect = canvas1.getBoundingClientRect();\n        var x = evt.clientX - rect.left;\n        var y = evt.clientY - rect.top;\n\n        \/\/ Draw the rectangle.\n        ctx1.fillStyle = collision1(x, y) ? RED : GREEN;\n        ctx1.fillRect(WIDTH \/ 4, HEIGHT \/ 4, WIDTH \/ 2, HEIGHT \/ 2);\n\n        \/\/ Draw the circle.\n        ctx1.fillStyle = CIRCLE_COLOUR;\n        ctx1.beginPath();\n        ctx1.arc(x, y, radius, 0, 2 * Math.PI);\n        ctx1.fill();\n    }\n\n    function collision1(x, y) {\n        var left = WIDTH \/ 4, right = 3 * WIDTH \/ 4;\n        var top = HEIGHT \/ 4, bottom = 3 * HEIGHT \/ 4;\n        var corners = [\n            { x: left, y: top },\n            { x: right, y: top },\n            { x: left, y: bottom },\n            { x: right, y: bottom },\n        ];\n        for (var c of corners) {\n            if ((c.x - x) ** 2 + (c.y - y) ** 2 <= radius ** 2) {\n                return true;\n            }\n        }\n        return (x >= left - radius && x <= right + radius && y >= top && y <= bottom) || (x >= left && x <= right && y >= top - radius && y <= bottom + radius);\n    }\n\n    document.addEventListener(\n        \"mousemove\",\n        draw1,\n    );\n<\/script><p>The first thing I implemented was pixel-perfect collision detection with the <em>corners<\/em> of the rectangle.\nThis is easy to check because each corner is a single point and to check if a single point is inside a circle amounts to checking if the distance between the point and the centre of the circle is less than the radius of the circle:<\/p>\n<p class=\"mathjax mathjax--block\">\\[\n(p_x - c_x)^2 + (p_y - c_y)^2 \\leq r^2\\ ?\\]<\/p>\n<p>In the demo below, try getting the circle close to the corners of the rectangle: that's when a collision is detected.<\/p>\n<canvas id=\"mainCanvas2\" style=\"background:var(--ui); margin: auto; display: block;\"><\/canvas><script>\n    const canvas2 = document.getElementById(\"mainCanvas2\");\n    const ctx2 = canvas2.getContext(\"2d\");\n\n    canvas2.width = WIDTH;\n    canvas2.height = HEIGHT;\n\n    function draw2(evt) {\n        ctx2.clearRect(0, 0, canvas2.width, canvas2.height);\n\n        \/\/ Get mouse position.\n        var rect = canvas2.getBoundingClientRect();\n        var x = evt.clientX - rect.left;\n        var y = evt.clientY - rect.top;\n\n        \/\/ Draw the rectangle.\n        ctx2.fillStyle = collision2(x, y) ? RED : GREEN;\n        ctx2.fillRect(WIDTH \/ 4, HEIGHT \/ 4, WIDTH \/ 2, HEIGHT...<\/script>","summary":"Today I learned how to detect collisions between circles and rectangles with 100% accuracy.","date_modified":"2025-10-20T22:34:56+02:00","tags":["geometry","javascript","programming"],"image":"\/user\/pages\/02.blog\/04.til\/120.circle-vs-rectangle-collision-detection\/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 #051 \u2013 Heron&#039;s formula","date_published":"2022-09-05T00:00:00+02:00","id":"https:\/\/mathspp.com\/blog\/til\/herons-formula","url":"https:\/\/mathspp.com\/blog\/til\/herons-formula","content_html":"<p>Today I (re)learned Heron's formula to compute the area of a triangle from its three sides.<\/p>\n\n<p><img alt=\"A blurred image of two triangles with many arbitrary mathematical formulas floating in front of them, and the words \u201cHeron's formula\u201d in big white letters in the centre.\" src=\"\/images\/6\/c\/3\/2\/1\/6c3212f5944cf70467ff207e77261cbc3b27d63f-thumbnail.webp\"><\/p>\n<h2 id=\"heron-s-formula\">Heron's formula<a href=\"#heron-s-formula\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Heron's formula is a formula that lets you compute the <em>area<\/em> of a triangle from the lengths of its three sides <span class=\"mathjax mathjax--inline\">\\(a\\)<\/span>, <span class=\"mathjax mathjax--inline\">\\(b\\)<\/span>, and <span class=\"mathjax mathjax--inline\">\\(c\\)<\/span>:<\/p>\n<p class=\"mathjax mathjax--block\">\\[\n\\sqrt{s \\times (s - a) \\times (s - b) \\times (s - c)}\\]<\/p>\n<p>The value <span class=\"mathjax mathjax--inline\">\\(s\\)<\/span> is the semi-perimeter of the triangle, which is half the perimeter, <span class=\"mathjax mathjax--inline\">\\(\\frac{a + b + c}{2}\\)<\/span>.<\/p>\n<h2 id=\"proof-of-heron-s-formula\">Proof of Heron's formula<a href=\"#proof-of-heron-s-formula\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Heron's formula is not too hard to prove.\nYou can prove it algebraically by considering an arbitrary triangle that is subdivided into two smaller right triangles by the height of one side.\nThen, you determine the side lengths of those two triangles with respect to the original lengths <span class=\"mathjax mathjax--inline\">\\(a\\)<\/span>, <span class=\"mathjax mathjax--inline\">\\(b\\)<\/span>, and <span class=\"mathjax mathjax--inline\">\\(c\\)<\/span>, and you massage the numbers around until the formula shows up.<\/p>\n<p>If you would like a more detailed proof, you can always drop a comment below!<\/p>\n<p>That's it for now! <a href=\"\/subscribe\">Stay tuned<\/a> and I'll see you around!<\/p>","summary":"Today I (re)learned Heron&#039;s formula to compute the area of a triangle from its three sides.","date_modified":"2025-07-23T16:49:02+02:00","tags":["geometry","mathematics"],"image":"\/user\/pages\/02.blog\/04.til\/051.herons-formula\/thumbnail.webp"},{"title":"Problem #057 \u2013 how to find the circle centre","date_published":"2022-03-13T00:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/problems\/how-to-find-the-circle-centre","url":"https:\/\/mathspp.com\/blog\/problems\/how-to-find-the-circle-centre","content_html":"<p>Can you find the centre of the circle with just five lines?<\/p>\n\n<figure class=\"image-caption\"><img title=\"Photo by Luis Eusebio on Unsplash.\" alt=\"\" src=\"\/images\/b\/7\/2\/2\/8\/b72284c909165f91b635b4001f78d188d188ce6c-thumbnail.webp\"><figcaption class=\"\">Photo by Luis Eusebio on Unsplash.<\/figcaption><\/figure><h2 id=\"problem-statement\">Problem statement<a href=\"#problem-statement\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Suppose you have a circle, like the one in the figure below.\nAt your disposal, you have a compass, a straightedge\n(like a ruler, but without length ticks),\nand a pencil.<\/p>\n<figure class=\"image-caption\"><img title=\"A circle.\" alt=\"A black circle on a white background.\" src=\"\/user\/pages\/02.blog\/03.problems\/p057-how-to-find-the-circle-centre\/_circle.webp\"><figcaption class=\"\">A circle.<\/figcaption><\/figure><p>Can you find the centre of the circle with just five lines?\n(Every time you use the compass counts as one line,\nand every time you use the straightedge counts as another line.)<\/p>\n<div class=\"notices blue\">\n<p>Give it some thought!<\/p>\n<\/div>\n<p>If you need any clarification whatsoever, feel free to ask in the comment section below.<\/p>\n<h2 id=\"solvers\">Solvers<a href=\"#solvers\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Congratulations to the ones that solved this problem correctly and, in particular, to the ones\nwho sent me their correct solutions:<\/p>\n<ul><li>Dmitry R., USA;<\/li>\n<li>Martin J., Czech Republic;<\/li>\n<li>David H., Taiwan;<\/li>\n<li>Mario R., Ecuador;<\/li>\n<li>Paul M., USA;<\/li>\n<li>Luis C., Peru;<\/li>\n<li>Pietro P., Italy;<\/li>\n<\/ul><p>Know how to solve this?\nJoin the list of solvers by <a href=\"mailto:rodrigo@mathspp.com?subject=Solution%20to%20Problem%20#057%20%E2%80%93%20how%20to%20find%20the%20circle%20centre\" class=\"mailto\">emailing me<\/a> your solution!<\/p>\n<h2 id=\"solution\">Solution<a href=\"#solution\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>There are many ways in which the centre of the circle can be found!\nHowever, doing that with just 5 lines is the challenge.<\/p>\n<h3 id=\"deductive-reasoning\">Deductive reasoning<a href=\"#deductive-reasoning\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h3>\n<p>Recall that the centre of the circle is the point that is at the same distance of all the points in the circumference.\nSo, if you draw <em>any<\/em> chord and then draw its bisector, you know that bisector will go through the centre of the circle (point A in the figure):<\/p>\n<figure class=\"image-caption\"><img title=\"The bisector of a chord goes through the circle centre.\" alt=\"A circle with an arbitrary chord with endpoints D and E. Auxiliary circles were drawn from D to E and from E to D, and their intersections defined the bisector of the chord. The bisector goes through the centre of the original circle.\" src=\"\/user\/pages\/02.blog\/03.problems\/p057-how-to-find-the-circle-centre\/_chord_bisector.webp\"><figcaption class=\"\">The bisector of a chord goes through the circle centre.<\/figcaption><\/figure><p>In the figure above, I picked two arbitrary points D and E and drew the chord [DE].\nThen, I used D and E two draw to circles:<\/p>\n<ul><li>one centred at D with radius equal to the length of [DE]; and<\/li>\n<li>another centred at E with radius equal to the length of [DE].<\/li>\n<\/ul><p>Then, the line defined by the two intersections of those two circles goes through the centre (A).\nIf we do that once more, the intersections of those two bisectors give you the centre:<\/p>\n<figure class=\"image-caption\"><img title=\"The intersection of the two chords defines the centre.\" alt=\"Same process repeated on a second chord, whose bisector intersected with the first one at the centre of the original circle.\" src=\"\/user\/pages\/02.blog\/03.problems\/p057-how-to-find-the-circle-centre\/_two_chord_bisectors.webp\"><figcaption class=\"\">The intersection of the two chords defines the centre.<\/figcaption><\/figure><p>However, this uses a total of 8 lines.\nWe want to do this in just 5...\nAnd yet, going down to 6 lines is easy:\nwe just need to realise we don't really care about the chords, only their endpoints...\nAnd picking arbitrary points on the circumference doesn't cost any &ldquo;lines&rdquo;:<\/p>\n<figure class=\"image-caption\"><img title=\"4 circles and 2 lines make up a total of 6 lines.\" alt=\"Same drawing, but with the chords erased.\" src=\"\/user\/pages\/02.blog\/03.problems\/p057-how-to-find-the-circle-centre\/_six_moves.webp\"><figcaption class=\"\">4 circles and 2 lines make up a total of 6 lines.<\/figcaption><\/figure><p>The final step comes from realising that we don't need 4 separate circles!\nThe two bisector lines of the implied chords can be drawn with just 3 circles if we pick the points well enough!<\/p>\n<p>After drawing the first two auxiliary circles, pick one of the circles.\nThat circle will intersect the original circle at a point that you haven't used yet (H in the figure below).\nUse that point as the centre of the third circle, which you can draw with a radius equal to the other two auxiliary circles:...<\/p>","summary":"Can you find the centre of the circle with just 5 lines?","date_modified":"2025-07-23T16:49:02+02:00","tags":["geometry","mathematics"],"image":"\/user\/pages\/02.blog\/03.problems\/p057-how-to-find-the-circle-centre\/thumbnail.webp"},{"title":"Problem #049 \u2013 coin pyramid","date_published":"2021-11-14T00:00:00+01:00","id":"https:\/\/mathspp.com\/blog\/problems\/coin-pyramid","url":"https:\/\/mathspp.com\/blog\/problems\/coin-pyramid","content_html":"<p>Can you make the pyramid point the other way by moving only three coins?<\/p>\n\n<figure class=\"image-caption\"><img title=\"10 coin pyramid.\" alt=\"10 coins laid in a pyramid, with the tip to the right.\" src=\"\/images\/7\/2\/b\/1\/2\/72b12a2c78542b5b286f5cdcce0e432a916333e5-thumbnail.webp\"><figcaption class=\"\">10 coin pyramid.<\/figcaption><\/figure>\n<h2 id=\"problem-statement\">Problem statement<a href=\"#problem-statement\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>The image above shows a pyramid composed of 10 coins:\n4 coins, then 3, then 2, then 1.<\/p>\n<p>Your task is to make the pyramid point the other way by moving\n<em>only<\/em> three coins.<\/p>\n<p>In the image above, that means you want the pyramid to be pointing to the left.<\/p>\n<p>With a figure, if the initial pyramid is<\/p>\n<pre><code class=\"language-txt\">O O O O\n O O O\n  O O\n   O<\/code><\/pre>\n<p>you have to make it look like<\/p>\n<pre><code class=\"language-txt\">   O\n  O O \n O O O\nO O O O<\/code><\/pre>\n<p>Again, only moving 3 coins.<\/p>\n<p>The purpose of the puzzle is not for you to find a loophole in the instructions.<\/p>\n<div class=\"notices blue\">\n<p>Give it some thought!<\/p>\n<\/div>\n<p>If you need any clarification whatsoever, feel free to ask in the comment section below.<\/p>\n<p>This problem was shared by a solver of a previous problem, so thank <em>you<\/em>!<\/p>\n<h2 id=\"solvers\">Solvers<a href=\"#solvers\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>Congratulations to the ones that solved this problem correctly and, in particular, to the ones\nwho sent me their correct solutions:<\/p>\n<ul>\n<li>David H., Taiwan;<\/li>\n<li>Zech Z., US;<\/li>\n<li>Diana O., Venezuela;<\/li>\n<li>Michael W., US;<\/li>\n<li>Christ van W., Netherlands;<\/li>\n<li>Arun, Canada;<\/li>\n<li>Gabbar S., India;<\/li>\n<li>Andr\u00e9 R., Canada;<\/li>\n<li>Luiz G., UK;<\/li>\n<li>Daniel D., Sweden;<\/li>\n<li>Nishant M., India;<\/li>\n<li>Tahoor B., India;<\/li>\n<li>Nelson R., India;<\/li>\n<li>Rex B., US;<\/li>\n<li>Marco M., Italy;<\/li>\n<li>Pedro G., Portugal;<\/li>\n<li>Vikas Z., India;<\/li>\n<li>Robin B., Scotland;<\/li>\n<li>Michal K., Czech Republic;<\/li>\n<li>\u201cHelaxious\u201d, Brazil;<\/li>\n<li>Kees de L., Netherlands;<\/li>\n<li>Reza M., Kenya;<\/li>\n<li>Alex van V., Netherlands;<\/li>\n<\/ul>\n<p>Know how to solve this?<\/p>\n<p>Join the list of solvers by <a href=\"mailto:rodrigo@mathspp.com?subject=Solution%20to%20Problem%20#049%20%E2%80%93%20coin%20pyramid\" class=\"mailto\">emailing me<\/a> your solution!<\/p>\n<h2 id=\"solution\">Solution<a href=\"#solution\" class=\"toc-anchor after\" data-anchor-icon=\"#\" aria-label=\"Anchor\"><\/a><\/h2>\n<p>It is easier to <em>show<\/em> you the solution than it is to explain it to you,\nbut what you want to do is take the three corner coins and \u201cmove them to the opposite side\u201d:<\/p>\n<figure class=\"image-caption\"><img title=\"A depiction of the coin pyramid pointing to the other side.\" alt=\"\" src=\"\/user\/pages\/02.blog\/03.problems\/p049-coin-pyramid\/_solution.webp\"><figcaption class=\"\">A depiction of the coin pyramid pointing to the other side.<\/figcaption><\/figure>\n<p><a href=\"\/subscribe\">Don't forget to subscribe to the newsletter<\/a> to get bi-weekly\nproblems sent straight to your inbox.<\/p>","summary":"Can you make the pyramid point the other way by moving only three coins?","date_modified":"2025-07-23T16:49:02+02:00","tags":["geometry","mathematics"],"image":"\/user\/pages\/02.blog\/03.problems\/p049-coin-pyramid\/thumbnail.webp"}]}
