Added a couple more general-purpose functions
Change in algorithm: find endpoints via triangles

Since we now have a triangulation algorithm that is doing the right
thing with stroke widths, we can count on properties like "triangles
at an endpoint have only one side not shared with the outline". So
our new algorithm becomes:

1) Triangulate the outline.
2) Remove all sides from consideration that are also on the outline.
3) Turn all remaining sides into midpoints, but still grouped as triangles.
4) Any triangles with just one midpoint? That's an endpoint.
5) Any triangles with two midpoints? That's a simple midline.
6) Any triangles with three midpoints? That's an intersection.

Also, all midpoints will appear in precisely two triangles (the only
midpoints that would appear in only one triangle were along outline
line segments, and we've already eliminated those). We can use this
to find the "next" point for triangles with two midpoints (which is
most of them).

The current commit is just the first step towards this algorithm. It
only identifies endpoints. But it seems to identify them correctly.
Fix bug where off-curve points were being used
WIP on new midpoint-drawing algorithm

I've written down the general features the algorithm should have,
but not yet implemented it. Will implement later, but now's a good
time to make a commit and leave a record of my implementation plan.