TAD2011.06 Lorenz Attractor

Sixth TAD project. Draws Lorenz attractors. The algorithm I am using is from Clifford Pickover’s Computers and the Imagination: Visual Adventures Beyond the Edge. Click within the white square, below, to draw a new attractor:

Source code:

/**
 * LorenzAttractor
 * by Joshua Madara, hyperRitual.com
 * Adapted from Clifford Pickover's
 * _Computers and the Imagination_, p.125.
 * Click in the display area to generate a new drawing.
 */

// define variables
float h = 0.01;
int npts = 4000;
float frac = 8 / 3;
float x = 0.6;
float y = 0.6;
float z = 0.6;
float xNew;
float yNew;
float zNew;

void setup() {
  size(400, 400);
  background(0);
  stroke(255, 127);
  smooth();
}

void draw() {
  // draw border
  line(0, 0, width-1, 0);
  line(width-1, 0, width-1, height-1);
  line(width-1, height-1, 0, height-1);
  line(0, height-1, 0, 0);
}

void mousePressed() {
  background(0);
  translate(width/2, height/2);
  // draw attractor
  for(int i=0; i<npts; i++) {
    xNew = x + h*10*(y-x);
    yNew = y + h*((-x*z) + 28*x-y);
    zNew = z + h*(x*y - frac*z);
    line(x*(width/50), y*(height/50), xNew*(width/50), yNew*(height/50));
    x = xNew; y = yNew; z = zNew;
    // println("x:"+x+" y:"+y+" z:"+z);
  }
  translate(-(width/2), -(height/2));
}

TAD2011.05 Labeled Graph Maker

Fifth TAD project. Similar to yesterday’s, but labels each node with a sequential number.

Labeled Graph Maker

Source code:

/**
 * LabeledGraphMaker
 * by Joshua Madara, hyperRitual.com
 * This sketch draws complete graphs from 1 to 20 nodes,
 * and labels each node with a sequential number.
 * The vertex calculations are based on Ira Greenberg's
 * Poly Maker from _Processing: Creative Coding and 
 * Computational Art_, pp. 229-230.
 * Move your mouse left/right across the drawing to 
 * decrease/increase the size of the graph.
 */

PFont nanoSansLC;
int minNodes = 1;
int maxNodes = 20;

void setup() {
  size(400, 400);
  background(0);
  smooth();
  fill(0);
  stroke(255);
  strokeWeight(1);
  ellipseMode(CENTER);
  nanoSansLC = loadFont("NanoSansLC.vlw");
  textFont(nanoSansLC);
  textAlign(CENTER, CENTER);
}

void draw() {
  background(0);
  // vary # of nodes by mouse's horizontal position
  int varNodes = round(map(mouseX, 0, width, minNodes, maxNodes));
  // calc # of edges from # of nodes
  int edges = varNodes*(varNodes - 1)/2;
  // call function to draw graph
  makeGraph(width/2, height/2, varNodes, width/2.5);
}

void makeGraph(int x, int y, int nodes, float radius) {
  float[] px = new float[nodes];
  float[] py = new float[nodes];
  float angle = 270;
  // calculate and store vertex positions
  for(int i=0; i<nodes; i++) {
    px[i] = x+cos(radians(angle))*radius;
    py[i] = y+sin(radians(angle))*radius;
    angle+=360.0/nodes; // 360/nodes returns int; need float
  }
  // draw edges
  for(int j=0; j<nodes; j++) {
    for(int k=1; k<nodes; k++) {
      line(px[j], py[j], px[k], py[k]);
    }
  }
  // draw labeled nodes
  for(int j=0; j<nodes; j++) {
    fill(0);
    ellipse(px[j], py[j], width/8, height/8);
    fill(255);
    text(j+1, px[j], py[j]);
  }
}

Graph Maker

Fourth TAD project. Unfortunately, some personal matters have become more pressing such that I may need to soon bow out of this year’s TAD having barely begun.

I am uncertain what it is that so fascinates me about graphs such as those generated here, but it has long been part of my interest in the occult and its circles, triangles, squares, pentagrams, hexagrams, etc. Geometry was one of my favorite subjects in school, and I often fantasized about what goes on at the corners of these shapes, what happens to us when we gain or lose a dimension.

This is my first time using Processing.js with Keyvan Minoukadeh‘s Processing JS WordPress plugin, so you can play with the sketch right here on this page, and do not need Java (move your mouse around the image until you see interaction):

Source code:

/**
 * GraphMaker
 * by Joshua Madara, hyperRitual.com
 * This sketch draws complete graphs from 1 to 20 nodes.
 * The vertex calculations are based on Ira Greenberg's
 * Poly Maker from _Processing: Creative Coding and 
 * Computational Art_, pp. 229-230.
 * Move your mouse left/right across the drawing to 
 * decrease/increase the size of the graph.
 */

int minNodes = 1;
int maxNodes = 22;

void setup() {
  size(400, 400);
  background(0);
  smooth();
  noFill();
  stroke(255);
  strokeWeight(1);
  ellipseMode(CENTER);
}

void draw() {
  background(0);
  // vary # of nodes by mouse's horizontal position
  int varNodes = round(map(mouseX, 0, width, minNodes, maxNodes));
  // calc # of edges from # of nodes
  int edges = varNodes*(varNodes - 1)/2;
  // display # of vertices and # of edges
  text("vertices: "+varNodes+"  edges: "+edges, 5, 15);
  // call function to draw graph
  makeGraph(width/2, height/2, varNodes, width/2.5);
}

void makeGraph(int x, int y, int nodes, float radius) {
  float[] px = new float[nodes];
  float[] py = new float[nodes];
  float angle = 270;
  // calculate and store vertex positions
  for(int i=0; i<nodes; i++) {
    px[i] = x+cos(radians(angle))*radius;
    py[i] = y+sin(radians(angle))*radius;
    angle+=360.0/nodes; // 360/nodes returns int; need float
  }
  // draw nodes and edges
  for(int j=0; j<nodes; j++) {
    ellipse(px[j], py[j], width/9, height/9);
    for(int k=1; k<nodes; k++) {
      line(px[j], py[j], px[k], py[k]);
    }
  }
}

TAD2011.03 Planetary Color Grid

Third TAD project. I intend to use the 2D array in future sketches.

Planetary Color Grid

Source code:

/**
 * PlanetaryColorGrid
 * by Joshua Madara, hyperRitual.com
 * This project displays a grid of the planetary colors
 * for each hour * day of the week, per "Table of the Planetary 
 * Hours" from the "Introduction" to Mathers' _The Key of 
 * Solomon the King_. The colors are specified in the 
 * same book: "Table of the Archangels, Angels, Metals, 
 * Days of the Week, and Colours Attributed to each Planet."
 */

// set color for each planet
color MER = #800080; // Mercury, Purple
color MOO = #FFFFFF; // Moon, White
color SAT = #000000; // Saturn, Black
color JUP = #0000FF; // Jupiter, Blue
color MAR = #FF0000; // Mars, Red
color SUN = #FFFF00; // Sun, Yellow
color VEN = #008000; // Venus, Green

// create 2D array to store color by hour (row) and day (column)
color[][] TBL = {
// SUN,MON,TUE,WED,THU,FRI,SAT
  {MER,JUP,VEN,SAT,SUN,MOO,MAR}, // 12 AM
  {MOO,MAR,MER,JUP,VEN,SAT,SUN}, // 1
  {SAT,SUN,MOO,MAR,MER,JUP,VEN}, // 2
  {JUP,VEN,SAT,SUN,MOO,MAR,MER}, // 3
  {MAR,MER,JUP,VEN,SAT,SUN,MOO}, // 4
  {SUN,MOO,MAR,MER,JUP,VEN,SAT}, // 5
  {VEN,SAT,SUN,MOO,MAR,MER,JUP}, // 6
  {MER,JUP,VEN,SAT,SUN,MOO,MAR}, // 7
  {MOO,MAR,MER,JUP,VEN,SAT,SUN}, // 8
  {SAT,SUN,MOO,MAR,MER,JUP,VEN}, // 9
  {JUP,VEN,SAT,SUN,MOO,MAR,MER}, // 10
  {MAR,MER,JUP,VEN,SAT,SUN,MOO}, // 11
  {SUN,MOO,MAR,MER,JUP,VEN,SAT}, // 12 PM
  {VEN,SAT,SUN,MOO,MAR,MER,JUP}, // 1
  {MER,JUP,VEN,SAT,SUN,MOO,MAR}, // 2
  {MOO,MAR,MER,JUP,VEN,SAT,SUN}, // 3
  {SAT,SUN,MOO,MAR,MER,JUP,VEN}, // 4
  {JUP,VEN,SAT,SUN,MOO,MAR,MER}, // 5
  {MAR,MER,JUP,VEN,SAT,SUN,MOO}, // 6
  {SUN,MOO,MAR,MER,JUP,VEN,SAT}, // 7
  {VEN,SAT,SUN,MOO,MAR,MER,JUP}, // 8
  {MER,JUP,VEN,SAT,SUN,MOO,MAR}, // 9
  {MOO,MAR,MER,JUP,VEN,SAT,SUN}, // 10
  {SAT,SUN,MOO,MAR,MER,JUP,VEN}, // 11
};

// variable x and y positions for each square in grid
int xPos = 0;
int yPos = 0;

void setup() {
  size(70, 240); // columns * 10, rows * 10
  noStroke(); // fill only
  noLoop(); // draw once
}

void draw() {
  yPos = 0;
  for(int i = 0; i < 24; i++) { // for all rows
    xPos = 0;
    for(int j = 0; j < 7; j++) { // for all columns
      fill(TBL[i][j]); // set color of square
      rect(xPos, yPos, 10, 10); // draw square
      xPos += 10; // move to draw next column
    }
    yPos += 10; // move to draw next row
  }
}

TAD2011.02 Emotiv EPOC Video Recorder

Second TAD project (with video). [2013.12.09: the TAD website has been offline for a while now]

Emotiv EPOC Video Recorder

Here is the source code:

/**
 * EPOC Recorder 1
 * by Joshua Madara, hyperRitual.com
 * This sketch records graphical data from the Emotiv 
 * EPOC via OSC messages, as a .mov video file.
 */

import oscP5.*;
import processing.video.*;

// declare objects
OscP5 oscP5;
MovieMaker mm;
Format formatter;
PFont miniMono;
Date time;

int barColor = (color(255,0,0));

void setup() {
  size(320, 240);
  background(0);
  rectMode(CORNERS);
  
  // listen for OSC messages on port 7400
  oscP5 = new OscP5(this, 7400);
  
  // plug the messages from COG/PUSH to function makeFrame()
  oscP5.plug(this,"makeFrame","/COG/PUSH");
  
  // load MiniMono font
  miniMono = loadFont("MiniMono.vlw");
  textFont(miniMono);
  
  // format timestamp
  formatter = new SimpleDateFormat("HH:mm:ss:SSS");
  
  // Create MovieMaker object with size, filename,
  // framerate, compression codec and quality
  mm = new MovieMaker(this, width, height, "epoc_record.mov",
                       30, MovieMaker.H263, MovieMaker.LOSSLESS);
}

void draw() {
  // not used
}

// for each new event, add a frame to the video
void makeFrame(float pushValue) {
  background(0); // clear screen
  
  // update and draw timestamp and COG/PUSH value
  /* note that the time here is the local time when the 
  event is recorded, not a count-up timer that initiates 
  when recording begins, although that could be implemented */
  time = new Date();
  String timestamp = formatter.format(time);
  fill(255);
  text("Time: "+timestamp+"  Value: "+pushValue, 5, 10);
  
  // draw horizontal lines
  for (int i = 0; i <= 10; i++) {
    stroke(map(i, 0, 10, 255, 0));
    float yPos = map(i, 0, 10, 20, 220);
    line(100, yPos, 220, yPos);
  }
  
  // draw bar
  float barHeight = map(pushValue, 0, 1, 220, 20);
  noStroke();
  fill(barColor, 100);
  rect(width/2 - 20, 220, width/2 + 20, barHeight);
  
  // write pixels to video frame
  mm.addFrame();
}

// press space bar to finish the video
void keyPressed() {
  if (key == ' ') {
    mm.finish();
  }
}