Sunday, March 20, 2011

Contour Plot with Perlin Noise (Android)

SUCCESS!... alright I finally got it working, a mechanism for generating random "terrain" using Perlin Noise as well as a mechanism for plotting contours... here's a look:

Generated Contour map from 400x400 Perlin Noise Matrix Took 484ms

...Generally speaking I wouldn't be too happy saying anything takes 1/2 second (484ms) on my desktop, but this is not a normal case... usually you will not have an exact 1-to-1 correspondence between your contour map and the data (image) and normally you'll get a much smaller matrix/list of elevations/list of points... (say 80x80) and you'll need a contour map for this... heres a look (the generated bitmap is in the top left)

...for this scenario the generation of the 80x80 matrix took 16 ms. (I could make this look "better" if, instead of painting pixels that are 1x1, I'd paint pixels that are 5x5.... I generated another image and upped the tile size:

...this took about 31 milliseconds to generate the contour for it.

You might argue that the image above is rather smooth in comparison, so I fooled around with the Perlin noise "turbulence" and generated the following image (using 4x4 tiles, 100x100 Perlin noise generated matrix to generate a 400x400 contour map image)
..this took 41 milliseconds... acceptable.

So a few things had to come together to make this happen.  First, I had to adapt the W.V Snyder Conrec routine to work in a "non-Java-applet" mode...second I had to fiddle with the implementions of Perlin Noise to find out which one had the best fit.  Anyways I'm not "there" yet (currently it's running in a Java JFrame and I'm using an in memory BufferedImage), but I built all the AWT specific stuff in an abstraction so I'm nearly there.  Anyways originally I was going to use some processing based "blobification" tools but those were slow didnt scale (beyond 256x256 matrix for my Desktop... ewww) and did alot of "new"'s which kill Android.

Anyways it's nice to have a generic configurable contour plotting mechanism for Java/android anyways,( I can configure the number of contour lines/etc.) but also this can be used for image manipulation (instead of "feeding" it Perlin noise, feed it an image and it will contour plot the images based on HSB (Hue Saturation Brightness) Or this can be used by feeding it in actual elevations (I think from USGS) and it can develop a map like the one above from this data...    Big thing is... it's Fast, and it'll run on Android (even though I havent tested it yet)

So I'm gonna try and figure out a way to make the contours a little less jaggy (at the moment these circular looking contours are actually the result of a bunch of individual drawLines, so I might see some optimizations using breziers and drawPoly, gotta check on that though)

FWIW a 2000x2000 matrix with 4,000,0000 unique elevations took 17,735 msec to contour  (and I still didn't run out of memory... the blobDetector I was using prior, choked on images much larger than 256x256)

Well I need a beer, will work on it tommorrow, gotta celebrate the little victories!

1 comment:

  1. Hi!
    Is it possible to get the sources of this stuff? Looks nice!