<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Thezida</title><link>https://www.thezida.com/</link><description>Recent content on Thezida</description><generator>Hugo</generator><language>en-us</language><lastBuildDate>Tue, 29 Sep 2026 18:18:27 +0200</lastBuildDate><atom:link href="https://www.thezida.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Hello World</title><link>https://www.thezida.com/posts/hello-world/</link><pubDate>Tue, 29 Sep 2026 18:18:27 +0200</pubDate><guid>https://www.thezida.com/posts/hello-world/</guid><description>&lt;h1 id="this-is-hello-world-post"&gt;This is hello world post&lt;/h1&gt;&#10;&lt;p&gt;My first Hugo post.&lt;/p&gt;</description></item><item><title>PDF merger</title><link>https://www.thezida.com/tools/pdf-merger/</link><pubDate>Sun, 01 Feb 2026 12:00:00 +0200</pubDate><guid>https://www.thezida.com/tools/pdf-merger/</guid><description>&lt;div class="pdf-merger"&gt;&#10; &lt;p&gt;Select two or more PDF files, arrange them in the order you want, and merge them in your browser.&lt;/p&gt;&#10; &lt;p&gt;&#10; &lt;label for="pdf-merger-files"&gt;PDF files&lt;/label&gt;&lt;br&gt;&#10; &lt;input id="pdf-merger-files" type="file" multiple accept="application/pdf,.pdf"&gt;&#10; &lt;/p&gt;&#10; &lt;ol id="pdf-merger-list" aria-label="PDFs in merge order"&gt;&lt;/ol&gt;&#10; &lt;button id="pdf-merger-submit" type="button"&gt;Merge PDFs&lt;/button&gt;&#10; &lt;p id="pdf-merger-status" role="status" aria-live="polite"&gt;&lt;/p&gt;&#10; &lt;a id="pdf-merger-download" hidden download="merged.pdf"&gt;Download merged PDF&lt;/a&gt;&#10;&lt;/div&gt;&#10;&#10;&lt;style&gt;&#10;.pdf-merger ol { padding-left: 1.5rem; }&#10;.pdf-merger li { margin: .5rem 0; }&#10;.pdf-merger li button { margin-left: .4rem; }&#10;.pdf-merger #pdf-merger-files { max-width: 100%; }&#10;.pdf-merger [hidden] { display: none; }&#10;&lt;/style&gt;&#10;&#10;&lt;script type="module"&gt;&#10;import createQpdf from 'https://cdn.jsdelivr.net/npm/qpdf-wasm-esm-embedded@1.1.1/qpdf.mjs';&#10;&#10;const fileInput = document.getElementById('pdf-merger-files');&#10;const fileList = document.getElementById('pdf-merger-list');&#10;const mergeButton = document.getElementById('pdf-merger-submit');&#10;const status = document.getElementById('pdf-merger-status');&#10;const download = document.getElementById('pdf-merger-download');&#10;let files = [];&#10;let qpdfPromise;&#10;&#10;function renderFiles() {&#10; fileList.replaceChildren();&#10; files.forEach((file, index) =&gt; {&#10; const item = document.createElement('li');&#10; item.append(document.createTextNode(file.name + ' '));&#10;&#10; const moveUp = document.createElement('button');&#10; moveUp.type = 'button';&#10; moveUp.textContent = 'Move up';&#10; moveUp.disabled = index === 0;&#10; moveUp.setAttribute('aria-label', `Move ${file.name} up`);&#10; moveUp.addEventListener('click', () =&gt; {&#10; [files[index - 1], files[index]] = [files[index], files[index - 1]];&#10; renderFiles();&#10; });&#10;&#10; const moveDown = document.createElement('button');&#10; moveDown.type = 'button';&#10; moveDown.textContent = 'Move down';&#10; moveDown.disabled = index === files.length - 1;&#10; moveDown.setAttribute('aria-label', `Move ${file.name} down`);&#10; moveDown.addEventListener('click', () =&gt; {&#10; [files[index], files[index + 1]] = [files[index + 1], files[index]];&#10; renderFiles();&#10; });&#10;&#10; const remove = document.createElement('button');&#10; remove.type = 'button';&#10; remove.textContent = 'Remove';&#10; remove.setAttribute('aria-label', `Remove ${file.name}`);&#10; remove.addEventListener('click', () =&gt; {&#10; files.splice(index, 1);&#10; renderFiles();&#10; });&#10;&#10; item.append(moveUp, moveDown, remove);&#10; fileList.append(item);&#10; });&#10;}&#10;&#10;fileInput.addEventListener('change', (event) =&gt; {&#10; files.push(...Array.from(event.target.files));&#10; renderFiles();&#10; status.textContent = `${files.length} PDF${files.length === 1 ? '' : 's'} selected.`;&#10; download.hidden = true;&#10; event.target.value = '';&#10;});&#10;&#10;mergeButton.addEventListener('click', async () =&gt; {&#10; if (files.length &lt; 2) {&#10; status.textContent = 'Select at least two PDF files.';&#10; return;&#10; }&#10;&#10; mergeButton.disabled = true;&#10; download.hidden = true;&#10; status.textContent = 'Loading PDF merger…';&#10; try {&#10; qpdfPromise ??= createQpdf();&#10; const qpdf = await qpdfPromise;&#10; status.textContent = 'Merging PDFs…';&#10;&#10; for (let i = 0; i &lt; files.length; i++) {&#10; qpdf.FS.writeFile(`/in${i}.pdf`, new Uint8Array(await files[i].arrayBuffer()));&#10; }&#10;&#10; const args = ['--empty', '--pages'];&#10; for (let i = 0; i &lt; files.length; i++) args.push(`/in${i}.pdf`, '1-z');&#10; args.push('--', '/merged.pdf');&#10; await qpdf.callMain(args);&#10;&#10; const output = qpdf.FS.readFile('/merged.pdf');&#10; const url = URL.createObjectURL(new Blob([output], { type: 'application/pdf' }));&#10; download.href = url;&#10; download.hidden = false;&#10; status.textContent = 'Your merged PDF is ready.';&#10; } catch (error) {&#10; console.error(error);&#10; status.textContent = 'Could not merge these PDFs. Check that they are valid PDF files and try again.';&#10; } finally {&#10; mergeButton.disabled = false;&#10; }&#10;});&#10;&lt;/script&gt;</description></item><item><title>Geometry algorithm sandbox</title><link>https://www.thezida.com/posts/geometry-sandbox/</link><pubDate>Fri, 16 May 2025 12:00:00 +0200</pubDate><guid>https://www.thezida.com/posts/geometry-sandbox/</guid><description>&lt;div class="geometry-sandbox"&gt;&#10; &lt;div class="canvas-container"&gt;&#10;&#10; &lt;canvas class="canvas-window" id="canvas" width="600" height="600"&#10; oncontextmenu="event.preventDefault()"&gt;&lt;/canvas&gt;&#10;&#10; &lt;div class="canvas-output" id="output"&gt;&#10; FPS: N/A&#10; &lt;/div&gt;&#10;&#10; &lt;div class="canvas-output" id="vertices"&gt;&#10; Number of vertices: 0&#10; &lt;/div&gt;&#10;&#10; &lt;div class="button-container"&gt;&#10; &lt;button class="canvas-button" id="resetButton"&gt;Reset&lt;/button&gt;&#10;&#10; &lt;button class="canvas-button" id="undoButton"&gt;Undo&lt;/button&gt;&#10;&#10; &lt;button class="canvas-button" id="configButton"&gt;Config&lt;/button&gt;&#10;&#10; &lt;button class="canvas-button" id="prButton"&gt;Pause&lt;/button&gt;&#10; &lt;/div&gt;&#10;&#10; &lt;div class="input-container"&gt;&#10; &lt;button class="canvas-button" id="setConfigButton"&gt;Set configuration&lt;/button&gt;&#10;&#10; &lt;label for="algorithm-name"&gt;Choose an algorithm:&lt;/label&gt;&#10; &lt;select id="algorithm-name" name="algorithm-name"&gt;&#10; &lt;option value="NoAlgorithm"&gt;No Algorithm&lt;/option&gt;&#10; &lt;option value="ConvexHullNaive"&gt;Convex Hull Naive&lt;/option&gt;&#10; &lt;option value="ConvexHullGraham"&gt;Convex Hull Graham&lt;/option&gt;&#10; &lt;option value="ConvexHullJarvis"&gt;Convex Hull Jarvis&lt;/option&gt;&#10; &lt;option value="ConvexHullChan"&gt;Convex Hull Chan&lt;/option&gt;&#10; &lt;option value="SpatialIndexingGrid"&gt;Spatial Indexing Grid&lt;/option&gt;&#10; &lt;option value="SpatialIndexingQuadTree"&gt;Spatial Indexing Quad Tree&lt;/option&gt;&#10; &lt;/select&gt;&#10;&#10; &lt;label for="collisions"&gt;Collisions&lt;/label&gt;&#10; &lt;input type="checkbox" id="collisions" name="collisions"&gt;&#10;&#10; &lt;label for="gravity-global"&gt;Global gravity&lt;/label&gt;&#10; &lt;input type="checkbox" id="gravity-global" name="gravity-global"&gt;&#10;&#10; &lt;label for="gravity-particle"&gt;Gravity per particle&lt;/label&gt;&#10; &lt;input type="checkbox" id="gravity-particle" name="gravity-particle"&gt;&#10;&#10; &lt;label for="minSize"&gt;Min size in pixels:&lt;/label&gt;&#10; &lt;div class="input-number-container"&gt;&#10; &lt;button class="decrease" id="decrease-minSize"&gt;&amp;#x2193;&lt;/button&gt;&#10; &lt;input type="number" id="minSize" name="minSize" step="1" value="10"&gt;&#10; &lt;button class="increase" id="increase-minSize"&gt;&amp;#x2191;&lt;/button&gt;&#10; &lt;/div&gt;&#10;&#10; &lt;label for="maxSize"&gt;Max size in pixels:&lt;/label&gt;&#10; &lt;div class="input-number-container"&gt;&#10; &lt;button class="decrease" id="decrease-maxSize"&gt;&amp;#x2193;&lt;/button&gt;&#10; &lt;input type="number" id="maxSize" name="maxSize" step="1" value="100"&gt;&#10; &lt;button class="increase" id="increase-maxSize"&gt;&amp;#x2191;&lt;/button&gt;&#10; &lt;/div&gt;&#10; &lt;/div&gt;&#10;&#10; &lt;div class="instructions"&gt;&#10; &lt;h3&gt;Instructions&lt;/h3&gt;&#10; &lt;p&gt;Click anywhere to spawn a point. Size of spawned point will be random between currently set minimal and&#10; maximal size. Point will also be given random velocity vector. Button &lt;b&gt;Reset&lt;/b&gt; removes all points&#10; and button &lt;b&gt;Undo&lt;/b&gt; removes last added point.&lt;/p&gt;&#10; &lt;p&gt;Current configuration can be seen by clicking on button &lt;b&gt;Config&lt;/b&gt;. There you can set config you want&#10; and then press button &lt;b&gt;Run&lt;/b&gt; to resume simulation. Same thing could also be achieved with keyboard&#10; key &lt;b&gt;I&lt;/b&gt; for opening and closing configuration and keyboard key &lt;b&gt;P&lt;/b&gt; for pausing and resuming&#10; simulation. If you are on &lt;u&gt;&lt;i&gt;Smartphone&lt;/i&gt;&lt;/u&gt; it is recommended to use input fileds below&#10; simulation&#10; window and button&#10; &lt;b&gt;Set configuration&lt;/b&gt;. But all combinations of given are possible.&#10; &lt;/p&gt;&#10; &lt;p&gt;Buttons &lt;b&gt;Run&lt;/b&gt; and &lt;b&gt;Pause&lt;/b&gt; are shown depending of current state of simulation. You can use them&#10; for pausing and resuming simulation. When you pause simulation but configuration window is not open you&#10; can still play with adding and removing points.&lt;/p&gt;&#10; &lt;p&gt;There are few possible configuration parameters you can set and are listed bellow.&lt;/p&gt;&#10; &lt;p&gt;Algorthm name chooses one of the available algorithms for rendering.&lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;NoAlgorithm&lt;/i&gt;&lt;/u&gt; renders only points.&lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;ConvexHullNaive&lt;/i&gt;&lt;/u&gt; renders convex hull for all points using naive algorithm.&lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;ConvexHullGraham&lt;/i&gt;&lt;/u&gt; renders convex hull for all points using Graham scan algorithm. It&#10; collors upper&#10; and lower hull differently.&lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;ConvexHullJarvis&lt;/i&gt;&lt;/u&gt; renders convex hull for all points using Jarvis algorithm.&#10; Currently rendering&#10; doesn't differ from naive algorithm but if you have suggestions on how to color it send me an email :).&#10; &lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;ConvexHullChan&lt;/i&gt;&lt;/u&gt; renders convex hull for all points using Chans algorithm. It renders&#10; jarvis outter&#10; hull red and graham scan inner upper and lower hulls orange and yellow respectively.&lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;SpatialIndexingGrid&lt;/i&gt;&lt;/u&gt; renders spatial indexing method using uniform grid. It colors&#10; red those boxes&#10; which currently contain a point.&lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;SpatialIndexingQuadTree&lt;/i&gt;&lt;/u&gt; renders spatial indexing method using quad tree. It renders&#10; quad tree&#10; nodes with maximum depth of 3.&lt;/p&gt;&#10; &lt;p&gt;This simulation has also some basic physics implemented. Explanation for each follows.&lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;Collisions&lt;/i&gt;&lt;/u&gt; toggles collisions between particles. It currently uses mix of position&#10; based approach&#10; and approach decribled in &lt;a&#10; href="chrome-extension://efaidnbmnnnibpcajpcglclefindmkaj/https://www.phys.ufl.edu/~kevin/teaching/2060/08spring/two-body_collisions.pdf"&gt;here&lt;/a&gt;.&#10; &lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;Global gravity&lt;/i&gt;&lt;/u&gt; toggles global gravity directed down for all particles.&lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;Gravity per particle&lt;/i&gt;&lt;/u&gt; toggles gravity of each particle. When it is on, each particle will&#10; exert&#10; pulling force on other particles based on its size. Bigger the particle bigger the force.&lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;Min size in pixels&lt;/i&gt;&lt;/u&gt; defines currently minimum size of point radius in pixels. Note: when&#10; resizing&#10; windows these will automatically change.&lt;/p&gt;&#10; &lt;p&gt;&lt;u&gt;&lt;i&gt;Max size in pixels&lt;/i&gt;&lt;/u&gt; defines currently maximal size of point radius in pixels. Note: when&#10; resizing&#10; windows these will automatically change.&lt;/p&gt;&#10;&#10; &lt;/div&gt;&#10;&#10; &lt;/div&gt;&#10;&lt;/div&gt;</description></item><item><title>About</title><link>https://www.thezida.com/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.thezida.com/about/</guid><description>&lt;p&gt;I’m a Software Engineer working on performance engineering for ADAS platforms. I enjoy digging into how hardware and software work together and finding ways to make systems run more efficiently.&lt;/p&gt;</description></item><item><title>Search</title><link>https://www.thezida.com/search/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://www.thezida.com/search/</guid><description/></item></channel></rss>