elliptical canvas.arc?


I've been reading over the Canvas API and am a bit puzzled by the 
inconsistency of the available draw commands.

There are four primitives: line, arc and curve (2nd order as well as 3rd 
order bezier, unfortunately named rather poorly, so even though the 3rd 
order should be called cubicCurveTo, it's for some reason called 
bezierCurveTo). These can be used to draw several shapes that are 
sometimes considered primitives: n-gons (triangles, rectangles, 
quadrilangles, etc), n-curves (arcs, elliptoids, polycurves) and the 
generally not considered primitive "path".

There is a line(), and a rect(), but no triangle(). However, given that 
any polygon can be drawn with beginshape/lineto/endshape makes it more a 
curious omission that a problem. There is an arc(), but no circle(). 
Again, not a genuine problem, but if the idea is to enable creativity 
through canvas, it's kind of silly to need a full arc command if all you 
want to do is call circle(x,y,radius). Much more severe is that there is 
no corresponding elliptical arc command. This means that people cannot 
draw ellitical arcs, nor ellipses. Now, this is genuinely puzzling 
because the first thing you add to a graphical context is an elliptical 
arc, because it lets people draw circles as well as general elliptoids, 
so it already covered every draw operation in that family. The current 
canvas draft, however, goes with the circular arc and so misses out on 
what is essentially a crucial draw primitive.

This omission should not remain the case for the final API. The fact 
that the arc command was made circular rather than elliptical means that 
at the very least there is a need for an addition "ellipsArc" in order 
to draw ellipses and elliptical arcs. I would like to suggest the 
following function for inclusion in the API:

   context.ellipticalArc(x, y, semi-major-radius, semi-minor-radius, 
startAngle, endAngle)

I left off the anticlockwise indicator because frankly I believe adding 
that to the current arc command was a mistake (the parameter ordering 
dictates that an arc is draw from "start" to "end", and for decades we 
have drawn these things with the numbers going up. So an arc from 0 to 
1/2 * PI is the exact complement of an arc from 1/2 * PI to 0). That 
said, adding it in for consistency with arc is up to the working group.

That said, while it is possible that some believe the API is already too 
far in its draft process to change something like this, I would like to 
remind everyone that the whole point of a draft is to make sure 
everything makes sense before making it as final - now is the only time 
oddities like these can still be caught. Browser makers can change their 
browsers and push an update as long as the API is in draft, but once it 
hits final, that's it. Any oddity left in is there essentially forever.

To explain a bit more why this command is necessary: every graphics 
package in existence lets users define ellipses. From Illustrator to 
Sketchup to Processing to Maya, people expect to be able to draw 
ellipses, and canvas currently simply can't. That alone should be reason 
enough to add an elliptical arc command, so that every kind of 
elliptical curve can be drawn. Extending the API to offer an 
ellipticalArc command will fix this problem, and will fix this with 
virtually no work for those who have to implement it. A proper circular 
implementation uses Y = ±sqrt(r² *(1- X²/r²)) = ±sqrt(constant - x²), a 
proper elliptical implementation uses Y = ±sqrt(ry² * (1- X²/rx²) = 
±sqrt(constant - X² * constant) - running through the function doesn't 
even require an extra multiplication because the range + step size used 
in the loop to determine X/Y coordinates can be scaled before entering 
the loop - aside from that scaling, their runtime performance is identical.

Hopefully I've made a bit of a case for the inclusion of an elliptical 
arc command (better yet, replacement of the current circular one, 
although as long as there's an elliptical arc in addition to a circular 
arc, all common draw primitives are covered, and that's the most 
important part).

- Mike Kamermans

Received on Tuesday, 10 May 2011 08:25:41 UTC