Given a field of disks, and given a disk, find a path by which you can move the disk to the edge of the field without having the disk intersect with the other disks.
Click the add buttons to add any number of disks to canvas. Click the clear button to remove all drawings from the canvas. Click the canvas to place a starting puck at any given location, when you click another location that puck ceases to be the starting puck and the newest puck created becomes the starting puck.
This program is implmented entirely in javascript with 3 files:
There's javascript that serves a wrapper in the main page, but it mostly serves as a wrapper for these functions (mostly the Demo.render() method). In general during each render the program:
Every delaunay edge is the closest path from one point to another, and each circumcicle is equadistant between each of the points. Futhermore each triangle's circumcircle does not contain any other point. What that means is a puck can pass between 2 other points if there's a delaunay edge between them and the puck can fit between them. A puck can pass through a triangle if it can fit in the circumcenter's radius. Due to the fact this is a delaunay triangulation, those points on the edges are the farthest away from adjacent disks. Circumcircle centers are the farthest away from the verticies of the delaunay triangulation.
I'm able to determine the convex hull in O(n) time since I kept track of neighbors. Each edge has between 1 and 2 neighbors in the triangulation. If there exists a triangle that has 1 neighbor and it were not on the convex hull, then there must be an outer edge not on the convex hull. If there is an outer edge that not on the convex hull, it must be in a hole. Since this triangulation does not include holes, then any edge with one neighbor has to be on the convex hull.
I modified the existing delaunay triangulation methods by adding some methods to the api like midpoint. But more importantly I've fixed an issue that would have delaunay.js run in O(n^2) time in exchange for adding O(2n) space, which is neglible since delaunay.js takes up O(n) space originally. I did this by replacing the arrays with custom-built sets.
I've used sets whenever possible so that duplicate detection can be done in O(1) time. I've stored a radius in each vertex for the possiblility of having variable sized pucks, something that I was not able to achieve. Each I split puck into 2 methods so they could possibly split during certain operations, another optimization I was not able to achieve.
Credits to Google for Canvas.js, and Joshua Bell for the modified Delaunay.js
This work is dedicated to the Public Domain.