Search code examples
javascriptcanvasangleellipse

Is the Canvas2D ellipse() specification/implementation incorrect?


I've been playing around with how to render wireframe perspective-correct spheres using only canvas2d and ellipse math. It's been fun, but I've soon come to realize that the ellipse() function has a very strange implementation with regards to the spec.

Indeed, the ellipse function takes 7 (or 8) arguments:

ellipse(x, y, radiusX, radiusY, rotation, startAngle, endAngle)

The startAngle is described as such:

The angle at which the ellipse starts, measured clockwise from the positive x-axis and expressed in radians.

Given a parameter 0 <= t <= 2 * PI, we can compute the position of the associated point on the ellipse like so:

let dx = radiusX * cos(t)
let dy = radiusY * sin(t)

let px = x + dx * cos(rotation) - dy * sin(rotation)
let py = y + dx * sin(rotation) + dy * cos(rotation)

And if we use startAngle = t, our ellipse will begin its arc at our point. But. But. t is NOT an angle, and definitely not the angle of our point from the x-axis of the ellipse. Apparently some people still call it the eccentric angle, but my point still stands.

(See here)

And indeed, if we try to make the arc of an ellipse start at a specific angle, we can see that the result is not what we expect, unless the ellipse is a circle (radiusX = radiusY) or startAngle is a multiple of PI / 2.

Here is an interactive demo I've put up so that you can witness the strange default behaviour.

My claim is that the function should always behave like it does in the corrected case with the current specification.

Either that or change the spec to talk about parameters t for startAngle and endAngle, and avoid saying they are angles, because currently they definitely are not.

Does anyone know how this implementation/spec came to be, if anyone reported this before and if not where to lead such a discussion? Any other insight appreciated!

I found this related question but it's rather unsatisfactory as replies merely show how to correct the function, but don't discuss whether the spec or implementation should be corrected.


Solution

  • Yes the specs were wrong here.

    Thanks to your question, I did edit the ellipse method so that it uses the angle from the eccentric circle, as were already doing all the implementations, and I also fixed the MDN article so it talks about "eccentric angle" in both cases.

    As a general rule, when you find a bug in the specs, triple check you're sure about it, then open an issue on the specs's github project (most specs link to their repo at the top of the document, WHATWG specs also have a "File an issue about the selected text" link at the bottom-right corner of the page). But if you're not confident, writing a question on StackOverflow just like you did is also welcome, at least to get a confirmation that you found a bug.