In the pub on Friday I was reminded of the little ray tracer I hacked up while at University, and I couldn't resist tinkering with it a bit the next day. Unfortunately the code has gone moldy over the past few years, but while I was looking at it I found another little hack I did a while ago.
This isn't something I discovered. I found the formula on the Grotesque Geometry website (under ‘grotesque geometry I’), which credits it to Gary Tupper of Pedagoguery Software. Anyway, here's what it looks like:
What's surprising is how interesting and wibbly this picture is, given that it's just a plot of some simple trigonometry. Here's the expression which is used to calculate the intensity at each point:
sin(x * (cos(y) - cos(x))) + sin(x) - sin(y)
My little program (in C) to generate it is below. It uses the image plotting and output code from my ray tracer, which is why I found it among the wreckage of that project, but it should be obvious how to change it to use any other image library.
#include "image.h" #include <string.h> #include <stdlib.h> #include <stdio.h> #include <math.h> /* Spidery wibbly picture generator. * Geoff Richards, 2002-2003. * Do what you want with this code. There's no warranty. * * Good example: ./spider 1280 1024 30 * * Based on a forumla found here: http://www.cromp.com/tess/ */ int main (int argc, char **argv) { SilsnaImage *img; int width, height; double zoom; int x, y; double xf, yf; double v; int mono; SilsnaFColor c; int scale; int i; if (argc != 4 && (argc != 5 || strcmp(argv[1], "--mono"))) { fprintf(stderr, "Usage: %s [--mono] WIDTH HEIGHT ZOOM\n", argv[0]); return 1; } i = 1; if (argc == 5) mono = 1, ++i; else mono = 0; width = atoi(argv[i++]); height = atoi(argv[i++]); zoom = atof(argv[i++]); scale = width > height ? width : height; img = silsna_img_new(width, height, 1, mono ? 1 : 8); for (y = 0; y < height; ++y) { for (x = 0; x < width; ++x) { xf = ((double) x / scale - 0.5) * zoom; yf = ((double) y / scale - 0.5) * zoom; v = sin(xf * (cos(yf) - cos(xf))) + sin(xf) - sin(yf); if (mono) silsna_img_set_pixel_mono(img, x, y, v < 0); else { c.r = c.g = c.b = (v + 1) / 2; c.a = 1; silsna_img_set_pixel_f(img, x, y, &c); } } } if (mono) silsna_img_write(img, "spider.pbm", SILSNA_FILETYPE_PBM, 0); else silsna_img_write(img, "spider.pgm", SILSNA_FILETYPE_PGM, 0); return 0; } /* vi:set ts=4 sw=4 expandtab: */
