Rotating 3D SVG Cube

Since getting my head around how 3D graphics work (to a degree at least), I thought I'd apply what I know to my favourite format: SVG. Below is an SVG displaying a sqaure, but if you click on the arrows, the shape changes, giving the appearance of a cube rotating about either the x- or y-axis.

The SVG works by storing the x-, y- and z-coordinates of a cube in three separate arrays. When the arrows are pressed, these values are transformed, and the x and y positions of the twelve lines that make up the edges of the cube are updated. The code for the transformation is almost identical to that in my Python program -- there is even a Math.atan2() function. To see the code in more detail, either right click on the SVG and choose View Frame Source, or click on the link at the bottom of this post.

Another feature of this SVG which I'm pleased about is the fact that the functions are repeated called if the mouse is held down on the buttons. I've described how to do this here.

I made this SVG pretty quickly and I think it's pretty inefficient. There's quite a lot more I could do if I get some time:

  • Use matrix transformations. I'm not sure if ECMAScript can multiply matrices natively, but it should be easy enough to write a function for it. This should make the code a bit more efficient and save having separate functions for rotating about the different axes.
  • Make a more complex shape. I already have a Python .obj reader and it should be quite easy to make this output SVG files. Then I could view more complex shapes created in other programs.
  • Shade the surfaces. I have a Python program that does this reasonably well, so I could try to adapt the code for this. It would be interesting to see how fast the program can run.
  • Add more transformations. I could add rotation about the z-axis, zooming and translations. I could try to make an entire 3D game, but I think that would be going too far.

 

AttachmentSize
3D_cube.svg4.77 KB

Topics:

Comments

Hey Peter! Incredible Website! Congratulations!

Thank you so much for this awesome template. I can't wait to see how this will handle .obj data, I don't care it's just wireframe, simple things are the best ones :) It would be awesome if we can just copy and paste .obj vertices and faces and see it "rendered" as .svg.

This is very old, but maybe his matrix is still usefull for you?

http://www.kevlindev.com/geometry/3D/js3d/cube.svg

This is another example I like pretty much, but canvas doesn't handle zoom beautifully like .svg ;)

http://www.canvasdemos.com/userdemos/toxicgonzo/3dobjviewer.html

And my "clean" version of it: 

http://primotico.webs.com/html5/html5.html

Yours,

Ortiz

 

Nice cube!

Thanks for this. It was quite useful in developing some some roatating 3D charts using SVG.

A couple of notes:

1)I found it more precise to always rotate from an intial set of array values rather than incrementing the array values because the values gradually lose precision and you can't back-up to the precise original position. So I keep track of the rotation angle, and move the objects from an initial position based on that angle. Yes, it requires more computations, but there is no difference to the user.

2) If you hold a button down on your cube it eventually reverses the rotation direction. 

Thanks again for publishing this.

This took me back to the bbs days and the "Denthor of Asphyxia" tutorials... which I can still find, unbelievable...

http://archive.gamedev.net/archive/reference/listed82.html?categoryid=130

Anyway, in case you're interested, I took you're SVG and started playing with it.

I now have all the platonic solids being controlled as well.

I turned them into objects, so that all you need to do is "new" it, and then add some points and faces.:

var cube = new Obj("cube");

cube.addPoint([x,y,z]);

cube.createFace([p1,p2,p3,...]); 

Then call .draw() on each object when you want to update it on screen.

It hides the faces that shouldn't be shown, and creates the SVG objects dynamically.  Also does Z ordering and scaling as well :)

Let me know if you want a copy, I'll send it to ya.

Post new comment

The content of this field is kept private and will not be shown publicly.