This is a story from the series Behind the Scene: Zen Lattice.
For drawing in the browser, I compared 2 options: Paper.js and D3.js. Viewing from many aspects D3.js would have won the favor for its wide community support and much more advanced development… But Paper.js won because of one little factor: rounding corners.
Drawing a triangle is a given in a lot of scripting languages, but rounded corner control is not well supported. I know I know, if I were to think like developer, I would have put the rounded corner as “least concerned”...In my drawing though, I can’t let go of the rounded corner of the triangles, because it’s part of the design that makes this piece less like a mathematical lattice study, but more of an art. It creates negative spaces, which lubricate our perception of the rotation.
So the first thing I did is to figure out how to create a round corner with a specified radius on any triangle. Yona Appletree answered on Stack Overflow and his Interactive Demo with Code Example. This is a pretty robust plugin that would round any corner of any SVG points, which means it can be combined with D3.js. But for my usage, I want something hacky and lightweight. I don’t want all the options and controls to weight down other stuff I’m trying to do.
Thanks to the almighty Stack Overflow, I found a paper.js function posted by Alex Blackwood. Matt Reyer later refined the code on Gist. It’s very neat, no dependency, fewer lines, and code that I could actually read and understand. What this function does is:
It uses your input r to interpolate 2 points and 2 handle bars, and draws a Bezier curve to approximate the arc. Visually this is fine for most angles, as long as you’re not too keen on the accuracy of your radius. It’s quick to process if you just want to smooth a jagged line. It does 99% of to job and I could almost rest in peace, if only I could ignore a tiny problem: The radius input is not what it meant to be.
Technically when we say we need to round an angle by a radius of r, we mean this:
In Paper.js, a regular polygon is drawn by define the number of sides and the radius of the polygon. So if we draw a regular triangle with a radius R, then round its corners by R/2, it should become a circle:
But with Alex’s paper.js function, it only goes this far:
Stack Overflow provided some clue, that using Bezier curve to accurately approximate an geometrical arc is hard. Here’s part 1 and part 2 of a paper with the math formulas. That’s probably why Paper.js still hasn’t built any native function to round any corner. Here’s a blog post by Hans Muller, talking about doing it for Flex (2001) with ActionScript. He based his demo on this paper: approximation of A Cubic Beszier Curve By Circular Arcs And Vice Versa.
I’ll leave this topic for my future exploration. At this point I decided that Alex’s function is good enough for me.