Showing posts with label fractals. Show all posts
Showing posts with label fractals. Show all posts

20111101

Visual analogue of a Shepard tone

A Shepard tone is an auditory illusion that appears to indefinitely ascend or descend in pitch, without actually changing pitch at all.
 
Shepard tones work because they actually contain multiple tones, separated by octaves. As tones get higher in pitch, they fade out. New tones fade in at the lower pitches. The net effect is that it sounds like all the constituent tones are continually increasing in pitch -- and they are, but pitches fade in and out so that, on average, the pitch composition is constant.

Since 2D quasicrystals can be rendered as a sum of plane-waves, it is possible to form the analogue of a Shepard tone with these visual objects. Each plane wave is replaced with a collection of plane waves, at 2,4,8,16... etc times the spatial frequency of the original plane wave.

The relative amplitudes of the plane waves are set so that the spatial frequency stays approximately the same even as the underlying waves are scaled. The result is a quasicrystal that appears to zoom in or out indefinitely, without fundamentally changing in structure.

The infinite zoom effects creates a motion-fatigue optical illusion, which will cause illusory contraction of your visual field after staring at the GIF below:
 
 

 

More quasicrystal zoom GIFs can be found here. You can run and modify the code I used to generate these animation. Copy the following code into a file called QuasiZoom.java. Then, in a terminal, type "javac QuasiZoom.java" in the same directory, and then "java QuasiZoom". Various parameters to tune the output are noted in comments in the code. Then use Gimp to make an animated GIF.

import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import static java.lang.Math.*;

public class QuasiZoom {

    // Defines a gaussian function. We will use this to define the
    // envelope of spatial frequencies
    public static double gaussian(double x) {
        return exp(-x*x/2)/sqrt(2*PI);
    }

    public static void main(String[] args) throws IOException {
        int k = 5;        //number of plane waves
        int stripes = 3;  //number of stripes per wave
        int N = 500;      //image size in pixels
        int divisions=40; //number of frames to divide the animation into
        int N2 = N/2;

        BufferedImage it = new BufferedImage(N, N, BufferedImage.TYPE_INT_RGB);

        //the range of different spatial frequencies
        int [] M=new int[]{1,2,4,8,16,32,64,128,256};
        
    //the main ( central ) spatial frequency
        double mean=log(16);

    //the spread of the spatial frequency envelope
        double sigma=1;

    //counts the frames 
        int ss=0;

    //iterate over spatial scales, scaling geometrically
        for (double sc=2.0; sc>1.0; sc/=pow(2,1./divisions)) 
        {    
            System.out.println("frame = "+ss);

            //adjust the  wavelengths for the current spatial scale
            double [] m=new double[M.length];
            for (int l=0; l<M.length; l++)
                m[l]=M[l]*sc;

            //modulate each wavelength by a gaussian envelop in log
            //frequency, centered around aforementioned mean with defined
            //standard deviation
            double sum=0;
            double [] W=new double[M.length];
            for (int l=0; l<M.length; l++) {
                W[l]=gaussian((log(m[l])-mean)/sigma);
                sum+=W[l];
            }
            sum*=k;

            for (int i = 0; i < N; i++) {
                for (int j = 0; j < N; j++) {

                    double x = j - N2, y = i - N2; //cartesian coordinates
                    double C = 0;                  // accumulator
 
                    // iterate over all k plane waves
                    for (double t = 0; t < PI; t += PI / k){
                        //compute the phase of the plane wave
                        double ph=(x*cos(t)+y*sin(t))*2*PI*stripes/N;
                        //take a weighted sum over the different spatial scales
                        for (int l=0; l<M.length; l++)
                            C += (cos(ph*m[l]))*W[l];
                    }
                    // convert the summed waves to a [0,1] interval
                    // and then convert to [0,255] greyscale color
                    C = min(1,max(0,(C*0.5+0.5)/sum));
                    int c = (int) (C * 255);
                    it.setRGB(i, j, c | (c << 8) | (c << 16));
                }
            }
            ImageIO.write(it, "png", new File("out"+(ss++)+".png"));
        }
        
    }
}


20110721

Fractals on the Master Boot Record

WeAlone contributor Keegan has adapted the video feedback method of rendering Julia sets to fit in 512 bytes of Intel machine code that runs from the master boot record. This program was created for the IO MBR demo competition.



When a computer starts up, a very small program begins the process of loading and booting up progressively more complex programs, until an entire modern operating system is loaded. With some cleverness and optimization, we were able to make a program that fits in this space, and rather than booting the machine, renders animated Julia set fractals.

The source code is written in assembly, and can be downloaded here. The compiled program image can be downloaded from here.

If you're running Linux, you can try this out yourself using the qemu machine emulator, which can be retrieved from the package manager ( menu → system → administration → synaptic package manager, search for and install 'qemu-kvm' ). Once installed, simply typing "qemu phosphene.mbr" in a terminal should suffice.

You can also create a USB thumb drive that can boot most Intel architecture machines into this fractal rendering mode. Once booted, it is possible to remove the USB stick and leave the machine in a fractal-rendering coma until it is power cycled. Be careful here, if you overwrite the MBR on your own machine, you will trash your partition table and leave your system only able to boot as a fractal.

Assuming your USB thumb drive is /dev/sdb, the following commands will create a bootable USB stick. For the love of humanity do not write to /dev/sda, since this is probably your system boot partition.

$: sudo dd if=phosphene.mbr of=/dev/sdb
$: sync
( wait until IO lights stop blinking and remove the drive )

In one instance, we found that writing to /dev/sdb1 worked while writing to /dev/sdb did not. I'm not sure if this was a fluke, but you can try this if it doesn't seem to work on the first try.

These programs are so small, they can be distributed as plaintext in base64.


with a more flickery, rapidly changing colorscheme :

McCO2I7AuOAHjtC8ABC4EwDNELsPALQOvpl9rM0QhMB1+R5oAKAfMfa/AJ65AArzpR8xwM0QuAFP
uQEBvwB+zRCwQDHS93UEULgCT7sBAc0QusgDMMDuQrkAAVDuiNjuiPjuWAQCgcMDBeLv2+PHBYUA
3wXGBbHfBb0AAWgAEA+hFh+M4IDEEI7AvgAgv8B4sRCs0OgmAAVH4veBxjABgcfwAYH/AJhy5zH2
Mf+M4ID0UI7AiSzfBNjy2cDZ/9nJ2ereydn/2ejYwNz63vnZ7d7puoABuQACYNnqiRTfBNj12OGJ
DN8E2PXY4t3S3MrZwdjI3uveydjA2MPZwt7C2ercwt7B2M3fHIsU2MvfHIscgOcBieiB+oABcxXR
4sDmBIzgAPSO6DD2weIIAdNligcmiAVhR+Kghf91B4zAgMQQjsBKdY9F3tmM4ID0UI7gjthoAKAH
MdLoNgAx9r9AeLuAAbkAAqSF/3UKNgIW/g9T6B0AW+LvgceAAEv2w391CYzYgMQQjtgx9oXbddXp
8P64BU8x280Qw0kDDQppbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////
////////////////////////////////////////////////////////////////////////Vao=



A nice colorscheme with a black background :

McCO2I7AuOAHjtC8ABC4EwDNELsPALQOvp99rM0QhMB1+R5oAKAfMfa/AJ65AArzpR8xwM0QuAFP
uQEBvwB+zRCwQDHS93UEULgCT7sBAc0QusgDMMDuQrkAAVDuiNjuiPjuWAQCgcMDBeLv2+PHBYUA
3wXGBbHfBb0AAWgAEA+hFh+M4IDEEI7AvgAgv8B4sRCs0OgmAAVH4veBxjABgcfwAYH/AJhy5zH2
Mf+M4ID0UI7AiSzfBNjy2cDZ/9nJ2ereydn/2ejYwNz63vnZ7d7puoABuQACYNnqiRTfBNj12OGJ
DN8E2PXY4t3S3MrZwdjI3uveydjA2MPZwt7C2ercwt7B2M3fHIsU2MvfHIscgOcBMMCB+oABcxvR
4sDmBIzgAPSO6DD2weIIAdNligc8/3QC/sAmiAVhR+Kahf91B4zAgMQQjsBKdYlF3tmM4ID0UI7g
jthoAKAHMdLoNgAx9r9AeLuAAbkAAqSF/3UKNgIW/g9T6B0AW+LvgceAAEv2w391CYzYgMQQjtgx
9oXbddXp6v64BU8x280Qw0kDDQppbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////
////////////////////////////////////////////////////////////////////////Vao=


To convert these strings into a usable program, in Linux, use the base64 command. Type "base64 -d > phosphene.mbr" in the terminal, and press enter. Then, paste one of the base 64 encoded programs in the terminal. Press enter, and then control+D ( end of file ). This will convert the text into the compiled machine code for phosphene.mbr. Run it as explained above using qemu or making a bootable USB drive.

$: base64 -d > foo.mbr
McCO2I7AuOAHjtC8ABC4EwDNELsPALQOvp99rM0QhMB1+R5oAKAfMfa/AJ65AArzpR8xwM0QuAFP
uQEBvwB+zRCwQDHS93UEULgCT7sBAc0QusgDMMDuQrkAAVDuiNjuiPjuWAQCgcMDBeLv2+PHBYUA
3wXGBbHfBb0AAWgAEA+hFh+M4IDEEI7AvgAgv8B4sRCs0OgmAAVH4veBxjABgcfwAYH/AJhy5zH2
Mf+M4ID0UI7AiSzfBNjy2cDZ/9nJ2ereydn/2ejYwNz63vnZ7d7puoABuQACYNnqiRTfBNj12OGJ
DN8E2PXY4t3S3MrZwdjI3uveydjA2MPZwt7C2ercwt7B2M3fHIsU2MvfHIscgOcBMMCB+oABcxvR
4sDmBIzgAPSO6DD2weIIAdNligc8/3QC/sAmiAVhR+Kahf91B4zAgMQQjsBKdYlF3tmM4ID0UI7g
jthoAKAHMdLoNgAx9r9AeLuAAbkAAqSF/3UKNgIW/g9T6B0AW+LvgceAAEv2w391CYzYgMQQjtgx
9oXbddXp6v64BU8x280Qw0kDDQppbwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD/////////////
////////////////////////////////////////////////////////////////////////Vao=
$: qemu foo.mbr


20101121

Fractals

The folks at fractalforums.com have been rendering more of those crazy alien-cyborg-city-spaceship ray-traced fractals. I don't understand their algorithms but their "mandelbulb" software is free for download. Perfect for zoning out for a little brain-massage.









And I thought I was just going to pop over to youtube to grab this little wheel illusion video. The fractals are much more entertaining.


20100823

I would not mind living inside this fractal

Youtube user zsirhorcsog has posted some sort of crazy 3D fractal. It more or less looks like a gothic cathedral made of math, when you zoom in. Its something I would not mind at all seeing converted to a nonspecific place-of-worship-esq building.


20080326

I should be doing work

Two days behind and I'm just pointing the web-cam back at the computer screen.


20080124

a ( e^z+e^(iz) ) + c


Adding a rotation and scaling parameter hes increased the variety of fractals that can be observed in Perceptron. Gradient and coloring methods are important for revealing the structure of the maps, and a gradient control parameter has been added. Functions of the form a ( e^z+e^(iz) ) + c, ( a and c complex ) have been providing much amusement.


20070914

Conformal maps on photography

I just found a Flickr set with some cool examples of applying conformal maps to photography.


20070909

Fractal neurofeedback

There's an article on the Mind Hacks blog that overlaps heavily with the kind of stuff we talk about here. Their output looks Sheep-ish; since my realtime Electric Sheep renderer is working now, maybe I'll build an OpenEEG box and bang out an open source alternative.


20070903

More screenshots

Here's the latest.

Edit: I've added some more screenshots to the gallery, with tasty vertical symmetry imposed by mirroring.


Here I'm trying out some different maps, and also incorporating a camera feed, which is what gives it the more fuzzy, organic look. The geometric patterns with n-way radial symmetry come from z' = z*c, which gives simple scaling and rotation. The squished circles come from z' = sin(real(p) + t) + i*sin(imag(p)), where p = z^2 + c and t is a real parameter.


20070901

More fractal video feedback

I've been working on a new implementation of the fractal video feedback idea. Unlike the previous attempts, the code is nice and modular, so complicated bits of OpenGL hackery get encapsulated in an object with a simple interface. It's still very much a work in progress, but I thought I'd share some results now. Feedback (no pun intended) is very much appreciated.

Video:

Shoving the video through the YouTubes kills the quality. I have some higher quality screenshots in a Flickr gallery. Some of my favorites:




The basic idea is the same as Perceptron: take the previous frame, map it through some complex function, draw stuff on top, repeat. In this case, the "stuff on top" consists of a colored border around the buffer that changes hue, plus some moving polygons that can be inserted by the user (which aren't used in the video, but are in some of the stills). In these examples, the map is a convex combination of complex functions; in the video it's z' = a*log(z)*c + (1-a)*(z2+c). Here z is the point being rendered, z' is the point in the previous frame where we get its color, c is a complex parameter, and a is a real parameter between 0 and 1.

There are two modes: interactive and animated. In interactive mode, c and a are controlled with a joystick (which makes it feel like a flight simulator on acid). The user can also place control points in this (c,a) space. In animated mode, the parameters move smoothly between these control points along a Catmull-Rom spline, which produces a nice C1 continuous curve.

The feedback loop is rendered offscreen at 4096x4096 pixels. Since colors are inverted every time through the loop, only every other frame is drawn to the screen, to make it somewhat less seizuretastic. At this resolution, the system has 48MB of state. On my GeForce 8800GTS I can get about 100 FPS in this loop; by a conservative estimate of the operations involved, this is about 60 GFLOPS. I bow before NVIDIA. Now if only I had one of these...


20070422

Idea : fractally compressed AR

This is an augmented reality idea I had while walking around looking at trees after Drop Day. Basically, one would wear a VR headset that displays imagery from the outside world, except that occurrences of similar visual objects get replaced with the exact same object, or the same object perturbed in some synthetic way.

So, for example, the leaves of a tree would get replaced with fractals that are generated to look like leaves. As another example, areas of the same "texture" could be identified (basically, areas with little low-frequency spatial component, possibly after a heuristically determined perspective correction). Then a random small exemplar patch is selected and used to fill the entire area with Wei & Levoy / Ashikhmin-style synthetic textures.

The point of all of this is that you're essentially applying lossy compression (by identifying similar regions and discarding the differences between them), then decompressing and feeding the information into the brain (and thus mind). Working on the assumption that consciousness essentially involves a form of lossy compression which selects salient features and attenuates others, you can determine the degree and nature of this compression by determining when a similar, externally applied compression becomes noticeable or incapacitating.

My guess is that there will be a wide range of compression levels where reality is still manageable and comprehensible but develops a highly surreal character. Of course to experiment meaningfully you'd need a good enough AR setup that the hardware itself doesn't introduce too much distortion, although you could also control for this by having people use the system without software distortions.


20070416

I'm on the Interblag!

I finally got around to writing something for this blog. First, I have a quotation from our beloved Admiral:

"Do you want this fire extinguisher? No? How about this tag that says 'do not remove under penalty of fire marshal'?"

Second, the Perceptron screenshots on here look really damn good, and I decided I should post some of what I've been working on lately as well. This started yesterday as a CS 101 assignment and kind of got out of control.






There's also a movie here of me playing with it. It's 56M and still looks shitty due to compression, but you can at least get the idea. May cause seizures in a small percentage of the population.

Update: The video is (maybe) on YouTube now: