Here’s some huge wallpapers made of math

I don’t feel like writing a big post explaining all of it, so the summary is that I spent a few hours playing with colorspaces, Hilbert curves, and image generation, and produced some stuff that looks kind of neat.  I’ve posted everything in one big wad, and you’re welcome to poke at this ugly undocumented code if you like. I also posted prior Python art scraps.

All the images in this post are shrunken down — the full size loss-less PNGs are on the github with the code. This is the kind of thing it kicks out:

colors-64-rgb-0000

Basically, I walk a 3D color space via a 3D Hilbert curve, mapping it to a 1D scalar. I then walk that 1D scalar on a 2D Hilbert curve, rendering each color in place in an image. Here’s an example of a 1D sequence of colors walked:

strip-rgb-small

From there, I fiddled with the various outputs in Paint.NET to make pretty pictures, e.g.:
denty-rainbow-small(Original here) I was able to render the above one at a ridiculous resolution (8192×4608), so it looks awesome spanning four monitors.

Others:

hashed1-small

(Original here)

squares1-small

(Original here)

Check out the github dump for more.

Cache up internet radio for later *skippable* playback

If there’s an internet radio station you like, you might want to listen to it on the move, even when you don’t have internet.  It’s fairly trivial to slurp the MP3 stream with a tool like wget, but then you end up with a 4GB single file.  It’ll play fine, but when a crappy song comes on, it would be nice to skip ahead without having to hold down the “forward” button for a while. Worse, many MP3 players don’t keep track of position in a song, so when you start back up, you’ll be at the start of the stream again.

What I do is slurp the MP3 stream, but divide it into fixed chunks, like 5MB.  You can tell how much runtime per chunk based on the bitrate.  A 128kbps stream means there are 128*1024 bits per second, or about 0.983 megabytes/minute.  So 5MB is roughly 5 minutes.

This means I have a directory with a few hundred MP3 files to be played in sequence.  If you have gapless playback, you don’t even notice the track changes. If you’re listening to a lousy song, you can skip 5 minutes into the future just by pressing next track.  Even lousy MP3 players keep track of which song you were on, so your radio picks up where it left off, and even if you lose your place, it’s easier to find your way back, since you can just skip five minutes at a time until you start hearing new content.

To do this chunk download approach, I use this old perl script I wrote a few years ago. It’s a little ugly…if I were to write it today, it would probably be 10 lines of Python, but it works well enough, even on Windows (provided you have perl and wget).

#!/usr/bin/perl

use strict;

if (!@ARGV) {
	die < [basename] [size]
EOL
}

my $url = $ARGV[0];
my $basename = $ARGV[1] || "save";
my $chunksize = $ARGV[2] || 5*1024*1024;
my $blocksize = 4096;

my $chunkleft = $chunksize;

open STREAM, "wget -O- $url |" or die;
my $n=1;
while (1) {
	my $buf;
	my $filename = sprintf("%s-%03d.mp3",$basename,$n);
	open OUT, ">$filename" or die "$filename: $!\n";
	while ($chunkleft > 0) {
		my $r = read(STREAM, $buf, $blocksize);
		if ($r == 0) { die "EOF, exiting.\n"; } 
		elsif ($r<0) { die "stream: $!\n"; }

		$chunkleft -= $r;
		print OUT $buf;
	}
	close OUT;
	$chunkleft = $chunksize;
	print "\nFinished writing $filename.\n";

	$n++;
}

Hilbert curves are cool

Hilbert curves are cool.  They’re a form of fractal comprised entirely of 90 degree angles. It’s a way to make a single continuous line fill up any given space (2D, 3D, and beyond).

hilbert1

The background to this blog is a hilbert curve I rendered myself (code).  Above is a simpler version of the curve, blown up so you can see it, with the color of the line changing so you can see how it flows.

It has a some cool properties.  For example, if you subdivide the image width-wise and height-wise by a power of two, you get squares that also contain one contiguous part of the line.  It turns out this is important in computer simulations.  Because of how CPU caching works, it’s faster to read a bunch of bytes next to each other than ones far apart. So if you’re simulating weather patterns or particle physics or whatever, you have to map memory (which is one-dimensional) to 2D or 3D space.  If you use a hilbert curve to do that mapping, then when you divide the space up to work on it, each little square or block will live on a continuous piece of memory, and your program will run much faster.

Also, I just think they look cool.  I played with a few filters and came up with some cool images of the 2D hilbert curve:

hilbert-10-lavender-sin729x hilbert-10-rainbowedges-sin81x hilbert-10-rainbowedges-sin81x-quadmirror-rot45 hilbert-10-ice-sin81x hilbert-10-ice-sin9x hilbert-10-ice-sawtooth hilbert-10-fire-sin81x

Also, they work in 3D too.  I wanted to see this, so I wrote a program to build a 3D hilbert curve in Minecraft:

2011-01-17_22.34.05 2011-01-17_22.31.40 2011-01-17_22.31.332

The code to render these is here.  This code is two years old (Jan 2011), and it’s based on the pymclevel Python module, which may be dead or different by now.  Also, it outputs schematic files, which was a format you fed to a Minecraft map editor to plop the object into an existing world.

I also rendered another cool fractal, the Menger sponge:

2011-01-17_17.58.03 2011-01-17_17.58.30 2011-01-17_17.58.48 2011-01-17_17.59.40

Code to generate that is here.

How to hack the Sandbox game

The Sandbox” is a powder game recently ported to Android. It’s fun, but they try to get you to buy “mana” to unlock stuff that you need to use in the normal course of the game. Nope, not gonna do that.

We can hack the Android version to drop the price of elements to near-free.

To do this:

  1. Get the Sandbox APK by backing up the installed game (ES File Manager’s App Manager can do this)
  2. Transfer APK to PC
  3. Extract it as a ZIP file
  4. Edit assets/shop.plist to drop prices to 3 mana for each element
  5. Rezip the files
  6. Use the “testsign.jar” tool to sign the ZIP, thus making it an installable APK:

    java -jar testsign.jar hacked.zip ready-to-install.apk
  7. Uninstall the non-hacked game from your device
  8. Copy the hacked APK to your device
  9. Install the hacked APK.

All the elements should now cost just 3 mana, so head to the element store and unlock them all.

Getting around stability/sound issues

On my Nexus 7, the hacked version of the game didn’t have sound for some reason and I saw a few glitches.

To fix this, I just:

  1. unlocked all the elements,
  2. backed up the profile data (/sdcard/Android/data/com.pixowl.thesandbox.android),
  3. uninstalled the hacked APK,
  4. installed the normal APK, and
  5. restored the profile data.

After re-launching the game, the unlocked profile remains with sound restored.

Methods which didn’t work

There is a guide to hack the iPhone version by editing rewards.plist, a file which exists in the Android version too, but making the change suggested in that guide had no effect, which is why I hit the shop.plist instead. Perhaps they left that file as a red herring?

Also, you may be tempted to try to edit the player profile.dat directly to change your mana, and you can find the binary number to do it (offset 0x94), but the file is hashed with a 160-bit hash (probably SHA-1), and the hash is salted or something, because I couldn’t figure out how to re-sign it.