This isn’t Scala related, but a couple days ago I submitted an entry into the bus-tops contest under the title vectorfield. I’m really pleased with the result. It’s interesting how limitations lead you to new places. The 8 framerate limit actually inspired me to put in way more dots than I originally intended, which then led to profiling + optimizing iterations.
A while back, Hackers at Berkeley hosted a small session on Artifical Intelligence, introducing (among other things) the Markov Chain. I decided to implement my own for random word/name generation, using single letters as states and training on about 22k English words (wlist_match10 at http://www.keithv.com/software/wlist/). This gave me some decent results:
And some less decent results:
I also wanted to visualize these connections in a way that quickly portrayed information, so I took my old friend the Particle System and connected all the letters up according to how high the probabilities were.
It’s a bit messy, but you can see several interesting features of the English language. The most striking thing was that the most common vowels (a,e,o) always float towards the center of the system. You can shake up the mass but the sheer number of relatively balanced connections makes the vowels only stable near the center.
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).
Here is one of many ways to achieve awesome:
- Take any image
- Map regions of the image into ASCII characters of equal dimension
- Make sure your font metrics are equivalent to those of Facebook’s
It is quite difficult to turn this sketch into an applet since I was using the webcam, but you can see the source code here. Originally I tried matching the font of Processing to be the same as that of Facebook but there’s too many CSS subtleties; in the end I had to write some JS to manually get the char-width of each character. Unfortunately the image starts skewing depending on your browser zoom and whether you have certain fonts installed or not, but there’s nothing to be done about such things.
A while back I was struck by inspiration from an applet that was shown in my EE20 lecture about phasors. I went about writing my own version of this applet, but combined with the expression parsing powers of Scala. I decided to try some Appletception, putting no less than four PApplets contained within a normal Applet class. This was both a boon and a… uh…. unboon? anti-boon? noob? HA. Let me tell you why: (P.S. I’m also trying this bold important phrases thing that was semi-mostly-completely inspired by coding horror’s blogging style.)
Good things about embedding PApplets
- Different parts of code live in different methods; the concepts in my mind are reflected accurately in the hierarchy. Instead of having a huge setup/draw method that would do four things at once, I instead have four classes each doing one thing at a time. This keeps the code closer to our mental model, which is what we want.
- Swing’s windowed, focusable event system can be fully taken advantage of! I don’t have to worry about what “region” the mouse is in, or which applet should respond to my key-presses/mouse wheel scrolls, because swing does it for me.
- The positioning of the applets is determined by the layout manager; so I don’t have to. Again, swing does it for me.
- It’ll be simple to extend this sketch to include other swing-y things like easy resizing, or adding a border (which was implemented, to wonderful effect, in four lines).
- It’s multithreaded, so one PApplet may go really slowly (say 5 fps) but the other one will still be at 60 fps. This isn’t necessarily a good thing depending on how you look at it.
Bad things about embedding PApplets
- Multithreading bites you in the ass. Each PApplet starts its own thread, and only that thread will run the draw() method correctly, and there’s nothing you can do about it. I was able to keep my issues to a minimum by having only one method that might be called concurrently, and then just synchronizing that method. But it could easily get messy.
- Because they’re not all synchronized, the frames won’t line up. If you drag the Argand diagram quickly, you’ll notice that the plots for the Real and Imaginary parts get very blocky and very NOT function-y. This is because they depend on the state of the camera in the Argand diagram, which changes as they’re asking about it. The fundamental problem is that the rendering of the Real and Imaginary parts is much, much slower than the rendering of the Argand diagram, so one frame in one applet is actually 5-10 frames in the other.
- You have to connect the wires together. I forgot to override and delegate the start, stop, and destroy methods from my outer Applet to all my inner PApplets so my applet would freeze every time I refreshed the page. This isn’t too much overhead but can still bite you.
I wanted to finish this sketch for several weeks but silly, silly things like homework and midterms kept getting in the way, and I really wanted to polish this one up a little bit and make it usable. In particular, I re-wrote my parser library to return an Expr class instead of just a float (this effectively caches the parsed structure), resulting in speedups of ~600x. Drastic but not unexpected, considering the massive, complex machinery that parser combinators are.
I also finally figured out how to use pack200 compression; the resulting applet is down from 472kb to just 102kb, smaller than normal Java Processing applets. Amazing what Proguard + pack200 can do.