Abhinav Kumar https://abhinavcode13.github.io/ Tue, 08 Jul 2025 15:38:30 +0000 Tue, 08 Jul 2025 15:38:30 +0000 Jekyll v3.10.0 Making Sense of Curves: Drawing Tangents and Normals with Diagrams Library <p>Drawing <em>tangent</em> and <em>normal</em> vectors on curves helps understand how curves behave. The <a href="https://diagrams.github.io/">Diagrams library</a> in Haskell makes this easy. Based on <a href="https://photon-ray.xyz/diagramatics-site/examples/">Pontus Granström’s example</a>, here’s how to do it.</p> <p>First, import the libraries:</p> <div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kr">import</span> <span class="nn">Diagrams.Backend.SVG.CmdLine</span> <span class="kr">import</span> <span class="nn">Diagrams.Prelude</span> </code></pre></div></div> <p>Define your points and create a smooth curve:</p> <div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">pts</span> <span class="o">=</span> <span class="n">map</span> <span class="n">p2</span> <span class="p">[(</span><span class="mi">0</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="mi">1</span><span class="p">),</span> <span class="p">(</span><span class="mi">3</span><span class="p">,</span><span class="mi">0</span><span class="p">),</span> <span class="p">(</span><span class="mf">3.5</span><span class="p">,</span><span class="mi">0</span><span class="p">)]</span> <span class="n">spline</span> <span class="o">::</span> <span class="kt">Located</span> <span class="p">(</span><span class="kt">Trail</span> <span class="kt">V2</span> <span class="kt">Double</span><span class="p">)</span> <span class="n">spline</span> <span class="o">=</span> <span class="n">cubicSpline</span> <span class="kt">False</span> <span class="n">pts</span> </code></pre></div></div> <p>Pick a point on the curve and get its vectors:</p> <div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">param</span> <span class="o">=</span> <span class="mf">0.45</span> <span class="n">pt</span> <span class="o">=</span> <span class="n">atParam</span> <span class="n">spline</span> <span class="n">param</span> <span class="n">tangentVector</span> <span class="o">=</span> <span class="n">tangentAtParam</span> <span class="n">spline</span> <span class="n">param</span> <span class="n">normalVector</span> <span class="o">=</span> <span class="n">normalAtParam</span> <span class="n">spline</span> <span class="n">param</span> </code></pre></div></div> <p>Create the visual elements - lines for vectors and a square for the right angle:</p> <div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">symmetricLine</span> <span class="n">v</span> <span class="o">=</span> <span class="n">fromOffsets</span> <span class="p">[</span><span class="mi">2</span> <span class="o">*^</span> <span class="n">v</span><span class="p">]</span> <span class="o">#</span> <span class="n">center</span> <span class="n">tangentLine</span> <span class="o">=</span> <span class="n">symmetricLine</span> <span class="n">tangentVector</span> <span class="n">normalLine</span> <span class="o">=</span> <span class="n">symmetricLine</span> <span class="n">normalVector</span> <span class="n">rightAngleSquare</span> <span class="o">=</span> <span class="n">square</span> <span class="mf">0.1</span> <span class="o">#</span> <span class="n">alignBL</span> <span class="o">#</span> <span class="n">rotate</span> <span class="p">(</span><span class="n">signedAngleBetween</span> <span class="n">tangentVector</span> <span class="n">unitX</span><span class="p">)</span> </code></pre></div></div> <p>Finally, put everything together:</p> <div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">example</span> <span class="o">::</span> <span class="kt">Diagram</span> <span class="kt">B</span> <span class="n">example</span> <span class="o">=</span> <span class="n">frame</span> <span class="mf">0.5</span> <span class="o">$</span> <span class="n">strokeLocTrail</span> <span class="n">spline</span> <span class="o">&lt;&gt;</span> <span class="n">mconcat</span> <span class="p">[</span> <span class="n">tangentLine</span> <span class="p">,</span> <span class="n">baselineText</span> <span class="s">"tangent"</span> <span class="o">#</span> <span class="n">translate</span> <span class="n">tangentVector</span> <span class="p">,</span> <span class="n">normalLine</span> <span class="p">,</span> <span class="n">topLeftText</span> <span class="s">"normal"</span> <span class="o">#</span> <span class="n">translate</span> <span class="n">normalVector</span> <span class="p">,</span> <span class="n">rightAngleSquare</span> <span class="p">]</span> <span class="o">#</span> <span class="n">moveTo</span> <span class="n">pt</span> <span class="o">#</span> <span class="n">fontSize</span> <span class="n">large</span> </code></pre></div></div> <p>A <strong>tangent vector</strong> shows which way the curve is pointing at any point. The <strong>normal vector</strong> sits at a right angle to the tangent, pointing away from the curve. We use a <strong>parameter</strong> - just a number - to tell us exactly where we are along the curve.</p> <p>Seeing math as pictures makes it much easier to understand than staring at equations. You can quickly check if your calculations are right by looking at the visual result. This builds intuition faster than pure algebra.</p> <p>You could animate the vectors to show how they change as you move along the curve. Another idea is to display vectors at several points at once. You might also add curvature circles to show how sharply the curve bends.</p> <p>Check out the <a href="https://diagrams.github.io/">Diagrams docs</a> for more examples. The <a href="https://diagrams.github.io/gallery/Tangent.html">original example</a> by <a href="https://x.com/pnutus" target="_blank">Pontus Granström</a> shows this code in action. Learn more about <a href="https://www.haskell.org/">Haskell</a> to write your own diagrams.</p> <p><img src="https://abhinavcode13.github.io/assets/tangent-curve.png" alt="Tangent and Normal Vectors on a Curve" /></p> <hr /> <p><em>Simple code for drawing tangent and normal vectors on curves using Haskell’s Diagrams library.</em></p> Sun, 06 Jul 2025 00:00:00 +0000 https://abhinavcode13.github.io/mathematics/haskell/diagrams/2025/07/06/visualizing-tangent-normal-vectors-with-diagrams.html https://abhinavcode13.github.io/mathematics/haskell/diagrams/2025/07/06/visualizing-tangent-normal-vectors-with-diagrams.html tangent normal vectors curves mathematics haskell diagrams When Disks Dance: Visualizing Hanoi’s Puzzle in Haskell <p>Ever wondered what the <a href="https://en.wikipedia.org/wiki/Tower_of_Hanoi">Towers of Hanoi</a> puzzle looks like when solved step by step? I found this cool Haskell code that shows the solution as pictures. It’s really neat to watch the disks move around!</p> <p>The Towers of Hanoi is that old puzzle with three pegs and some disks of different sizes. You have to move all disks from the left peg to the right peg, but you can only move one disk at a time and you can never put a bigger disk on top of a smaller one.</p> <p>Here’s how the code works:</p> <p>First, it picks some nice colors for the disks:</p> <div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">colors</span> <span class="o">=</span> <span class="n">cycle</span> <span class="o">$</span> <span class="n">map</span> <span class="n">sRGB24read</span> <span class="p">[</span> <span class="s">"#9FB4CC"</span><span class="p">,</span> <span class="s">"#CCCC9F"</span><span class="p">,</span> <span class="s">"#DB4105"</span><span class="p">,</span> <span class="s">"#FFF8E3"</span><span class="p">,</span> <span class="s">"#33332D"</span><span class="p">]</span> </code></pre></div></div> <p>Each disk gets a different color based on its size. The bigger disks are wider rectangles, which makes sense when you look at it.</p> <p>To draw a single disk, it makes a rectangle with width based on the disk number:</p> <div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">renderDisk</span> <span class="o">::</span> <span class="kt">Disk</span> <span class="o">-&gt;</span> <span class="kt">Dia</span> <span class="n">renderDisk</span> <span class="n">n</span> <span class="o">=</span> <span class="n">rect</span> <span class="p">(</span><span class="n">fromIntegral</span> <span class="n">n</span> <span class="o">+</span> <span class="mi">2</span><span class="p">)</span> <span class="mi">1</span> <span class="o">#</span> <span class="n">lc</span> <span class="n">black</span> <span class="o">#</span> <span class="n">lw</span> <span class="n">thin</span> <span class="o">#</span> <span class="n">fc</span> <span class="p">(</span><span class="n">colors</span> <span class="o">!!</span> <span class="n">n</span><span class="p">)</span> </code></pre></div></div> <p>For a whole stack of disks, it just piles them up on top of a peg:</p> <div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">renderStack</span> <span class="o">::</span> <span class="kt">Stack</span> <span class="o">-&gt;</span> <span class="kt">Dia</span> <span class="n">renderStack</span> <span class="n">s</span> <span class="o">=</span> <span class="n">disks</span> <span class="p">`</span><span class="n">atop</span><span class="p">`</span> <span class="n">post</span> <span class="kr">where</span> <span class="n">disks</span> <span class="o">=</span> <span class="p">(</span><span class="n">vcat</span> <span class="o">.</span> <span class="n">map</span> <span class="n">renderDisk</span> <span class="o">$</span> <span class="n">s</span><span class="p">)</span> <span class="o">#</span> <span class="n">alignB</span> <span class="n">post</span> <span class="o">=</span> <span class="n">rect</span> <span class="mf">0.8</span> <span class="mi">6</span> <span class="o">#</span> <span class="n">lw</span> <span class="n">none</span> <span class="o">#</span> <span class="n">fc</span> <span class="n">black</span> <span class="o">#</span> <span class="n">alignB</span> </code></pre></div></div> <p>The cool part happens in the solving. The algorithm uses recursion - that’s when a function calls itself. For n disks, it:</p> <ol> <li>Moves n-1 disks from the start to the middle peg</li> <li>Moves the biggest disk to the end</li> <li>Moves the n-1 disks from the middle to the end</li> </ol> <div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">solveHanoi</span> <span class="o">::</span> <span class="kt">Int</span> <span class="o">-&gt;</span> <span class="p">[</span><span class="kt">Move</span><span class="p">]</span> <span class="n">solveHanoi</span> <span class="n">n</span> <span class="o">=</span> <span class="n">solveHanoi'</span> <span class="n">n</span> <span class="mi">0</span> <span class="mi">1</span> <span class="mi">2</span> <span class="kr">where</span> <span class="n">solveHanoi'</span> <span class="mi">0</span> <span class="kr">_</span> <span class="kr">_</span> <span class="kr">_</span> <span class="o">=</span> <span class="kt">[]</span> <span class="n">solveHanoi'</span> <span class="n">n</span> <span class="n">a</span> <span class="n">b</span> <span class="n">c</span> <span class="o">=</span> <span class="n">solveHanoi'</span> <span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="n">a</span> <span class="n">c</span> <span class="n">b</span> <span class="o">++</span> <span class="p">[(</span><span class="n">a</span><span class="p">,</span><span class="n">c</span><span class="p">)]</span> <span class="o">++</span> <span class="n">solveHanoi'</span> <span class="p">(</span><span class="n">n</span><span class="o">-</span><span class="mi">1</span><span class="p">)</span> <span class="n">b</span> <span class="n">a</span> <span class="n">c</span> </code></pre></div></div> <p>The <code class="language-plaintext highlighter-rouge">doMove</code> function actually does each move by taking a disk from one stack and putting it on another:</p> <div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">doMove</span> <span class="o">::</span> <span class="kt">Move</span> <span class="o">-&gt;</span> <span class="kt">Hanoi</span> <span class="o">-&gt;</span> <span class="kt">Hanoi</span> <span class="n">doMove</span> <span class="p">(</span><span class="n">x</span><span class="p">,</span><span class="n">y</span><span class="p">)</span> <span class="n">h</span> <span class="o">=</span> <span class="n">h''</span> <span class="kr">where</span> <span class="p">(</span><span class="n">d</span><span class="p">,</span><span class="n">h'</span><span class="p">)</span> <span class="o">=</span> <span class="n">removeDisk</span> <span class="n">x</span> <span class="n">h</span> <span class="n">h''</span> <span class="o">=</span> <span class="n">addDisk</span> <span class="n">y</span> <span class="n">d</span> <span class="n">h'</span> <span class="n">removeDisk</span> <span class="n">x</span> <span class="n">h</span> <span class="o">=</span> <span class="p">(</span><span class="n">head</span> <span class="p">(</span><span class="n">h</span><span class="o">!!</span><span class="n">x</span><span class="p">),</span> <span class="n">modList</span> <span class="n">x</span> <span class="n">tail</span> <span class="n">h</span><span class="p">)</span> <span class="n">addDisk</span> <span class="n">y</span> <span class="n">d</span> <span class="o">=</span> <span class="n">modList</span> <span class="n">y</span> <span class="p">(</span><span class="n">d</span><span class="o">:</span><span class="p">)</span> </code></pre></div></div> <p>Finally, it makes a list of all the puzzle states and shows them stacked up and down:</p> <div class="language-haskell highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">renderHanoiSeq</span> <span class="o">::</span> <span class="p">[</span><span class="kt">Hanoi</span><span class="p">]</span> <span class="o">-&gt;</span> <span class="kt">Dia</span> <span class="n">renderHanoiSeq</span> <span class="o">=</span> <span class="n">vcat'</span> <span class="p">(</span><span class="n">with</span> <span class="o">&amp;</span> <span class="n">sep</span> <span class="o">.~</span><span class="mi">2</span><span class="p">)</span> <span class="o">.</span> <span class="n">map</span> <span class="n">renderHanoi</span> </code></pre></div></div> <p>Pretty cool how a few lines of code can show you exactly how an algorithm works, right? Sometimes the best way to understand something is to see it in action.</p> <p><img src="https://abhinavcode13.github.io/assets/Towerofhanoi.png" alt="Towers of Hanoi Solution" /></p> <hr /> <p><em>Visualizing the classic Towers of Hanoi puzzle solution using Haskell and the Diagrams library.</em></p> Tue, 28 Jan 2025 00:00:00 +0000 https://abhinavcode13.github.io/algorithms/haskell/diagrams/puzzles/2025/01/28/towers-of-hanoi-visual-solution.html https://abhinavcode13.github.io/algorithms/haskell/diagrams/puzzles/2025/01/28/towers-of-hanoi-visual-solution.html towers-of-hanoi recursion visualization haskell algorithms haskell diagrams puzzles Understanding context.WithTimeout in Go <p>When you’re building real-world applications, things don’t always go as expected. Maybe an external API is slow, or a background process takes longer than it should. If your program just waits and waits, it can block everything else.</p> <p>Go provides the <code class="language-plaintext highlighter-rouge">context</code> package to help deal with these situations. Specifically, <code class="language-plaintext highlighter-rouge">context.WithTimeout</code> lets you define a maximum time an operation should take — and cancels it if it runs too long.</p> <p>This post walks through a simple example using <code class="language-plaintext highlighter-rouge">context.WithTimeout</code>, and how you can apply it in real applications.</p> <p><strong>What is the context Package?</strong><br /> The <code class="language-plaintext highlighter-rouge">context</code> package in Go helps manage deadlines, cancellation signals, and request-scoped data across goroutines. In other words, it gives you control over when to stop waiting for something that’s taking too long.</p> <p><strong>Why Timeouts Matter</strong><br /> Imagine making a network call to an external service. If it hangs or takes too long, your entire app might get stuck. Timeouts help prevent this. By setting a limit on how long you’ll wait, you make your application more robust and responsive.</p> <p><strong>A Simple Timeout Example</strong></p> <p>Let’s start by simulating a slow operation that takes 5 seconds to complete, but give it only 2 seconds to finish.</p> <div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span> <span class="n">main</span> <span class="k">import</span> <span class="p">(</span> <span class="s">"context"</span> <span class="s">"fmt"</span> <span class="s">"time"</span> <span class="p">)</span> <span class="k">func</span> <span class="n">slowOperation</span><span class="p">(</span><span class="n">ctx</span> <span class="n">context</span><span class="o">.</span><span class="n">Context</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span> <span class="k">select</span> <span class="p">{</span> <span class="k">case</span> <span class="o">&lt;-</span><span class="n">time</span><span class="o">.</span><span class="n">After</span><span class="p">(</span><span class="m">5</span> <span class="o">*</span> <span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">)</span><span class="o">:</span> <span class="k">return</span> <span class="no">nil</span> <span class="k">case</span> <span class="o">&lt;-</span><span class="n">ctx</span><span class="o">.</span><span class="n">Done</span><span class="p">()</span><span class="o">:</span> <span class="k">return</span> <span class="n">ctx</span><span class="o">.</span><span class="n">Err</span><span class="p">()</span> <span class="p">}</span> <span class="p">}</span> <span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">cancel</span> <span class="o">:=</span> <span class="n">context</span><span class="o">.</span><span class="n">WithTimeout</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">Background</span><span class="p">(),</span> <span class="m">2</span><span class="o">*</span><span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">)</span> <span class="k">defer</span> <span class="n">cancel</span><span class="p">()</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">slowOperation</span><span class="p">(</span><span class="n">ctx</span><span class="p">)</span> <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Operation failed:"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span> <span class="k">return</span> <span class="p">}</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Operation succeeded"</span><span class="p">)</span> <span class="p">}</span> </code></pre></div></div> <ul> <li><code class="language-plaintext highlighter-rouge">time.After(5 * time.Second)</code> simulates a slow task.</li> <li><code class="language-plaintext highlighter-rouge">ctx.Done()</code> is a channel that is closed when the context is canceled or times out.</li> <li>Since our context times out in 2 seconds, the function returns early with an error: <code class="language-plaintext highlighter-rouge">context deadline exceeded</code>.</li> </ul> <p><strong>Making an HTTP Request with Timeout</strong></p> <p>Here’s a practical use case: making an HTTP request that you don’t want to hang indefinitely.</p> <div class="language-go highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">package</span> <span class="n">main</span> <span class="k">import</span> <span class="p">(</span> <span class="s">"context"</span> <span class="s">"fmt"</span> <span class="s">"net/http"</span> <span class="s">"time"</span> <span class="p">)</span> <span class="k">func</span> <span class="n">main</span><span class="p">()</span> <span class="p">{</span> <span class="n">ctx</span><span class="p">,</span> <span class="n">cancel</span> <span class="o">:=</span> <span class="n">context</span><span class="o">.</span><span class="n">WithTimeout</span><span class="p">(</span><span class="n">context</span><span class="o">.</span><span class="n">Background</span><span class="p">(),</span> <span class="m">2</span><span class="o">*</span><span class="n">time</span><span class="o">.</span><span class="n">Second</span><span class="p">)</span> <span class="k">defer</span> <span class="n">cancel</span><span class="p">()</span> <span class="n">req</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">http</span><span class="o">.</span><span class="n">NewRequestWithContext</span><span class="p">(</span><span class="n">ctx</span><span class="p">,</span> <span class="n">http</span><span class="o">.</span><span class="n">MethodGet</span><span class="p">,</span> <span class="s">"https://httpbin.org/delay/5"</span><span class="p">,</span> <span class="no">nil</span><span class="p">)</span> <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Error creating request:"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span> <span class="k">return</span> <span class="p">}</span> <span class="n">resp</span><span class="p">,</span> <span class="n">err</span> <span class="o">:=</span> <span class="n">http</span><span class="o">.</span><span class="n">DefaultClient</span><span class="o">.</span><span class="n">Do</span><span class="p">(</span><span class="n">req</span><span class="p">)</span> <span class="k">if</span> <span class="n">err</span> <span class="o">!=</span> <span class="no">nil</span> <span class="p">{</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Request failed:"</span><span class="p">,</span> <span class="n">err</span><span class="p">)</span> <span class="k">return</span> <span class="p">}</span> <span class="k">defer</span> <span class="n">resp</span><span class="o">.</span><span class="n">Body</span><span class="o">.</span><span class="n">Close</span><span class="p">()</span> <span class="n">fmt</span><span class="o">.</span><span class="n">Println</span><span class="p">(</span><span class="s">"Response status:"</span><span class="p">,</span> <span class="n">resp</span><span class="o">.</span><span class="n">Status</span><span class="p">)</span> <span class="p">}</span> </code></pre></div></div> <p>In this example:</p> <ul> <li>We request an endpoint that intentionally waits 5 seconds before replying.</li> <li>But our context times out in 2 seconds.</li> <li>The request fails quickly, and we avoid a long delay.</li> </ul> <p><strong>Best Practices and Common Mistakes</strong></p> <ul> <li>Always call <code class="language-plaintext highlighter-rouge">cancel()</code> when you use <code class="language-plaintext highlighter-rouge">context.WithTimeout</code> (or <code class="language-plaintext highlighter-rouge">WithCancel</code>). This cleans up resources used by the context and avoids memory leaks.</li> <li>Don’t ignore <code class="language-plaintext highlighter-rouge">ctx.Err()</code> – this tells you why the context ended (timeout, manual cancel, etc).</li> <li>Don’t block forever – if you don’t listen to <code class="language-plaintext highlighter-rouge">ctx.Done()</code>, your goroutines may never exit.</li> </ul> <p><strong>When to Use context.WithTimeout</strong></p> <ul> <li>You need to limit how long an operation can run.</li> <li>You’re making external calls (e.g., HTTP, DB).</li> <li>You want graceful cancellation across goroutines.</li> </ul> Mon, 10 Jun 2024 00:00:00 +0000 https://abhinavcode13.github.io/golang/programming/2024/06/10/context-withtimeout-go.html https://abhinavcode13.github.io/golang/programming/2024/06/10/context-withtimeout-go.html go context timeout cancellation golang programming