I made a website that stitches together maps generated in the video game Minecraft and displays them with various labeled points of interest.
This is another app scaffolded and built with the Vue CLI, written in TypeScript and with some components that use TSX and render functions. It uses the RBush library to spatially index the map elements and the Bezier.js library to help create SVG curves. The data used by the frontend is built by a small Python program that includes a module written in the Cython extension language in order to process binary data from the Minecraft files at very high speeds. This was a surprisingly math- and data-heavy project.
There already exists a lot of software that generates maps from Minecraft worlds, but I didn't want this program to generate new maps - I wanted to extract and display the ones that I had organically created in-game. These maps consisted of various static images that portrayed a world at very different levels of detail, so I needed to separate the map areas that were mapped out at the higher level of detail and thus could be zoomed in on from those that weren't. To do this, I grouped adjacent maps at similar levels of detail into "islands" and displayed the available islands as part of the "zoom in" interaction.
The more interesting problem was stopping users from panning away from a high-detail island and into low-detail territory while they were zoomed in. To do this, the build step generates data for polygons that enclose all the maps of each island and the front end treats the sides of these as collision bounds that interact with an imaginary point at the center of the user's screen, with the goal of keeping this point from escaping the current island (except when "cutting across" a concave corner; the polygons are altered to leave room for that.) To do this, I perform a simple point-in-polygon test to see if a user's interaction kept the center-of-the-screen point inside the polygon and, if not, I find the closest point on the polygon to the one the user was aiming towards and move the map so that the screen is centered on that. (This method of projecting the collision point back onto the polygon means that the component of its movement vector that wasn't responsible for trying to leave the polygon is preserved (i.e. if you try to pan the map diagonally off an island you will slide along its edge instead of just stopping.))
I also wanted to display organically curved paths on the map that went from point to point without having to manually draw them. To do this, I connected the points with imaginary line segments, calculated the slopes of the tangents of the corners where those line segments meet, and created Bezier curves that had the same slopes at the same points but interpolated them smoothly in between.