import java.awt.Color; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.image.BufferedImage; import java.io.File; import java.io.IOException; import java.util.Arrays; import java.util.Collections; import javax.imageio.ImageIO; /* * Created on 14-Aug-2007 * */ /** * This class generates a set of PNG images that compare the spatial coherence of * the Z curve and that of its dual (which I refer to as an A curve). * * This code is in the public domain. * * @author Tom Gibara */ public class ZOrderRenderer { /** * Generates a set of images in the directory specified by the first argument. * If no arguments are specified, the current directory is used. * * @param args arguments to the application * @throws IOException if the images cannot be written */ public static void main(String[] args) throws IOException { File dir; if (args.length == 0) { dir = null; } else { dir = new File(args[0]); } int side = 1 << 8; for (int order = 1; order < 8; order++) { int scale = side >> order; plot( generateZ(order, false), scale, fileFor(dir, "z", order, side) ); plot( generateZ(order, true), scale, fileFor(dir, "a", order, side) ); } } private static File fileFor(File dir, String type, int order, int side) { return new File(dir, String.format("%1$s_order_%2$d_%3$dx%3$d.png", type, order, side)); } private static int[] generateZ(int order, boolean invert) { int size = 1 << (order * 2); int[] values = new int[size]; for (int i = 0; i < size; i++) { int z = uninterleave(i, order, invert); values[z] = i; } return values; } private static int uninterleave(int i, int order, boolean invert) { int x = 0; int y = 0; for (int j = 0; j < order; j++) { x |= (i & (1 << (j*2))) >> j; y |= (i & (1 << (j*2+1))) >> (j+1); } if (invert) { x = Integer.reverse(x) >>> (32 - order); y = Integer.reverse(y) >>> (32 - order); } return (y << order) | x; } private static void plot(int[] values, int scale, File file) throws IOException { int size = values.length; int order = (Integer.numberOfTrailingZeros(size)+1)/2; int side = scale << order; BufferedImage image = new BufferedImage(side, side , BufferedImage.TYPE_INT_ARGB); Graphics2D g = image.createGraphics(); g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY); int x = 0; int y = 0; for (int i = 0; i < size; i++) { int v = values[i] * 255 / (size-1); g.setColor(new Color(v, v, v)); g.fillRect(x, y, scale, scale); x += scale; if (x == side) { y += scale; x = 0; } } ImageIO.write(image, "PNG", file); } }