This past week I took a job offer to do a quick applet for Fabripod. Fabripod wants to sell lamps, and they want to let people customize them to their liking – in particular, they wanted an online interface (aka an Applet) to let people control various parameters, and immediately see the resulting figure. Like this:
You basically partition the sphere into a set of quads (which are actually trapezoids), and then draw shapes projecting out from each normal. It’s much easier to act as if every quad has its own coordinate system and then transform the shape accordingly. It’s also quite amazing how fast one can develop with the right tools; this first sketch took less than a day to mock up.
Added a few more options and some indicators; by associating each indicator with a function that will calculate its value, it’s easy to simulate the displayed text as a def instead of a var.
This is basically the final version; it’s amazing what some good lights can do to a sketch. About halfway through this picture and the previous one I had to do a lot of code rewriting in order to cache; this involved changing most of my defs into vars and then doing “mutate on UI change” acrobatics. Pleasantly, the sketch runs at ~40 fps for almost all use cases (using software 3D rendering, since exporting an Applet using OPENGL is difficult).
My previous explorations really taught me that I had absolutely NO CLUE how to spherical geometry, so I’ve spent these past weeks teaching myself how to get around in spherical coordinates. I’ve come up with a potpourri of sketches exploring spherical geometry. These are mostly for my own benefit, but I thought I’d share anyways.
This sketch does the simplest things, like drawing great circles and small circles. It was a very good primer to start thinking in a spherical mindset. The strategy at this point was to always imagine important vectors being aligned along the XYZ axes, and which reduced the problem down to a much simpler one, and then implementing the solution through rotation transformations.
I wondered what kind of path a point on the sphere would take if it was constantly rotating around some moving axis. To this end, Rodrigues’ rotation formula proves extremely helpful.
Going back to my roots – gravitation! The red ball is gravitationally attracted to the green balls using a spherical distance metric. This was actually tricky because velocities aren’t as straightforward as they are in Euclidean space. I ended up creating the notion of a “Local Plane”, which is basically an azimuthal projection of the sphere centered at the red ball. This lets you do vector math as if you were in a simple 2D space, so it’s very easy to add forces and integrate for velocity.
I’ve been getting the feeling that my random planet generator isn’t finished yet. I’d really have liked to polish it up and make it look really nice, so a couple days ago I set out to fix the most daunting thing, the aliasing near the poles. The issue is basically that some points are too close together while others are too far apart. While this problem isn’t easy to solve mathematically, you can get pretty close by making each point act as a repeller, and then constraining all of them to move along a sphere:
An initial set of 100 random points after it’s settled into stability. It’s pretty even, but the points don’t have the regularity that I’d like them to.
The rectangular projection after it has been repelling for a short while; you can still clearly see the sampled lines. This is already significantly better than before, partly because of the repelling but also partly because I created proper nodes for the two poles. What’s interesting is that if you KEEP letting this run, pretty soon the symmetry of the lines gets broken and a pattern similar to the random points appears.
This one starts with a surface refinement described in http://paulbourke.net/miscellaneous/sphere_cylinder/. You start with an octahedron and then turn each face into four faces by bisecting the edges of the faces and creating new triangles out of the resulting shapes… the URL describes it much better :P This has good spread and regularity, and also has the added bonus of already having calculated the edges that each node is next to (so I don’t have to triangulate it to get a mesh).