One of my childhood jobs was for an engineering company. This was back in the days before Matlab or Mathematica. I would write software for this company (interestingly the company failed and was reincarnated as FlexPipe in 2001, the owners being the previous engineers), to compute numerical integrals to predict the pressure it should take to make their pipe explode, in various configurations. Eventually I used the Persistence of Vision raytracer to create slick graphics depicting the internal structure of their pipe, to help sell the product to potential investors.
Raytracing was extremely time consuming in the 1990's so I developed a fairly efficient pipeline for generating the graphics. One that I've been using ever since. Below is an image created by this pipeline, about 5 years ago. My pipeline primarily involved writing a Pascal (eventually C++) script to generate (part of) the script for Persistence of Vision. I would then run Persistence of Vision, sometimes for a few days, to generate the final image.
The main advantage of using Pascal and C++ to generate the data is it allowed me to be highly prescriptive on the geometric objects used -- allowing for the computation of the precise location of the circles in the above picture, as these are circles that the intersect the knot in precisely five points. The primary disadvantage is writing the Pascal or C++ program is the relatively slow compilation process and transition to a final rendered object. I've been sitting on the fence for years wondering if I should use an interactive modelling environment like AutoCad or Rhino.
I believe I've stumbled across a potential shortcut that will help me avoid that.
Python is a popular high-level programming language that has a large variety of increasingly sophisticated libraries available. VisPy is a library that utilizes OpenGL to interface with a computers GPU. In short, this allows for the rapid production of software to create rapidly-rendered graphics. So rapid, in many cases, that interactive graphics are possible.
It would be nice if it was that straightforward. I've been coding in Python to see how possible all this is. Using a high-level language like Python comes with a price. So I've set myself a set of exercises to see if I can code "the way I'd like to" in a high-level way, and get Python to do what I like. This is the first in a series of posts where I hope to convince myself that I can.
The first obstacle I've encountered is the sympy library. This is Python's primary library for manipulating formal mathematical expressions, such as functions, roots, special numbers such as π, etc. It is ultimately an object that stores mathematical constructions in a tree. So if you have a complicated mathematical expression and wish to evaluate it, sympy will parse through that tree (a structure based on pointers) and slowly assemble the required binary operations, perhaps using automatic casts and such to decide what you really want the library to do in the process. For a decent-sized formula (like say the boundary of a tubular neighbourhood of a torus knot in R3) this can easily be tens of thousands of times slower than coding it up in C++. If this was the end of the story, I would discard Python right here. Luckily sympy has libraries that allow one to speed this process up.
Here is my first coding example, using vispy to generate an interactive visualization of a (p,q)-torus knot. In future posts I hope to make the graphics increasingly interactive, using more features of the vispy library.
The code is broken into four blocks.
One other thing to note, I am running this code in an iPython / Jupyter notebook. This provides a web-browser based environment for editing and running Python code. I've been teaching a course recently using this environment and have found it quite pleasant. I will put the code in a comment below.
And here is a screenshot of the output.
In my next post I will explore the VisPy canvas a little further, and hopefully bring further layers of interactivity into this program.