Project 1 – Gauntlet

by Max Hawkins @ 2:42 am 12 January 2011

Schotter

LibCinder Implementation

Processing/Processing.js Implementation

Text Rain

#include "cinder/app/AppBasic.h"
#include "cinder/gl/gl.h"
#include "cinder/Text.h"
#include "cinder/gl/GlslProg.h"
#include "cinder/gl/Texture.h"
#include "cinder/Rand.h"
#include "cinder/Capture.h"
 
#include "Kinect.h"
 
using namespace ci;
using namespace ci::app;
using namespace std;
 
/***************************
 Messy, but -probably- works
****************************/
 
class Letter {
public:
    static std::map<char, gl::Texture> textureForCharacter;
    static std::map<char, float> baselineOffsetForCharacter;
    static float fontSize;
    static bool texturesGenerated;
 
    Vec2f mPosition;
    Vec2f mVelocity;
    Vec2f mAcceleration;
    char mLetter;
 
    Letter(char letter, Vec2f position) {
 
        mAcceleration = Vec2f(0, 0.01);
        mPosition = position;
        mVelocity = Vec2f(0, 0);
 
        mLetter = letter;
 
        if (!texturesGenerated) {
            for(char character = 'A'; character < 'Z'; character++) {
                float baselineOffset = 0;
                std::string str(1, character);
                textureForCharacter[character] = gl::Texture( renderString( str, Font("Arial", fontSize), Color::white(), &baselineOffset ) );
                baselineOffsetForCharacter[character] = baselineOffset;
            }
            texturesGenerated = true;
        }
    }
 
    void update() {
        mVelocity += mAcceleration;
        mPosition += mVelocity;
    }
 
    void draw() {
        float brightness = 1 - (mPosition.y / getWindowHeight());
        gl::color(Color(1, brightness, brightness ));
        gl::draw( textureForCharacter[mLetter], mPosition - Vec2f( 0, baselineOffsetForCharacter[mLetter] ) );
    }
 
    Area frame() {
        return Area(mPosition + Vec2f(0, baselineOffsetForCharacter[mLetter]), textureForCharacter[mLetter].getSize());
    }
 
    void detectCollisions(const Surface8u &background) {
        const Area clippedFrame( frame().getClipBy( background.getBounds() ) );
 
        if (clippedFrame.getWidth() <= 0 || clippedFrame.getHeight() <= 0) return;
 
        float sum = 0; // probably bad. hm.
 
        uint8_t inc = background.getPixelInc();
 
        const uint8_t *line = background.getData( clippedFrame.getUL() );
 
        for( int32_t y = clippedFrame.y1; y < clippedFrame.y2; ++y ) {
 
            const uint8_t *pixel = line;
 
            for( int32_t x = clippedFrame.x1; x < clippedFrame.x2; ++x ) {
                if(*pixel > 150) {
                    sum++;
                }
                pixel += inc;
            }
 
            line += background.getRowBytes();
        }
 
        if (sum > 10 && mVelocity.y > 0) {
            mVelocity.y = 0;
        }
        if(sum > 20) {
            mVelocity.y -= sum * 0.0004;
        }
 
//        mVelocity -= percent * 5;
    }
 
 
};
bool Letter::texturesGenerated = false;
std::map<char, float> Letter::baselineOffsetForCharacter;
std::map<char, gl::Texture> Letter::textureForCharacter;
float Letter::fontSize = 18;
 
class TextRainApp : public AppBasic {
public:
	void setup();
	void mouseDown( MouseEvent event );	
	void update();
	void draw();
private:
    std::vector<Letter> letters;
    void emitRandomLetter();
    float mLastEmitTime;
    float mEmitInterval;
 
    float lastEmitLocation;
    int lastEmitCharacterIndex;
 
    Kinect				mKinect;
	gl::Texture			mColorTexture, mDepthTexture;
    Surface8u mDepthSurface;
 
};
 
void TextRainApp::setup()
{
    setFrameRate(30);
    mEmitInterval = 1;
    mLastEmitTime = -mEmitInterval;
 
    lastEmitCharacterIndex = 0;
    lastEmitLocation = 0;
 
    mKinect = Kinect( Kinect::Device() ); // the default Device implies the first Kinect connected
 
    gl::enableAdditiveBlending();
}
 
void TextRainApp::mouseDown( MouseEvent event )
{
}
 
void TextRainApp::emitRandomLetter() {
    //    char character = (char) Rand::randInt(97, 122);
    string poem = ("A ONE THAT IS NOT COLD IS SCARECLY A ONE AT ALL");
    lastEmitCharacterIndex += Rand::randInt(poem.length());
    char character = poem[lastEmitCharacterIndex % poem.length()];
 
    if(character == ' ') return;
 
    float horizontalEmitLocation = ((float)(lastEmitCharacterIndex % poem.length()) / poem.length()) * getWindowWidth();
    Vec2f startPosition = Vec2f(horizontalEmitLocation, -18);
    lastEmitLocation = horizontalEmitLocation;
 
    Letter letter(character, startPosition);
    letters.push_back(letter);
}
 
void TextRainApp::update()
{
    if ((getElapsedSeconds() - mLastEmitTime) > mEmitInterval) {
        emitRandomLetter();
        mLastEmitTime = getElapsedSeconds();
    }
 
	if( mKinect.checkNewDepthFrame() ) {
		mDepthTexture = mKinect.getDepthImage();
        mDepthSurface = Surface8u( mKinect.getDepthImage() );
    }
 
	if( mKinect.checkNewColorFrame() )
		mColorTexture = mKinect.getColorImage();
}
 
void TextRainApp::draw()
{
	// clear out the window with black
	gl::clear( Color( 0, 0, 0 ) ); 
 
    gl::color(Color::white());
 
    if (mColorTexture) {
        gl::draw(mColorTexture);
    }
 
    for (vector<Letter>::iterator iter = letters.begin(); iter != letters.end();) {
 
        iter->update();
        iter->draw();
 
        if (mDepthSurface) {
            iter->detectCollisions(mDepthSurface);
        }
 
        if (iter->mPosition.y > getWindowHeight() || iter->mPosition.y < -1000) {
            iter = letters.erase(iter);
        } else {
            iter = ++iter;
        }
 
    }
}
 
 
CINDER_APP_BASIC( TextRainApp, RendererGl )

LeWei-TextRain

by Le Wei @ 2:19 am

Made with openFrameworks. The letters land on places that are darker than a certain threshold. Its kind of slow here but its much faster, I promise, when video is not recording.

Ward Penney-Schotter

by Ward Penney @ 2:15 am

Ward Penney – Schotter, Processing.js Active Object

Ward Penney – Schotter, Processing Applet

Ward Penney – Schotter, Code

/*
Interactive Art & Computational Design / Spring 2011
Carnegie Mellon University

Ward Penney
12-Jan-2011

This is an educational reproduction of the Schotter computational art, located at http://www.medienkunstnetz.de/works/schotter/
*/

// setup variables
int rows = 24; // rows of sqaures
int columns = 12; // columns of squares
int margin = 30; // margin around the matrix
int sideLength = 25; // side of each square
float factor = .5; // factor for randomness, smaller fraction means less variability in rotation and offset of squares

void setup() {

// set up the screen to have the desired margins around the determined
// amount of rows / columns of squares of a given sideLength
int sizeX = 2*margin + columns*sideLength;
int sizeY = 2*margin + rows*sideLength;
size (sizeX, sizeY);

smooth(); // turn on anti-aliasing
noFill(); // turn of rectangle fills
background(#FFFFFF); // background color
noLoop(); // execute draw() only once
}

void draw() {

// count squares
int squareCount = 1;

// print rows
for (int ir = 1 ; ir < rows ; ir ++) { // print columns for (int ic = 1 ; ic < columns ; ic ++) { // translate translate(margin + ic*sideLength + sideLength/2, margin + ir*sideLength + sideLength/2); // get proportional counter / count amount of rotaion, over a degree range float absRotationDegs = (map(squareCount, 0, rows * columns - 1, 0, 360) * factor)/2; float randomRotationRadians = radians(random(-absRotationDegs, absRotationDegs)); rotate(randomRotationRadians); // get random offsets, halved for negtive possibility float absOffsetX = (map(squareCount, 0, rows * columns - 1, 0, sideLength/2) * factor)/2; float absOffsetY = (map(squareCount, 0, rows * columns - 1, 0, sideLength*2) * factor)/2; float randomOffsetX = random(-absOffsetX, absOffsetX); float randomOffsetY = random(-absOffsetY, absOffsetY); // draw rectangle rectMode(CENTER); rect(randomOffsetX, randomOffsetY, sideLength, sideLength); // rotate back rotate(-randomRotationRadians); // translate back translate(-1*(margin + ic*sideLength + sideLength/2), -1*(margin + ir*sideLength + sideLength/2)); // increment square count squareCount += 1; } } }

Ward Penney - Schotter video demo in OpenFrameworks

Schotter: Processing

by cdoomany @ 1:53 am

size(300,400);
smooth();
background(0);
noStroke();
fill(242,204,47,90);
rectMode(CENTER);

int x = 28;
int y = 44;
int rndm = 0;
int step = 90/y;
int w = width/x;
int h = height/y;

for (int j = 2;j < y;j++){
rndm += step;
fill(242,204,j * 20,j + 90);

for (int i = 2;i < x;i++) {
pushMatrix();
float z = random(-rndm/2, rndm/2);
translate(i*w – w/2 + z/3,j*h – h/2 + z/3);
rotate(radians(z));
rect(0,0,w,h);
popMatrix();
}
}

shawn sims-schotter

by Shawn Sims @ 1:44 am


If you move your mouse slowly from the top of the grid to the bottom you will see the chaos ensue. This is the processing.js version above and below is the same code embedded in a jar applet.

This is the same Schotter interaction in c++ with the openFrameworks library.

Processing code below

// shawn sims

int xCount = 12;
int yCount = 20;

int boxSize = 20;
int distort = mouseY;
int gridShift = 50;

int resetMouse = 0;

void setup(){
size(325,565);
frameRate(2);
}

void draw(){
smooth();
background(255);
rectMode(CENTER);

int xLocation = (width - gridShift)/xCount;
int yLocation = (height - gridShift)/yCount;

int rowCount = (height - gridShift)/yLocation;
int column = (width - gridShift)/xLocation;

int distortion = 0;
int distortionRotate = 55/(distortion+rowCount);

for( int i=0; i

Susan Lin – Schotter

by susanlin @ 1:39 am

Processing.js


Processing

Processing Code
After a few iterations, the working code ends up being 18 lines and optimized (to the best of my ability).

void setup()
{
  size(384, 674); //12x21 grid
  background(255);
  noFill();
  stroke(0);
 
  float variability=0; //important to use float over int!
  for(int j=0; j&lt;672 ; j=j+32) {
    for(int i=0; i&lt;384; i=i+32) {
      pushMatrix();
      translate(i+random(-variability, variability), j+random(-variability, variability));
      rotate(radians(random(-variability, variability)));
      rect(0, 0, 32, 32);
      variability+=0.083; //increases per square, this number is 1/12
      popMatrix();
    }
  }
}

openFrameworks

Mark Shuster – Text Rain

by mshuster @ 1:32 am

Text Rain

Far from perfect, but it does respond to visual data. This was created in openFrameworks.

LeWei-Schotter

by Le Wei @ 1:30 am

Processing

Processing.js

Processing code

background(255);
smooth();
size(420, 724);
fill(0, 0);
 
float entropy = 0;
for (int i = 0; i < 20; i++) {
  for (int j = 0; j < 12; j++) {
    int x = 25 + 30*j + int(random(entropy*-1, entropy));
    int y = 15 + 30*i + int(random(entropy*-1, entropy));
    int angle = 0 + int(random(entropy*-1, entropy));
 
    pushMatrix();
    translate(x,y);
    rotate(radians(angle));
    rect(0,0,30,30);
    popMatrix();
    entropy += 0.08;
  }
 
}

openFrameworks

Gives you a new version each time it runs.

Paul-LookingOutwards-3

by ppm @ 12:59 am

Just Landed is a visualization of airline flights by Jer Thorp using Processing. Twitter is searched for passenger’s Tweets containing the phrase “just landed”. Tweets are parsed for a destination, and an home location is taken from that passenger’s profile. Each data point becomes an arc in the animation.

It is a clever use of social media as a new data set. Information which ten years ago would have been available only to large airlines keeping careful records is now published freely online, and by no conscious decision of anyone involved. However, the animation is a bit misleading; many assumptions are made when interpreting the data. (For example, all passengers are assumed to be coming from their home.) The inaccuracy is a compromise made in order to create impressive visuals from informally-gathered data.

More info available on Thorp’s blog.

Mark Shuster – Schotter

by mshuster @ 12:58 am

Processing

void setup() {
  size(300, 600);
  smooth();
  noFill();
  background(255);
  rectMode(CENTER);
  noLoop();
}
 
void draw() {
  int x, y;
  int offset = 50;
  for (y = 0; y < 24; y++) {
    for (x = 0; x < 12; x++) {
      resetMatrix();
      translate(offset + x*20,offset + y*20);
      float r = random(-y, y);
      rotate((PI * 2) / 360 * r * 2);
      rect(r/2, r/2, 20, 20);
      resetMatrix();
    }
    translate(-x*20,0);
  }
}

Processing.js


Timothy Sherman – Schotter

by Timothy Sherman @ 12:36 am

Processing.js:

Processing:

Processing Code:

 boolean toChange = true;
 void setup()
 {
   size(400, 760);
   smooth();
   noFill();
   background(248);
 }
 
 void mouseClicked()
 {
   toChange = true;
 }
 
 void draw()
 {
   if(toChange)
   {
     fill(248);
     rect(-1,-1,401,801);
     noFill();
     for(int j = 0;j<24;j++)
     {
       for(int i = 0;i<12;i++)
       {
         pushMatrix();
         translate(20+i*30+random(j*.3+i/30)-(j*.3+i/30)/2,20+j*30+random(j*.3+i/30)-(j*.3+i/30)/2);
         rotate(radians(random((6*j+i/2))-(6*j+i/2)/2));
         rect(0,0,30,30);
         popMatrix();
       }
     }
     toChange = false;
   }
 }

Cinder:

Paul-LookingOutwards-2

by ppm @ 12:23 am

Meischeid is a small animation by French director Matray.

3D primitives are displaced with various noise textures corresponding to different frequencies on the piano. The textures are animated by hand along to the music in After Effects. So, somewhat disappointingly, there is no music-driven procedural generation. But it is a beautiful interpretation of deconstructivist forms, and one which would lend itself naturally to automatic generation. I appreciate the use of simple polygons and particles as a material; ever since Pixar’s sub-pixel subdivision, digital animators have been trying to hide these basic building blocks of computer graphics. I also happen to be a freak about Blender, the 3D software used here.

More info at BlenderNation

Project1 – Gauntlet – Text Rain

by huaishup @ 12:20 am

The Text Rain project is coded using processing.

Part of the code is borrowed and revised from  Frame Differencing by Golan Levin.

The Main idea is to find the difference between two frames and match the different point with text’s position.

Here is the video:

[youtube clip_id=”HY_5GxodZcQ”]

And the link to the Video:
Video

Project1 – Gauntlet – Schotter

by huaishup @ 11:14 pm 11 January 2011

1. Schotter in js file

2. Schotter in applet

3. The Video for Openframeworks

Or Click Here

4. The Code for Schotter

/**

*/
int length = 20;
float randomseed = 0.0;

void setup() {
background(255);
smooth();
size(200,400);
display();

}

void display() {

for(int y=0;y for(int x=10;x pushMatrix();
translate(x*(1+random(-randomseed,randomseed)),0);

rotate(random(-randomseed-y/500,randomseed+y/500));

rect(0,5,length,length);

popMatrix();
}
translate(0,20*(1+random(-randomseed,randomseed)));
}
}

Chong Han Chua – Schotter

by Chong Han Chua @ 10:58 pm

Processing

Processing.js

OpenFrameworks

Paul-LookingOutwards-1

by ppm @ 10:49 pm

Electric Sheep is a distributed computing project by Scott Draves (PhD in Computer Science from Carnegie Mellon) generating a continuous fractal animation. Users anywhere can contribute their computers to the effort, view the results in real-time, and select their favorite patterns to be favored in the genetic evolution of future “sheep”.

The project amazes me aesthetically and technically–the way simple rules, when iterated, produce landscapes too vast and too volatile to ever be quite grasped by human senses.

The project succeeds in all it attempts. The functionality of audience-selected patterns connects users around the world in wordless visual play. By using viewer’s personal computing devices, it reveals the power available to us in consumer technology. However, it stops short of extending into the real world. Once we step away from the computer, the ongoing parade becomes invisible to us; we can only experience it with the help of our digital prosthetics.

Paul-TextRain

by ppm @ 10:45 pm

Text Rain clone à la openFrameworks:

The significant lines of code for Text Rain are:

void app::createLetter() {
    letter *l;
    // Index in textStr from which to take this letter
    int lPos;

    // Find first open position in text
    for(int i=0; ix = ofRandom(0.0, (float) screenWidth);

            lPos = l->x / ((float) screenWidth) * ((float) textStrLen);
            if(lPos < 0)
                lPos = 0;
            if(lPos >= textStrLen)
                lPos = textStrLen - 1;

            l->c = textStr[lPos];
            l->y = 0;
            l->vel = 0.5;
            text[i] = l;
            break;
        }
    }
}

void app::destLetter(int i) {
    free(text[i]);
    text[i] = (letter *) 0;
}

void app::setup(){
	camWidth  = 320;
	camHeight = 240;
	pixelMax = 3*camWidth*camHeight;

	vidGrabber.setVerbose(true);
	vidGrabber.initGrabber(camWidth,camHeight);

	textStrLen = strlen(textStr);

	// Create text
    textMax = 1000;
	text = new letter* [textMax];
    for(int i=0; iy > yMax) {
                destLetter(i);
            } else {
                // Move this letter down at its own speed
                l->y += l->vel;

                // Move this letter up as long as it is on an obstacle
                for(;;) {
                    pixel = 3 * ( ((int)l->y)*camWidth + ((int)l->x) );
                    if(pixel >= 0 && pixel < pixelMax &&
                       img[pixel] + img[pixel+1] + img[pixel+2] < obShade) {
                        l->y -= 1.0;
                    } else {
                        break;
                    }
                }
            }
        }
    }

    // Create a new letter every 60 frames
    if( !(ofGetFrameNum()%60) ) {
        createLetter();
    }
}

void app::draw(){
    letter *l;
    char str[2] = "a";

	ofSetColor(0xffffff);
	vidGrabber.draw(0,0);

	ofSetColor(255,255,255);

	// Draw all letters
    for(int i=0; ic;
            ofDrawBitmapString(str, (int) l->x, (int) l->y);
        }
    }
}

Paul-Schotter

by ppm @ 8:18 pm

Schotter clone à la Processing:

à la Processing.js:

and à la openFrameworks:

The openFrameworks version takes the random seed from the mouse position. Otherwise, the code is nearly identical for all three. The significant lines of code are:

float rot;
float tran;

translate(10, 10);

for(int col=0; col<12; col++) {
  rot = 0.0;
  tran = 0.0;
  translate(20, 0);

  pushMatrix();

  for(int row=0; row<24; row++) {
    translate(0, 20);
    pushMatrix();

    translate(random(-tran, tran), random(-tran, tran));
    rotate(random(-rot, rot));
    rect(-20, -20, 20, 20);

    popMatrix();

    rot += 0.03;
    tran += 0.03;
  }

  popMatrix();
}

Ben Gotow-Schotter

by Ben Gotow @ 5:46 pm

In Processing.js:

As a Java applet:

As code:

size(404,730);

int rows = 22;
int cols = 12;
int count = cols * rows;
int rect_width = 384 / cols;
int rect_height = rect_width;

smooth();
translate(10,10);
background(#ffffff);
noFill();

for (int ii = 0; ii < count; ii ++){ int origin_x = (ii%cols) * rect_width; int origin_y = floor(ii / cols) * rect_height; float randomness = ((float)ii / (float)count); float rand_rad = (random(2f) - 1f) * randomness * randomness; float rand_x = (random(8f) - 4f) * randomness * randomness; float rand_y = (random(8f) - 4f) * randomness * randomness; translate(origin_x, origin_y); rotate(rand_rad); rect(rand_x, rand_y, rect_width, rect_height); rotate(-rand_rad); translate(-origin_x, -origin_y); }

A video demonstrating it done in OpenFrameworks as well:

Eric Brockmeyer – Schotter

by eric.brockmeyer @ 5:04 pm

This is a processing.js file uploaded to my lab’s site. The wordpress processing.js plug-in had a problem with my class, however the code works fine when run with the processing.1.0.0.min.js file.

Press ENTER to pause.

This is the processing code for the Schotter project.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
//Eric Brockmeyer
//Interactive Art and Computational Design 
//January 11, 2011
//Reproduction of "Schotter" by Georg Nees
//press ENTER to pause!
Square[][] squares = new Square[12][24];
int keyValue = 0;
void setup(){
  size(241, 481);
  frameRate(24);
  background(#000000);
  for (int i = 0; i < 12; i++){
   for (int j = 0; j < 24; j++){
    squares[i][j] = new Square(i,j);
   }    
  }
}
void draw(){
  background(#000000);
  drawSquares();
}
void drawSquares(){
  for (int i = 0; i < 12; i++){
   for (int j = 0; j < 24; j++){
    squares[i][j].move();
    squares[i][j].draw();
   }    
  }
}
void keyPressed(){
  if (key == ENTER){
   if (keyValue == 0){
    keyValue = 1;
    noLoop();
   } 
   else {
    keyValue = 0; 
    loop();
   }  
  } 
}
class Square {
  int x, y, dim;
  float rotation;
  float xRandom, yRandom;
  Square(int xTemp, int yTemp) {
    x = xTemp;
    y = yTemp;
    dim = 20;
    rotation = 0;
  }
  void move() {
    rotation = y * random(0.05);
    xRandom = x + Y * random(-0.05,0.05);
    yRandom = y + y * random(-0.05,0.05);
  }
  void draw() {
    pushMatrix(); 
    translate(xRandom*dim+(dim/2), yRandom*dim+(dim/2)); 
    rotate(rotation);
    translate(-dim/2, -dim/2);
    noFill();
    strokeWeight(1);
    stroke(#ffffff);
    rect(0, 0, dim, dim);
    popMatrix(); 
  }
}

This is the Schotter processing applet.

Press ENTER to pause.

This is my Open Frameworks Schotter example.

OF “Schotter” Interpretation from eric brockmeyer on Vimeo.

« Previous PageNext Page »
This work is licensed under a Creative Commons Attribution-Noncommercial-Share Alike 3.0 Unported License.
(c) 2021 Interactive Art & Computational Design / Spring 2011 | powered by WordPress with Barecity