Archive for the ‘Projects’ Category
Monday, June 21st, 2010
After putting ioLib out there a month or so back, I wanted to get back into the early experimental days of my Processing discovery for a while and create some purely visual sketches that were just simple generated visuals. With ioLib added to the mix of course, so I could manipulate and save out variations as I saw fit.
There are two I’ve been playing with in particular. All images below are saved at wallpaper-friendly 2500×2500, in case you have a mad urge to use them for anything. (I’ve been considering creating a new Flickr account to dump the high-res output of various sketches to make sharing this stuff easier, but I’m still not convinced I need to pay another $25 for another pro account to make that happen.)
The first, ShapeDistortion, takes a basic grid of primitive polygons and adds distortion, roundedness via
curveVertex, and combines them with my typical generated palette secret sauce. As a bonus I built in some high-res texture support, though I only got as far as applying it to the background of the scene rather than on a shape-by-shape basis.
The second one, PaletteRays, shows the benefit of having controllable variables within a sketch. Using Perlin Noise and rotating around a central axis, the sketch plots thousands of semi-transparent circles that fade from one colour to the next, creating a fairly uniform blob effect. These are all from a single starting point and the different views are simply tweaked conditions while the sketch is running. It shows amazing amount of variety within the same basic framework; the focal blur effect is particularly surprising.
Now these pieces are in place, I suspect the next step will be tying in some external data sources and do something a little more interesting than straight up visual effects.
Sunday, May 2nd, 2010
It’s been more an issue of time restraints than lack of motivation that has kept me away from this blog over the past few months. Side projects here, trip around the world there, etc. etc.
To get back into my Processing exploration, I decided to formalize some of my most commonly-used functions into a single staring-point library/framework that I could build new sketches off of. Called ioLib, I’ve pushed it up to my ongoing gitHub repository of various sketches for anyone’s use. It’s not documented all that well, and as far as frameworks go I’d imagine there’s still a lot of work to be done toward making it self-contained, so I doubt it’ll be broadly applicable to people other than me. Maybe over time it’ll grow into something a bit more formal.
I tried to focus on some basic interactivity and output functions, stuff I find myself using over and over again. Straight from the README, this is what’s in it so far:
Bitmap and Vector Output
- pressing ‘s’ saves a screencap as PNG
- pressing ‘p’ saves a screencap as PDF
- 3D mode is a bit quirky; the raw triangles are saved, even for 2D shapes. The background colour doesn’t save either.
2D / 3D Toggle
So far everything works with both 2D and 3D renderers, switching is a simple matter of adjusting the sceneDimensions variable in the user-configurable settings.
Palette Generation from Random Images
Any images (PNG, JPG or GIF) dropped into data/paletteSource will be used as input for the random palette generation function. The paletteCount variable in the user-configurable settings controls how large the palette will be.
Mouse and Keyboard Interaction
- click and drag the mouse to rotate in 2D / 3D space
- pressing ‘+’ zooms in, ‘-’ zooms out
- arrow keys move the scene around
- holding Shift increases the offset 10x
- holding Ctrl increases the offset 100x
- holding Ctrl + Shift increases the offset 1000x
- pressing ‘c’ saves the palette
- pressing ‘r’ resets the palette
Thursday, November 19th, 2009
A geography issue I’ve been struggling with over the past little while is correcting my assumptions about how latitude / longitude coordinates work. When I originally built Elevation I decided to take a shortcut and ignore Earth curvature, treating my GPS points as a Cartesian grid.
And it worked, sort of. It gave me land forms that come close to representing the actual terrain. In hindsight it’s pretty obvious how distorted they were, but for the first few iterations of the program they were good enough.
I’ve now started looking into representing paths with more accuracy. At the moment Elevation’s speed scale is totally relative to the data, but I’d like to peg actual km/h values to it. I’d also like to indicate the scale of the map with sliding meter/kilometer markers that adjust based on zoom level. As I started going down this road I quickly realized the math needed a closer look.
Mercator is probably the most familiar projection out there, and it’s the same one Google, Yahoo, Microsoft etc. use for their online mapping services. While it seriously distorts extreme high and low latitudes (Greenland isn’t really the same size as Africa, after all), it has the advantage of treating smaller local areas more uniformly. Mercator won’t work at the North Pole or in the Antarctic, but at a regional level like city or state/province it’s a fairly uniform distortion so the maps just look right; since Elevation is intended for those smaller areas, that’s perfect for my needs.
So, how does one go about converting GPS lat/long coordinates to actual meters? That’s where the math comes in, and Wikipedia handily lists a few formulas for it. Processing doesn’t have
sec functions, so only the first two functions for
y will work; I chose the second:
x = λ - λo y = 0.5 * ln * ((1 + sin(φ)) / (1 - sin(φ)))
x value basically ends up being your raw longitude coordinate, though it’s handy to offset it from the central
x axis of your map. The
y value requires a bit more heavy lifting. In Processing, the above functions end up looking something like this:
float lambda = gpsLong - (mapWidth / 2); float phi = radians(gpsLat); float adjustedPhi = degrees(0.5 * log((1 + sin(phi)) / (1 - sin(phi))));
While Wikipedia doesn’t explicitly say anything about radians, I found it necessary to convert
y before the math would work in Processing, then convert the result back to degrees.
The resulting values still don’t represent real units on the surface of the globe; to get that you have to multiply each by the degree length, a variable value that corresponds to the surface distance between a single degree change in latitude. At the equator there are approximately 111km between degrees, but this number shrinks the closer you get to the poles.
Solving this problem is something I’m currently working on. An unfortunate red herring was that the degree length in Vancouver appears to be almost exactly 1.6 times less than the value at the equator, which looked for all the world like a flubbed imperial/metric conversion. If I were to start with the equator distance and divide by 1.6:
x = (adjustedPhi * 111319.9) / 1.6; y =(lambda * 111319.9) / 1.6;
I would get values that look fairly darn close to accurate in Vancouver. I thought that had solved it, but I now suspect the math at different latitudes is still very much wrong. I’ll update this post once I know more.
Thanks Microsoft, for publishing this piece on MSDN about how your Bing Maps tile system works. This bit in particular seems like it contains what I’m looking for:
The ground resolution indicates the distance on the ground that’s represented by a single pixel in the map. For example, at a ground resolution of 10 meters/pixel, each pixel represents a ground distance of 10 meters. The ground resolution varies depending on the level of detail and the latitude at which it’s measured. Using an earth radius of 6378137 meters, the ground resolution (in meters per pixel) can be calculated as:
ground resolution = cos(latitude * pi/180) * earth circumference / map width = (cos(latitude * pi/180) * 2 * pi * 6378137 meters) / (256 * 2^level pixels)
The map scale indicates the ratio between map distance and ground distance, when measured in the same units. For instance, at a map scale of 1 : 100,000, each inch on the map represents a ground distance of 100,000 inches. Like the ground resolution, the map scale varies with the level of detail and the latitude of measurement. It can be calculated from the ground resolution as follows, given the screen resolution in dots per inch, typically 96 dpi:
map scale = 1 : ground resolution * screen dpi / 0.0254 meters/inch = 1 : (cos(latitude * pi/180) * 2 * pi * 6378137 * screen dpi) / (256 * 2^level * 0.0254)
Monday, October 12th, 2009
As hinted in the comments in my last post, I’ve cleaned up my 3D elevation code and released it as a project, source and all. Go check out Elevation to grab Mac and Windows executables, or hit up GitHub to grab the source.
This project was a too-perfect alignment of things relevant to my interests. I got a chance to really stretch my legs with Processing, had an excuse to tinker with GitHub finally, spent some serious design time in Photoshop thinking through the site and app UI visuals, designed a high-res app icon, got to play with mapping and GPS software, and it all gave me the motivation to go out and pedal around this beautiful city to create my route data in the first place. Spending a month coding while racking up over 400km on the bike seems like a fairly healthy work/play balance.
And happily there’s plenty of fodder in here for future posts, from parsing differing XML formats to building a functional GUI. More on those soon.