<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>Jack Ibsen</title><link>https://jmi06.github.io/</link><description>Recent content on Jack Ibsen</description><generator>Hugo -- gohugo.io</generator><language>en-CA</language><copyright>Jack Ibsen</copyright><lastBuildDate>Thu, 09 Jul 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://jmi06.github.io/index.xml" rel="self" type="application/rss+xml"/><item><title>Combined Optimal Route: Audience friendly route optimizations for SailGP</title><link>https://jmi06.github.io/articles/cor/</link><pubDate>Thu, 09 Jul 2026 00:00:00 +0000</pubDate><guid>https://jmi06.github.io/articles/cor/</guid><description>This project won third place at the 13th DeepSense Ocean of Data Challenge
In SailGP, each team takes a slightly different path in order to capitalize on the best wind conditions. Combined Optimal Route (COR) takes the path of every team, and tries to find the most optimal route between them.
If two cars are racing on a track, one on the inside, one on the outside, which car&amp;rsquo;s path will be faster?</description><content:encoded><![CDATA[<p><em>This project won third place at the <a href="https://deepsense.ca/ocean-of-data-challenge/">13th DeepSense Ocean of Data Challenge</a></em></p>
<p>In SailGP, each team takes a slightly different path in order to capitalize on the best wind conditions. Combined Optimal Route (COR) takes the path of every team, and tries to find the most optimal route between them.</p>
<p>If two cars are racing on a track, one on the inside, one on the outside, which car&rsquo;s path will be faster? COR takes this one step further, asking instead: is there a combination of both routes that is actually the fastest?</p>
<p><img alt="GIF example of combining routes" src="/cor/racecar.gif"></p>
<p>For this project, I was given sensor data collected at a frequency of 1Hz across all competing teams, and all races for two SailGP events.</p>
<p>Every second of a leg is represented as a node in a directed graph. Each node contains the boat&rsquo;s heading, coordinates, the current wind speed, wind direction, and time elapsed during the leg. Directed edges are then connected between every node at time \(t\) to every other node at time \(t+1\)</p>
<p>In order to determine how favourable the conditions are to travel between nodes, we apply a weight to our edges. This weight is known as our penalty, the higher the number, the less favourable and realistic the path becomes. The penalty formula is as follows.</p>
\[Penalty = d(1000 + |h_{w} - h_{b}|)(cos(s))\]
<p>Where:</p>
<ul>
<li>\(d\) is the distance between nodes.</li>
<li>\(s\) is the speed of the wind.</li>
<li>\(h_{w}\) is the heading of the wind.</li>
<li>\(h_{b}\) is the heading of the boat.</li>
</ul>
<p>Dijsktra&rsquo;s algorithm is then run on our network to find the route with the lowest combined penalty. This in turn, becomes our most optimal route.</p>
<p><img alt="Examples of Combined Optimal Routes" src="/cor/example_routes.jpg"></p>
<p>Combined Optimal Route is not a perfect solution. For starters, the teams do not all pass these points at the same time. What might have been ideal conditions when the first place team sailed through, may not be ideal by the time the last place team reaches that point. It also does not take into account the real physics of these boats. A catamaran is not able to instantaneously take a 90 degree turn. But Combined Optimal Route is not meant to be a perfect solution. It is meant to allow a television audience to compare their favourite team&rsquo;s decisions, and how they chose to traverse the course. It gives the viewer a quick glance at how efficient each team&rsquo;s route was, and what theoretically could have been the best possible route.</p>
]]></content:encoded></item><item><title>~/Now</title><link>https://jmi06.github.io/now/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jmi06.github.io/now/</guid><description>QuantusSports QuantusSports is in a fairly stable state, the social media bots are working, and the data fetching scripts are doing their jobs. I just finished refactoring, cleaning, and commenting the code in the website repository. These changes will make things much simpler when I implement leagues that use different APIs, or when new sports are not compatible with how the core sports are structured.
Side Projects I am in the process of writing an article for a new metric I built for curling.</description><content:encoded><![CDATA[<h3 id="quantussports">QuantusSports</h3>
<p>QuantusSports is in a fairly stable state, the social media bots are working, and the data fetching scripts are doing their jobs. I just finished refactoring, cleaning, and commenting the code in the <a href="https://github.com/jmi06/Quantus-Sports">website repository</a>. These changes will make things much simpler when I implement leagues that use different APIs, or when new sports are not compatible with how the core sports are structured.</p>
<h3 id="side-projects">Side Projects</h3>
<p>I am in the process of writing an article for a new metric I built for curling. It allows for the comparison between a team&rsquo;s performance and the result they actually achieved.</p>
]]></content:encoded></item><item><title>~/Projects/Glyph</title><link>https://jmi06.github.io/projects/glyph/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jmi06.github.io/projects/glyph/</guid><description>Glyph | January 2026 Python, HTML, CSS
Glyph is a lightweight, TeX inspired markup language written in Python. It uses a syntax similar to TeX with it&amp;rsquo;s heavy use of backward slashes and curly braces. The Python utilty converts the .glyph files to HTML.</description><content:encoded><![CDATA[<h3 class="center" id="glyphhttpsgithubcomjmi06glyph--january-2026"><a href="https://github.com/jmi06/Glyph">Glyph</a> | January 2026</h3>
<p><em>Python, HTML, CSS</em></p>
<div class="image-row">
<p><img alt="Glyph example" src="/projects/glyph-screenshot.png"></p>
</div>
<p>Glyph is a lightweight, TeX inspired markup language written in Python. It uses a syntax similar to TeX with it&rsquo;s heavy use of backward slashes and curly braces. The Python utilty converts the .glyph files to HTML.</p>
]]></content:encoded></item><item><title>~/Projects/Meteo</title><link>https://jmi06.github.io/projects/meteo/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jmi06.github.io/projects/meteo/</guid><description>Meteo | December 2025 Python, Curses, Requests
Meteo is a TUI weather client for Canadian Weather. It fetches weather data from Environment Canada&amp;rsquo;s hidden API. It features current conditions, hourly forecasts, daily forecasts, and weather warnings/alerts.</description><content:encoded><![CDATA[<h3 class="center" id="meteohttpsgithubcomjmi06meteo--december-2025"><a href="https://github.com/jmi06/Meteo">Meteo</a> | December 2025</h3>
<p><em>Python, Curses, Requests</em></p>
<div class="image-row">
<p><img alt="Meteo weather conditions" src="/projects/meteo-screenshot2.png">
<img alt="Meteo warning example" src="/projects/meteo-screenshot1.png"></p>
</div>
<p>Meteo is a TUI weather client for Canadian Weather. It fetches weather data from Environment Canada&rsquo;s hidden API. It features current conditions, hourly forecasts, daily forecasts, and weather warnings/alerts.</p>
]]></content:encoded></item><item><title>~/Projects/PlayerRankings</title><link>https://jmi06.github.io/projects/playerrankings/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jmi06.github.io/projects/playerrankings/</guid><description>PlayerRankings | December 2025 - Present Python, Pandas
I created a Pitcher vs. Batter model to determine who is the best baseball player in MLB. It uses a similar formula to Quantus, except it treats every at-bat as it&amp;rsquo;s own game, and the result of that at-bat determines how much the rating is affected by. For example, if the batter hits a home run, it will impact their rating more than if they draw a walk.</description><content:encoded><![CDATA[<h3 class="center" id="playerrankingshttpsgithubcomjmi06playerrankings--december-2025---present"><a href="https://github.com/jmi06/PlayerRankings">PlayerRankings</a> | December 2025 - Present</h3>
<p><em>Python, Pandas</em></p>
<div class="image-row">
<p><img alt="Example of ratings" src="/projects/pvb-screenshot2.png">
<img alt="File with at bats" src="/projects/pvb-screenshot1.png"></p>
</div>
<p>I created a Pitcher vs. Batter model to determine who is the best baseball player in MLB. It uses a similar formula to Quantus, except it treats every at-bat as it&rsquo;s own game, and the result of that at-bat determines how much the rating is affected by. For example, if the batter hits a home run, it will impact their rating more than if they draw a walk. Similarly for pitchers, if they strikeout a batter, it will impact their rating more than a routine out. It also takes into account the opponents rating, if an ace gives up a home run to a poor hitter, their rating will take a bigger hit and vice versa. The plan is to integrate this into QuantusSports.</p>
]]></content:encoded></item><item><title>~/Projects/QuantusSports</title><link>https://jmi06.github.io/projects/quantussports/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jmi06.github.io/projects/quantussports/</guid><description>QuantusSports | May 2025 - Present Python, Flask, HTML, CSS, JavaScript, Vercel
QuantusSports is a sports analytics and statistics project I started in May 2025. It began as an Elo system for MLB games where point differentials were taken into account. I then ported the system over to the NHL and NBA as well.
The project now houses a number of rating systems, including the original QuantusRatings, and the graph theory based QuantusIndex.</description><content:encoded><![CDATA[<h3 class="center" id="quantussportshttpsquantussportsvercelapp--may-2025---present"><a href="https://quantussports.vercel.app/">QuantusSports</a> | May 2025 - Present</h3>
<p><em>Python, Flask, HTML, CSS, JavaScript, Vercel</em></p>
<div class="image-row">
<p><img alt="QuantusBasketball ratings page" src="/projects/quantussports-screenshot1.png">
<img alt="QuantusHockey team page" src="/projects/quantussports-screenshot3.png"></p>
  <!-- ![QuantusBaseball predictions page](projects/quantussports-screenshot4.png) -->
</div>
<p>QuantusSports is a sports analytics and statistics project I started in May 2025. It began as an Elo system for MLB games where point differentials were taken into account. I then ported the system over to the NHL and NBA as well.</p>
<p>The project now houses a number of rating systems, including the original QuantusRatings, and the graph theory based QuantusIndex.</p>
<p>Each league has it&rsquo;s own BlueSky account where live updates are posted after each game. Each league also features a predictions page, where team ratings are used to make game predictions.</p>
<p>More information about QuantusSports can be found on the <a href="https://quantussports.vercel.app/about">about page</a></p>
]]></content:encoded></item></channel></rss>