3D graphics in a 2D context (for dummies)
April 17, 2012 5:39 PM   Subscribe

HTML5 canvas question: I'm trying to model a 2D grid in 3D space and it's not working right. Can you help?

Please take a look at this page I made and uploaded to Pastebin (the source is in there, you can save it locally to view it; it contains two embedded images).

I started with this cool demo from Koen Hendrix, which renders sprites at certain points in 3D space. I added the ability to draw a line between any two points, and built a grid.

You can use the right/left arrow keys to rotate the model, which pivots around the blue dot. It works fine until you rotate past a certain spot, then the positions of some of the off-camera points start to skew. If you keep rotating they'll pull farther apart before snapping back into the proper positions.

I have never worked at the code level with a 3D graphical engine like this before... I'm learning a lot but I just can't wrap my head around what's going wrong here. I'm pretty rusty with my geometry and trigonometry. Can anybody more experienced please explain to me why the grid renders just fine from certain angles but not from others, and help me fix it?
posted by The Winsome Parker Lewis to Computers & Internet (10 answers total) 2 users marked this as a favorite
It seems to happen whenever one endpoint of a grid line goes too far behind the viewer. If you zoom out, it stops happening. Looking at the javascript, is yPlaneProjection() doing the right thing? It seems like it'll have odd results if one or the other of ry and rya is behind the viewpoint.
posted by hattifattener at 7:38 PM on April 17, 2012

Or, hey, maybe it's just that the usual perspective transform wraps around for points behind the viewer. A straight line from a point in front of you to a point in back of you won't be remotely straight once it's perspective-projected, so just drawing a straight line between its endpoints will produce unexpected effects.
posted by hattifattener at 7:44 PM on April 17, 2012

Have you considered using three.js?
posted by Rhomboid at 7:55 PM on April 17, 2012

Thanks for taking a look at it, hattifattener. I think you're on the right track. yPlaneProjection() is a modified version of the one written by Koen Hendrix, which I changed to allow for coordinate pairs representing lines. Honestly, this is where the math goes over my head. I'm not sure if the problem is in the Hendrix original (which just wasn't built with this in mind) or an error I made when changing it. I'm hoping to identify the problem and fix it.

Rhomboid: Yes, three.js is pretty cool looking. But I'm doing this as an educational exercise; I'm trying to understand how this sort of thing works under the hood and I've never worked with it before. My head spins when I try to figure out what sin/cos/tan transformations go where, and I haven't looked at a unit circle in many years. I'm trying to get into this stuff but got about as far as I could on my own steam and turned to AskMe for help. :-)
posted by The Winsome Parker Lewis at 8:36 PM on April 17, 2012

I just realized I probably should've said this outright... but if you know of a good crash-course tutorial in the basic math behind manipulating/rendering 3D points and lines, I'd love to see it. That'd really be more useful in the long run than somebody just swooping in and fixing my code anyway.
posted by The Winsome Parker Lewis at 8:45 PM on April 17, 2012

There was a post on /r/programming not long ago with a good introduction to the math behind 3D transformations.

(time passes)

This looks like it, although it's not quite how I remember.
posted by Rhomboid at 9:39 PM on April 17, 2012

I’m guessing that those specific points end up behind the camera, where their x, y positions in the canvas might are undefined in the context of your view.

Gerald & Pokorny’s Computer Graphics (1988) is a great resource for this that might help you get your sins and cosines straight. One concept explained in the book is the idea of near- and far-plane clipping, which would snip off the ends of those lines instead of trying to project them behind the viewer.

I’m also not seeing a lot of matrix abstractions in your code; the 4x4 homogenous matrix is a foundational concept of 3D graphics.
posted by migurski at 10:32 PM on April 17, 2012

*might be.
posted by migurski at 10:32 PM on April 17, 2012

Thanks for the help! I'd still love if someone could help with the specific problem in this code, but in the meantime I'll be poring over Rhomboid's and migurski's info, which looks extremely useful.
posted by The Winsome Parker Lewis at 11:10 AM on April 18, 2012

Do check whether your z values end up behind the camera, I have a feeling that's the problem. Good luck!
posted by migurski at 1:37 PM on April 18, 2012

« Older Recipes for leftovers, Passover edition   |   I need the perfect A.A. Mile quote to read at my... Newer »
This thread is closed to new comments.