Distance shapes playground
The previous four posts about distance shapes in Euclidean and taxicab geometries included illustrations that differed from the ones in my earlier posts about taxicab geometry. In those posts, I hard-coded points and lines in SVGs. Basic shapes like circles, ellipses, and parabolas are fairly easy to work out by hand. To draw ovals of Cassini I used an algebraic approach, but it was limited to cases where the foci were aligned vertically with each other. For more complex shapes, and cover all possible variations of those shapes, I made a distance shape playground. You can find the latest version of it here.
The buttons on the right add shapes to the both grids, the upper grid showing the shape in Euclidean geometry, while the lower uses the Manhattan distance to draw the shape in taxicab geometry. The same control points are used for both plots. Drag points to change the shapes. To reset the plots, click the "Clear" button. To export a plot as an SVG, click "Export SVG" on the upper right of each plot.
The current implementation defines each shape as a two-dimensional signed distance function, where negative values denote the inside of a shape, positive values the outside, and zero values the boundary. To draw the boundary, it uses a simple marching squares algorithm. It's not particularly fast, especially not at the level of recursion needed for a smooth curve. Thus, when dragging points, you'll see the recursion level drop and shapes become less precise, which helps keep the visual responsive, though it's by no means as fast as one would hope.
Nor is the algorithm flawless. The boundary will occasionally spill into a square whose corners are all outside the shape, so the boundary inside that square is missing. It also misses cases where the boundary itself becomes two-dimensional, as it can for midsets and difference-based hyperbolas. But speed wasn't necessary for the few static illustrations I needed, and unhandled edge cases were easy to avoid.
I played with partial support for additional Minkowski distances, but while the shapes were interesting, their meaning was much harder to intuit, and broken edge cases were more common.
The original prototype, with all the same functionality, was about 500 lines of ClojureScript code. The public playground is slightly shorter, thanks to offloading some functions I commonly use to a library.
If you have suggestions for improvements, I'm happy to hear them.