In mathematics and computer science, there is a concept calledÂ local optima. In short, the easiest to achieve solution (local optima) isn’t always the best solution (global optima). A nice metaphor for this concept is theÂ Hill Climbing algorithm.
Imagine that you wake and find yourself in a featureless world. Because of a dense fog, you can only see a few meters in each direction. In your hand is a note.
“Climb to the highest point.”
The ground rises to your right. You head right. It makes sense to you that if you always head in the direction which promises the greatest positive elevation change, you might be heading towards the highest point. After half an hour, the ground levels out. You have reached the destination. Unless…
Had you initially headed left, you might have only lost elevation for a few meters before starting to climb to an even higher peak.
This has been my experience with coding. You need to often go backwards to get further forwards. Or to stick with the metaphor, sometimes you need to head into the valley in order to find a higher peak. A couple weeks ago, I started back down the Java hill. I decided it was time to learn C++.
(note to the highly excitable: This is not a reflection of the merits of Java vs. C++. I get it… they each have their strong suits. Just like Flash has its pros vs. Java and C++).
Now, I am not a crazy person. I wouldn’t just do something like this out the clear blue sky. Anyone who knows me knows that I am generally adverse to change, especially change which is initially damaging to both your ego and your productivity. I couldn’t just copy everything over from Java to C++. I wouldn’t just be launching XCode instead of Eclipse.
This would turn out to be like the time I finally found a classical guitar teacher because I am overly fascinated with learning how to play the Usher Waltz by Koshkin to the point where it is all I have tried to learn for years. The teacher I found said I had developed a bunch of bad habits and would have to stop playing the Koshkin piece for a very long time. Instead, I should practice beginner finger exercises. No way. I showed him my strongest finger and left.
Can I help you with that?
C++ is a scary place. Happily, there was a guide. It’s called (codename) Flint and it is a C++ framework being developed at The Barbarian Group. It is still very much under development and its eventual status (internal or external, open-sourced or not) is unknown. I cherish it for helping to make my transition a bit less thorny. Otherwise, I might have flipped off C++ and gone happily back to Java.
(note:Â OpenFrameworks is another C++ framework which has been used on tons of beautiful projects. It also has the added benefit of actually being available whereas (codename) Flint is still being developed. I highly recommend checking it out.)
But switching to C++ from JavaÂ is still an initial step backwards. I have to learn about pointers and references and headers and operator overloading and much more. I know my limitations enough to know that I should leave the Fuji project on the back burner for a bit. If I were to dive right in and try to port that project right away, I would end up pulling out quite a few angry hairs. So I decided to do my finger exercises.
Most of the work I have done in the last month has involved creating suggested sample applications in the spirit of learning the ropes. Andrew Bell has been giving me assignments. First up, create a globe and map earthquake data onto it.
I had done something similar a while back in Processing but my data was limited to California and Nevada. Now I would be working with 7 days worth of data from all around the world for any earthquakes with a magnitude of 2.5 or higher. It isn’t a huge amount but I would have to find ways to deal with the clusters that are associated with any earthquake data visualization.
Creating the actual globe was great fun. I was pointed towards NASA’s Blue Marble project. There you can download Earth textures at astronomical sizes. Some are available at 86400×43200 pixels. I grabbed a color map and a height map. Using NormalMappr, I created an additional normal map from the height map.
The one drawback of the NASA data is the river systems aren’t as prominent as I would have liked. I ended up adding in the rivers and smaller lakes using this image as a source.
As I mentioned earlier, earthquakes come in clusters. The Dominican Republic had a few dozen 3.0M to 4.0M quakes in that week. If I just stuck pins exactly over the epicenter, all of the Dominican Republic pins would be reduced to a single blurry pin which would not give an accurate summary of the area.
I decided to go back to my old friend Magnetism. In order to keep the quakes grouped but individually distinct, I anchored the pin to the epicenter but allowed the other end to drift a short distance away. This distance would be determined by making each pin-head magnetic so that it pushes away its neighbors’ pin-heads.
It worked well enough so it was time to move on to a new assignment. I will eventually come back to this project because there is plenty more I would like to add such as timelined events and more interesting animations for the actual quake graphics. There are a couple more screenshots later in this post but it makes more sense to move on to the next project.
Next up, learning more about vectors and lists by making a flow field simulation. It would involve 20,000 particles which react to external forces and can be reborn locally if they should happen to stray too far. Into this mess of particles, you can place either an attractive force (gravity) or a repulsive force (orbital). The attractive forces pull every particle towards it based on the laws of gravitation. The repulsive forces spin either clockwise or counterclockwise and any particles nearby would be thrown away from the center of the rotating force.
Below I have added one of each type of force. The gravity is on the left and the orbital is on the right. The orange strands are the motion trail of each particle as they are pulled into the black hole where they are respawned in a random location on screen.
As you continue to add more forces of each variety, more complicated compositions can be formed. Here, there are 13 gravitational forces and 8 orbital forces (4 of each spin direction).
After a while it starts to look like a painting application created by H.R. Giger (but with fewer dead babies and engorged penises… man that guy was weird).
How about combining these last two projects? Sure! Why not! Below you see a couple more images from the Earthquake visualizer but now, each earthquake acts as a gravitational force for a few thousand particles mapped to spherical coordinates. It ends up creating a faux atmosphere and can draw the eyes towards areas of strong seismic activity.
Below, you can see the 7.8M quake that struck New Zealand a couple weeks ago. For scale contrast, the larger sphere near the top of the image is a 6.3M quake.
Andrew had already ported my particle source code over to (codename) Flint but he did a fairly direct translation, keeping all my poor judgement and outdated methods intact. I decided to have a fresh go at it and below you can see the results. It pretty much behaves the same way as before but with a few aesthetic changes. The emitter is a solid bumpmapped sphere which shrinks and spins and eventually starts throwing off sparks. The perlin noise is now a perlin noise derivative. Still on the to-do list, figure out how to do particles directly on the shader. But honestly, not sure if that is at all reasonable. Im guessing its harder than it sounds.
Where is it leading?
Eventually, I will make my way back here. These are the most recent screen grabs from the Fuji project which I had been building in Java. Though this build could run at about 25 frames per second, I feel a switch over to C++ and recoding the whole thing from scratch will most likely lead to a bunch of speed optimizations which will hopefully push it back into the 60 fps range. I know I was taking quite a few shortcuts and now I can begin to address them. Fingers crossed!
The last bits I added before moving over to C++ are swarming birds. I only got as far as creating them and having them fly from tall tree to tall tree. The flocking has not yet been added so it looks a bit haphazard.
I still have quite a long way to go. I plan on tacking a mesh terrain project next. I don’t know if I will do any of the beautiful but difficult terrain mesh optimizations like featured in this article by Shamus Young. I get the concepts entirely but have no idea how to deal with all that irregular data. Grids make sense to me. Adaptive resolution mesh does not.
And there you have it. A huge life change reduced to a single blog post. I will continue to post my new work with (codename) Flint as well as my continued work with Processing/Java. And once details about (codename) Flint become available, you will be able to read about them here.