Search code examples
graphicscanvastransformationprojectionperspective

Curve produced by perspective transformation applied to circular arc


I am trying to produce a drawing of a 3D sphere within a canvas which I would like to render quickly: My target is real-time performance for a small (300px square) canvas on iPad.

Most of the demos out there for HTML5 rendering of any complexity uses WebGL (with the likes of three.js) which is wonderful, but sees limited (none, actually, at the moment, but Apple technically could enable it) support on iOS.

canvas, however, works great.

So I'm taking a harder look at building some rudimentary rendering functionality with canvas since CSS3 gives me HW Transform and canvas can be used for rudimentary texturing. I can fake lighting by drawing to a canvas! Quite a step back, since this isn't even full HW T&L (DX7!...) but I remain convinced that it's possible to build things that are still very cool. The trick is to minimize the amount of geometry as much as possible (among other things).

Back to the topic at hand. My actual question is quite specific. If the sphere I want to draw is far enough away from the camera I can get away with an orthographic projection of it. It seems like in this case I can construct a wireframe-sphere using arc paths and the rotation and scaling transforms available to canvas. This doesn't allow me to texture the sphere in any way, but should produce nice smooth curves and will look nice.

What if I want to throw perspective projection into the picture? What sort of curves are produced from this type of transformation? Is there any possibility of being able to draw a close enough approximating curve using bezier or arc paths?

I know that a perspective projection of a sphere is an ellipse. Ellipses can be produced readily by scaling circles. It may just be as simple as figuring out the equation for that ellipse given the projection parameters. Can somebody help me out with this?

One option that's always open to me is to just forget the arcs and draw my wireframe with lines (which canvas will conveniently antialias for me) the way we have always traditionally done this, and call it a day. There's no way to avoid this either, if I wanted to texture my sphere for example.


Solution

  • Looking for an analytical formulation for this curve (and then attempting to fit this to some kind of bezier) will probably amount to digging a hole deeper and deeper.

    I'm also pretty certain that performance with the built-in curves will be horrific since they are probably helpers which use the line functionality I would use anyway, so I would only be reducing the control I have over rendering and performance.