Pixel Sorting

2.png
PImage img;

void setup() {
  size(915, 548);
  img = loadImage("Little_Chief_Mountain_GNP1.jpg");
  img.resize(915, 548);
}

void draw() {
  img.loadPixels();
  for (int x = 0; x < img.width; x+= img.width /300) {
    for (int y = 0; y < img.height; y+= img.height / 300) {
      int c = getPixel(img, x, y);
      if (getPixel(img, x-1, y) > c) {
        setPixel(img, x-1, y, c);
        c = getPixel(img, x-1, y);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x-1, y-1) > c){
        setPixel(img, x-1, y-1, c);
        c = getPixel(img, x-1, y-1);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x, y-1) > c){
        setPixel(img, x, y-1, c);
        c = getPixel(img, x, y-1);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x+1, y) > c){
        setPixel(img, x+1, y, c);
        c = getPixel(img, x+1, y);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x+1, y+1) > c){
        setPixel(img, x+1, y+1, c);
        c = getPixel(img, x+1, y+1);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x, y+1) > c){
        setPixel(img, x, y+1, c);
        c = getPixel(img, x, y+1);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x-1, y+1) > c){
        setPixel(img, x-1, y+1, c);
        c = getPixel(img, x-1, y+1);
        setPixel(img, x, y, c);
      }
      if (getPixel(img, x+1, y-1) > c){
        setPixel(img, x+1, y-1, c);
        c = getPixel(img, x+1, y-1);
        setPixel(img, x, y, c);
      }
    }
  }
  img.updatePixels();
  image(img, 0,0);
  noLoop();
}


public int getPixel(PImage img, int x, int y) {
   x = x < 0 ? 0 : x >= img.width ? img.width - 1 : x;
   y = y < 0 ? 0 : y >= img.height ? img.height - 1 : y;
  return img.pixels[x + y * img.width];
}

public void setPixel(PImage img, int x, int y, int c) {
   x = x < 0 ? 0 : x >= img.width ? img.width - 1 : x;
   y = y < 0 ? 0 : y >= img.height ? img.height - 1 : y;
  img.pixels[x + y * img.width] = c;
}

Superformula

1.png
float n1 = 0;
float n2 = 0;
float n3 = 0;
float m = 0;

float rotY = 0;
float rotX = 0;

void setup() {
  size(1280, 720, P3D); 
  n1 = random(1,100);
  n2 = random(1,100);
  n3 = random(1,100);
  m = (int)random(2,10);
}

void draw() {
  background(255);
  translate(width/2, height/2);
  rotateY(rotY);
  rotateX(rotX);
  noStroke();
  lights();
  int total = 75;
  PVector[][] globe = new PVector[total+1][total+1];
  float r = 300;
  for (int i = 0; i < total+1; i++) {
    float lat = map(i, 0, total, -HALF_PI, HALF_PI);
    float r2 = superFormulaR(m, n1, n2, n3, lat);//superShape3D(lat, m, 0.2, 1.7, 1.7);
    //float r2 = supershape(lat, 2, 10, 10, 10);
    for (int j = 0; j < total+1; j++) {
      float lon = map(j, 0, total, -PI, PI);
      float r1 = superFormulaR(m, n1, n2, n3, lon);//supershape(lon, m, 0.2, 1.7, 1.7);
      //float r1 = supershape(lon, 8, 60, 100, 30);
      float x = r * r1 * cos(lon) * r2 * cos(lat);
      float y = r * r1 * sin(lon) * r2 * cos(lat);
      float z = r * r2 * sin(lat);
      globe[i][j] = new PVector(x, y, z);
    }
  }

  //stroke(255);
  //fill(255);
  //noFill();
  //offset += 5;
  pushMatrix();
  colorMode(HSB);
  for (int i = 0; i < total; i++) {
    float hu = map(i, 0, total, 0, 255*6);
    fill((hu + 0) % 255 , (hu *10) % 255, (hu /2) % 255);
    beginShape(TRIANGLE_STRIP);
    for (int j = 0; j < total+1; j++) {
      PVector v1 = globe[i][j];
      vertex(v1.x, v1.y, v1.z);
      PVector v2 = globe[i+1][j];
      vertex(v2.x, v2.y, v2.z);
    }
    endShape();
  }
  popMatrix();
    rotY += PConstants.TWO_PI / 1000;
    rotX += PConstants.TWO_PI / 1000;
    if (frameCount % 350 == 0) {
      n1 = random(1,100);
      n2 = random(1,100);
      n3 = random(1,100);
      m = (int)random(2,20);  
    }
}

public PVector superFormula3D(float m, float n1, float n2, float n3, float phi, float theta)
{
   float r1 = superFormulaR(m, n1, n2, n3, theta);
   float r2 = superFormulaR(m, n1, n2, n3, phi);
   return new PVector(r1 * cos(theta) * r2 * cos(phi), r1 * sin(theta) * r2 * cos(phi), r2 * sin(phi));
}

public float superFormulaR(float m, float n1, float n2, float n3, float phi)
{
   float t1,t2;
   float a=1,b=1;

   t1 = cos(m * phi / 4) / a;
   t1 = abs(t1);
   t1 = pow(t1,n2);

   t2 = sin(m * phi / 4) / b;
   t2 = abs(t2);
   t2 = pow(t2,n3);

   return 1/pow(t1+t2,-1/n1);
}



public PVector superFormula(float m, float n1, float n2, float n3, float phi)
{
   float r;
   float t1,t2;
   float a=1,b=1;

   t1 = cos(m * phi / 4) / a;
   t1 = abs(t1);
   t1 = pow(t1,n2);

   t2 = sin(m * phi / 4) / b;
   t2 = abs(t2);
   t2 = pow(t2,n3);

   r = pow(t1+t2,1/n1);
   if (abs(r) == 0) {
      return new PVector(0,0);
   } else {
      r = 1 / r;
      return new PVector(r * cos(phi),r * sin(phi));
   }
}

Wiki: here

Glitched Block Matching Algorithm

391zuf.gif


Glitched Block matching algorithm. Usually used in video compression

  PImage img1;
  PImage img2;
  ArrayList mv;
  
void setup(){
  size(1280,720);
  img1 = loadImage("video\\thumb0087.jpg");
  img2 = loadImage("video\\thumb0088.jpg");
  
  mv = blockMatch(img1,img2,4);
}


ArrayList blockMatch(PImage img1, PImage img2, int N) {
  ArrayList moveVectors3 = new ArrayList();
  for (int oi = 0; oi < 1280; oi +=N) {
    for (int oj = 0; oj < 720; oj +=N) {
        PImage searchImage = img1.get(oi - N, oj - N, N*3, N*3);
        PImage R = img2.get(oi, oj, N, N);
        float mad = MeanDifference(searchImage, R, N, N, N);
        PVector sp = new PVector(oi, oj);
        PVector ep = null;
        int step = N;
        while (step!=1) {
          for (int i = 0; i < N*3; i+=N) {
              for (int j = 0; j < N*3; j+=N) {
                  float nmad = MeanDifference(searchImage, R, N, i, j);
                  if (nmad < mad) {
                      mad = nmad;
                      ep = new PVector(i + oi- N, j + oj- N);
                  }
              }
          }
          step/=2;
        }
        if (ep != null){
          //moveVectors.add(img1.get((int)ep.x, (int)ep.y,N,N));
          //moveVectors2.add(sp);
          moveVectors3.add(new PVector[]{sp,ep});
          //println(oi + "  " + oj);
        }
    }
  }
  return moveVectors3;
}

void printFromVec(PImage img, PVector[] moveVectors, int N) {
    image(img.get((int)moveVectors[1].x, (int)moveVectors[1].y, N,N), (int)moveVectors[0].x, (int)moveVectors[0].y);
}

void printAllFVec(PImage img, ArrayList moveVectors, int N) {
  for (int i = 0; i <  moveVectors.size(); i++) {
    printFromVec(img, moveVectors.get(i), N);
  }
}

void drawToGrap(PImage img, PImage base, PGraphics grap, ArrayList moveVectors, int N) {
  grap.beginDraw();
  grap.background(0);
  grap.image(base,0,0);
  for (int i = 0; i <  moveVectors.size(); i++) {
    grap.image(img.get((int)moveVectors.get(i)[1].x, (int)moveVectors.get(i)[1].y, N,N), (int)moveVectors.get(i)[0].x, (int)moveVectors.get(i)[0].y);
  }
  grap.endDraw();
}
  

float MeanDifference(PImage C, PImage R, int N, int x, int y) {
  float MAD = 0;
  for (int i = 0; i < N; i++) {
    for (int j = 0; j < N; j++) {
      if (j + y >= N*3 || i + x >= N*3) continue;
      MAD += Math.abs(hue(C.get(i + x, j + y)) - hue(R.get(i,j)));
    }
  }
  return MAD /= (N*N);
}



void draw() {
  image(img1,0,0);
    noFill();
    stroke(255);
  PGraphics g1 = createGraphics(width, height);
  drawToGrap(img2, img1, g1, mv, 4);
  image(g1,  0,0);
}

Wiki: here

Max Headroom

Processing script based off the TV show Max Headroom. 

float rotx = PI/4;
float roty = PI/4;

float boxSize = 800;
float lineNum = 30;
void setup()
{
  size(1020, 720, P3D);
  textureMode(NORMAL);
  shapeMode (CENTER);
}
 
void draw()
{
   
  background(0);
  translate(width/2.0, height/2.0, boxSize/2);
  rotateX(rotx);
  rotateY(roty);
  stroke(255);
  noFill();
  float z = boxSize/2;
  pushMatrix();
  int side = 0;
  for (float rotY = HALF_PI; rotY <= TWO_PI; rotY+= HALF_PI) {
    switch (side) {
      case(0):
      stroke(255,0,0);
      break;
      case(1):
      stroke(255,255,0);
      break;
      case(2):
      stroke(255,255,0);
      break;
      case(3):
      stroke(255,0,0);
      break;
    }
    side++;
    for (int i = 0; i <= lineNum; i++) {
      if (rotY == HALF_PI || rotY == TWO_PI) {
        drawLineFromX(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
      } else{
        drawLineFromY(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
      }
    }
    rotateY(rotY);
  }
  popMatrix();
  pushMatrix();
  rotateX(HALF_PI);
  stroke(0,0,255);
  for (int i = 0; i <= lineNum; i++) {
        drawLineFromY(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
  }
  popMatrix();
  pushMatrix();
  rotateX(-HALF_PI);
  stroke(0,255,0);
  for (int i = 0; i <= lineNum; i++) {
        drawLineFromY(-boxSize/2, boxSize/2, -boxSize/2 + i * boxSize/lineNum, z, 20);
  }
  popMatrix();
  lineNum = 20 + 10 * sin(frameCount / 100.0);
  boxSize = 700 + 100 * sin(frameCount / 100.0 + PI);
  if(!mousePressed){
    roty+=0.01;
    rotx+=0.02;
  }
}

float lineZOffset(int i, float z) {
  float size = 25 + 25 *sin(frameCount / 50.0 + PI /3);
  return z - size+ size * noise(frameCount / 100.0 + (float)i * 10000);
}

void drawLineFromX(float xStart, float xEnd, float y, float z, float points) {
  beginShape();
  float next = abs(xEnd - xStart) / points;
  curveVertex(xStart - next, y, z);
  curveVertex(xStart, y, z);
  int i = 1;
  for (float x = xStart + next; x < xEnd; x+= next) {
    curveVertex(x,  y, lineZOffset(2 + i, z));
    i++;
  }
  curveVertex(xEnd, y,  z);
  curveVertex(xEnd - next, y,  z);
  endShape();
}

void drawLineFromY(float yStart, float yEnd, float x, float z, float points) {
  beginShape();
  float next = abs(yEnd - yStart) / points;
  curveVertex(x,  yStart - next,z);
  curveVertex(x,  yStart, z);
  int i = 1;
  for (float y = yStart + next; y < yEnd; y+= next) {
  curveVertex(x,  y, lineZOffset(2 + i, z));
    i++;
  }
  curveVertex(x,  yEnd, z);
  curveVertex(x,  yEnd + next, z);
  endShape();
}
 

A Dark and Stormy Night, Programming with Poems

The above image was made using ADASN (A Dark and Stormy Night), a simple stack based programming language. I designed the code of the programming language to be written as normal English.  Every word of a sentence that has over 3 characters represents a number, 1 if it starts with a, 2 if it starts with b and etc. All the words in the sentence are then added up and if the resulting number corresponds to a command then the command is executed otherwise it is pushed onto the stack. Numbers 55 through to 86 represent commands. When the code is executed it generates a video where the code runs separately for each pixel every frame of the video.

The code tends to work best when written as a poem as it allows for more flexible sentence structure. The trick is to write code that not only describes how to make an image but what that image means.

Currently I have written a transpiler using JavaCC that converts the code into java and glsl, using processing to interface with opengl. This creates java source code that can then be compiled into a runnable jar file.

Commands

  • 55     time - pushes the current running time to the stack
  • 56    dup - duplicates the top of the stack
  • 57    push - pushes the number number to the stack even if its a command
  • 58    decimal - pops then pushes 1 / that numbers  
  • 59    <= - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 60    >= - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 61    < - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 62    > - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 63    = - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 64    != - pops the top 2 from the stack then compares then and pushes 1 or 0
  • 65    + - pops the top 2 from the stack then pushes one plus the other
  • 66    - - pops the top 2 from the stack then pushes one minus the other
  • 67    * - pops the top 2 from the stack then pushes one times the other
  • 68    / - pops the top 2 from the stack then pushes one divided by the other
  • 69    % - pops the top 2 from the stack then pushes one modulus the other
  • 70    x - pushes the x position of the current pixel
  • 71    y - pushes the y position of the current pixel
  • 72    r - pushed the red color value of the current pixel
  • 73    g - pushed the green color value of the current pixel
  • 74    b - pushed the blue color value of the current pixel
  • 75    sR - pops then sets the current red color value to that number
  • 76    sG - pops then sets the current green color value to that number
  • 77    sB - pops then sets the current blue color value to that number
  • 78    sin - pops then pushes the sin of that number
  • 79    cos - pops then pushes the cos of that number
  • 80    tan - pops then pushes the tan of that number
  • 81    rand - pushes a random number
  • 82    width - pushes the width of the video
  • 83    height - pushes the height of the video
  • 84     pop - pops the stack
  • 85    length - pops the top 2 on the stack and pushes the length of them
  • 86    atan - pops the top 2 on the stack and pushes the atan of them

Example

Bolbus.

Terrifically gigantic,
floating a buv, 
up in the heavens,
floating with love.

Rising at morn,
falling at night,
quivering a buv.

Rising at morn,
falling at night,
soaring a buv.

Watching from far above,
shining down sun,
moving the fun.

Beautiful.

Terrifically gigantic,
floating above, 
up in the heavens,
floating with love.

Rising at morn,
falling at night,
quivering a buv.

Rising at morn,
falling at night,
soaring above.

Watching from far above,
shining down sun,
moving the fun.

Terrifically gigantic,
floating around all up a bove, 
up in the heavens,
floating with love.

Around, all bashly above.

Terrifically gigantic,
floating a buv, 
up in the heavens,
floating with love.

Rising at morn,
falling at night,
quivering a buv.

Watching from far above,
shining sun,
moving the fun.

Rising at morn,
falling at night,
xhuming the sun.

(As you can see i did cheat a bit by changing the spelling of some words, xhuming instead of exhuming and a buv/a bove instead of above)

Parsing

This is what it gets parsed down to:

  1. 2 82 68 70 66 2 83 68 71 66 85 4 82 68 62 75
  2. 2 width / x - 2 height / y - length  4 width / > setR
  3. R = length y - (height /2), x - (width /2)) >  width / 4