This is a post about the development of Speed Snek. In the game of Speed Snek, the snek segments are drawn using solid links (like an articulated bus!). I need to figure out how to place these solid line segments along the user's input, which will be a squiggly line drawn using a finger or pointer.
The general process
Here's how I plan to implement it.
- Fix the beginning of the snek segment to either the user's finger/pointer (for the first segment) or the end of the preceding segment (for all other segments)
- Go down the user's input path (implemented as a list of canvas coordinates) until it reaches a point on the path that cannot be reached by the current snek segment (). The end point of the segment must lie on the line drawn between that point and the previous point .
- Figure out where on the line the end of the segment will lie.
- Trim the user input path data, so unnecessary path data isn't being stored in memory.
If all goes well, the snek should follow the user's input, with all articulation points falling on the input path like so:
The math
As seen in the figure above, it comes down to figuring out the intersection of the line segment determined by and with the circle of radius centered at .
The points on the segment can be defined parametrically by
where . Since the distance between this point and must be , we can use the Pythagorean theorem to get the equation
This can be cleaned up into a quadratic equation for
That's the quadratic formula, I know how to solve that! And so...
where
It's not pretty, but it shouldn't be too difficult to implement. The value of can then be plugged back into (1) to get the end point for the segment. Of course a quadratic formula can give us two answers, but we only care about cases where . What about if both values of match the range? Well, that's a problem for future me.