Brandy Glass
This is a little throwback to my student days. One of the projects we were assigned for our 4th-year Graphics and Dynamic Control course (with Dr. Mike Scott) was to animate a wireframe 3D model of "something". My friend and project-partner Brian Boyle and I decided to do a brandy glass, much like the one shown here. It is a project I really enjoyed doing at the time (Brian and I went all-out do do a good job on this one), which is why I wanted to recreate it here.
The animation you see here is written in HTML5/Javascript, while the original was written in C. The project is considerably easier to do now than it was the first time around in a number of respects:
- I have vastly more CPU horse-power available to me now. When Brian and I wrote the original, we put a fair bit of effort into making sure that we only used integer arithemtic for the calculations: CPUs of the day didn't have any native floating-point capability so any floating-point calculations would be done (slowly !) in software. We avoided any floating-point calculations in the main loop.
- Rotating the object involves some matrix multiplications. Not a big deal, really, but we had to write the code for doing the matrix multiplications ourselves. Because we were only using integers on 16-bit computers, we also had to be careful to avoid overflow errors (I remember that being a hassle for us). I didn't bother with that here: I just imported the handy math.js library and used that.
- On the PCs of the time, if you wanted your animations to be smooth, you had to either do your screen updates during the CRT's flyback interval or - if your graphics hardware had the capability - you would draw to an off-screen buffer and then page-flip the off-screen buffer onto the screen (again, I think you had to time the page-flip to happen during the flyback interval). I can't remember for sure (Brian - if you ever read this and you can remember, you might let me know !), but I think we did it the page-flip way. There's none of that here: for each screen update, I am clearing the previous picture and drawing the updated one directly onto the screen.
There is a little bit about the maths involved in doing the 3D transformations at https://www.tutorialspoint.com/computer_graphics/3d_transformation.htm. Also worth a look is the brilliant 3Blue1Brown video series on Linear Algebra that kicks off at https://www.youtube.com/watch?v=kjBOesZCoqc.
One aspect of the original project that I haven't (yet) reproduced here was that the motion of the glass was "realistic", in response to forces applied to it. This involved using the Runge-Kutta method for calculating the motion of the object. The one here just spins at fixed rates around all three axes.
Ofcourse, this isn't at all how you would do something like this now. All of the heavy lifting here is done by the main CPU. Any modern computer (or phone, for that matter) has hardware-accelerated graphics that can do the computations and rendering vastly quicker and more efficiently than is possible using the general-purpose CPU. The right way to do this here would be to use WebGL which is a Javascript API to OpenGL. That's an exercise for a later date. When I do it, I'll probably use three.js to hide some of the complexity of WebGL.