Moshe Ladanga

MADA 03 Assessment Presentation

leave a comment »

Moshe Ladanga
MA Digital Arts
Camberwell College of Arts
University of the Arts London
June 23, 2008
*please click on the images
Colloquium
(Video Presentation)
Processing Sketches
Artist’s Statement and Reflection
ShowBuild
MA08 DVD Work
(Documentation)
Exhibitions

Written by mosheladanga

June 23, 2008 at 7:52 AM

Posted in Reflections

Exhibitions during MADA 03

leave a comment »

*Please click on the images

FutureFilm: Camden Arts Centre

Audiovisiva 5.0-Milan, Italy

Written by mosheladanga

June 22, 2008 at 12:41 PM

Posted in Reflections

ShowBuild

leave a comment »

It was a really stressful week. Need I say more?

i ended up building almost all of the plinths along with Nick. I also helped take apart the wooden wall with David Cross in the Graphic Design room and put it together again in the Cinema Space. There was so much I did I don’t even remember everything. But let’s end it on a happy note:)

*Pictures courtesy of Tara, MA08 Flicker Group

Written by mosheladanga

June 22, 2008 at 12:09 PM

Posted in Reflections

MA08 DVD

leave a comment »

Nick Buer and I designed the main menu for the DVD that would accompany the catalogue for the final show. It was fun actually, and I would term it as a classy, understated motion graphics indulgence, haha:)

MA08 DVD Main Menu

I also made this motion graphics piece for the DVD, detailing the new courses next year.

MA08 New Courses

With the images that every MA student submitted, I made slideshows for each course with each student’s work, name, email address and website on a slide that lasts for 7 seconds so that each student is given enough exposure in the DVD. This one is for MA Digital Arts:

MA Digital Arts Slideshow

With the footage we got for the DVD, I edited these into video clips that show the diversity and community of the MA at Camberwell.

Interviews with Faculty

Interviews with Students

Tours

Written by mosheladanga

June 20, 2008 at 10:46 PM

Posted in Reflections

Exposure through the Negative

leave a comment »

Sometimes, the most simple means is the first thing we ignore. We go about our modern complexificatitons, trying to make something more interesting or at least appear more valuable by adding and multiplying functions to something already interesting on its own. This is one of the most important things I learned in developing my project.

For a period I had these experiments in Processing where the image acquired a very hard edge.

*Please click on the images to see in full

**To see it in action, copy code into Processing sketch and run it; make sure the computer is connected to a webcam

Neg Pos Slow with Lines:

import processing.video.*;

Capture video;

void setup() {
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
// Uses the default video input, see the reference if this causes an error
video = new Capture(this, 640, 480, 30);
}

void draw() {
if (video.available()) {
video.read();
image(video, 0, 0, 640,480);
loadPixels();

float invertFactor = 255.0;
for (int i=0; i<pixels.length; i++){
float r= abs(red(pixels[i])-invertFactor);
float g= abs(green(pixels[i])-invertFactor);
float b= abs(blue(pixels[i])-invertFactor);
float a= abs(alpha(pixels[i])-invertFactor);
pixels[i]=color(r,g,b,millis()%a);
if( i>0 && i% width==0){
float wave = millis()%100000;
invertFactor-=50000/wave;
}

}
}
updatePixels();
filter(GRAY);
filter(INVERT);

fill(255,0);
rect(0,0,640,480);
smooth();
}

Neg Pos Slow with Lines 02:


import processing.video.*;

Capture video;

void setup() {
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
// Uses the default video input, see the reference if this causes an error
video = new Capture(this, 640, 480, 30);
}

void draw() {
if (video.available()) {
video.read();
image(video, 0, 0, 640,480);
loadPixels();

float invertFactor = 255.0;
for (int i=0; i<pixels.length; i++){
float r= abs(red(pixels[i])-invertFactor);
float g= abs(green(pixels[i])-invertFactor);
float b= abs(blue(pixels[i])-invertFactor);
float a= abs(alpha(pixels[i])-invertFactor);
pixels[i]=color(r,g,b,millis()/a);
if( i>0 && i% width==0){
float wave = millis()%100000;
invertFactor-=50000/wave;
}

}
}
updatePixels();
filter(GRAY);
filter(INVERT);

fill(255,0);
rect(0,0,640,480);
smooth();
}

– Then I returned to a sketch I made earlier, something that I at first wasn’t so happy about because I felt the code was too simple. But the thing is, the resulting moving image says something more than those above. (Thanks to Katrin and also to Nikolas, Shazzy and Zai for their encouragement 🙂 ).

import processing.video.*;

Capture video;

void setup() {
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
// Uses the default video input, see the reference if this causes an error
video = new Capture(this, 640, 480, 30);
smooth();
}

void draw() {
if (video.available()) {
video.read();
image(video, 0, 0, 640,480);
loadPixels();
float invertFactor = 255.0;

for (int i=0; i<pixels.length; i++){
color colorSum= pixels[i];
int asum = (colorSum >> 24) & 0xFF;
int rsum = (colorSum >> 16) & 0xFF;
int gsum = (colorSum >> 8 ) & 0xFF;
int bsum = colorSum & 0xFF;

int r= int(abs(rsum-invertFactor));
int g= int(abs(gsum-invertFactor));
int b= int(abs(bsum-invertFactor));
int a= int(abs(asum-invertFactor));

pixels[i]=(a<<24)|(r<<16)|(g<<8)|b;
if (i>0 && i% width==0) {

float wave =sin(pixels[i]);
invertFactor-=(255.0/width*wave);
}
}
}
updatePixels();
filter(INVERT);
filter(THRESHOLD,0.9);

}

-Again, thanks to Katrin for the latest version above; she converted parts of my code into bitwise operations to make it run faster:)

Written by mosheladanga

June 15, 2008 at 7:45 PM

Posted in Reflections

Ira Greenberg’s Negative to Positive: Adaptation for Video

leave a comment »

I’ve been studying several programs for video feeds, such as Golan Levin’s FrameDifferencing, JMMyron’s library, etc. They are basic (supposedly, but to me it looked daunting enough just to read) programs that do simple things: detect motion, detect and isolate brightest points in the frame, detect and draw around illuminated figures- all of these for capturing particular kinds of data from video that can trigger programs to do something.

But what I wanted for my side of the installation was something subtle, and I wanted to interfere in how the computer captures the image, not necessarily using the pictorial data as just data. For me an image is more than just an image, and maybe I wouldn’t need to go about this whole interactive thing through a roundabout way. I wanted to learn how the computer reads video data, and in the processing books, almost all of the video capture programs dealt with operations at the level of pixel arrays. Since video is such a rich data stream, programmers deal with video data intrinsically, meaning working at the level of the bits to facilitate fast calculations for real-time rendering of video.

What I did to adapt Greenberg’s original code was to toy a bit with the inversion factor; it was really just changing it a bit, trying to see how the code reacts to video feed.

*Copy the code into a Processing sketch, make sure you have a webcam or video cam connected, and run it to see how it really is- and apologies, my code I think is still messy.

**Please click on the images to see them in full

import processing.video.*;

Capture video;

void setup() {
size(640, 480);
video = new Capture(this, 640, 480, 30);
}

void draw() {
if (video.available()) {
video.read();
image(video, 0, 0, 640,480);
loadPixels();

float invertFactor = 255.0;
for (int i=0; i<pixels.length; i++){
float r= abs(red(pixels[i])-invertFactor);
float g= abs(green(pixels[i])-invertFactor);
float b= abs(blue(pixels[i])-invertFactor);
float a= abs(alpha(pixels[i])-invertFactor);
pixels[i]=color(r,g,b);
if(i>0 && i% width==0){
float wave = b+r+g+a;
invertFactor-=(255.0/wave);
}

}
}
updatePixels();
}

Negative to Positive with Ghosting 01:

There are two main differences in this code from the previous one. I discovered the alpha factor can be integrated in how the video feed is displayed. Since the computer reads color values as A, R, G, and B, the translucency of each color can be factored in into the array, hence producing a ghosting effect.

The second point of difference is the modulus operator that I added to the invertFactor which breaks down the its value to finer increments, which I think produced the pale palette of the image (but honestly I’m not so sure, maybe it’s the one responsible for the ghosting).


import processing.video.*;

Capture video;

void setup() {
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
// Uses the default video input, see the reference if this causes an error
video = new Capture(this, 640, 480, 30);
}

void draw() {
if (video.available()) {
video.read();
image(video, 0, 0, 640,480);
loadPixels();

float invertFactor = 255.0;
for (int i=0; i<pixels.length; i++){
float r= abs(red(pixels[i])-invertFactor);
float g= abs(green(pixels[i])-invertFactor);
float b= abs(blue(pixels[i])-invertFactor);
float a= abs(alpha(pixels[i])-invertFactor);
pixels[i]=color(r,g,b,a);
if(i>0 && i% width==0){
float wave = r+b+g+a;
invertFactor-=(255.0/width%wave);
}
}
}
updatePixels();
}

Negative to Positive with Ghosting 05:

This experiment captured the aesthetic that I wanted for the video feed; the image is at the point of erasure, and coupled with the ghosting, the image becomes more of a trace, rather than a direct representation of what the camera captures.

I simplified the wave value that affects the invertFactor by multiplying it with the sine of the pixel sum, and I made the pixel sum monochrome by only having one value plus the alpha value.

import processing.video.*;

Capture video;

void setup() {
size(640, 480); // Change size to 320 x 240 if too slow at 640 x 480
// Uses the default video input, see the reference if this causes an error
video = new Capture(this, 640, 480, 30);
}

void draw() {
if (video.available()) {
video.read();
image(video, 0, 0, 640,480);
loadPixels();
float invertFactor = 255.0;
for (int i=0; i<pixels.length; i++){
float redsum= abs(red(pixels[i]));
float bluesum= abs(blue(pixels[i]));
float greensum= abs(green(pixels[i]));
float r= abs(red(pixels[i])-invertFactor);
float g= abs(green(pixels[i])-invertFactor);
float b= abs(blue(pixels[i])-invertFactor);
float a= abs(alpha(pixels[i])-invertFactor);
r=redsum;
b=bluesum;
g=greensum;
//pixels[i]=color(r,g,b,a);
pixels[i]=color(redsum*r,a);
if (i>0 && i% width==0) {

float wave =sin(pixels[i]);
invertFactor-=(255.0/width*wave);
//invertFactor-=255/width;
// pixels[i]=color(r,g,b,a);
}
}
}
updatePixels();

}

– Learning how to read arrays almost made me snap, but it was a necessary step in understanding how pixel arrays work in capturing and displaying video in the Processing Environment. What I got excited about was the effect of the slight manipulation of code on the way the moving image is displayed.

The last experiment, the one in black&white, gave me confidence in pushing it further. The black&white image looks more like a photograph rather than a video image, and there is this resulting tension between the experience of seeing yourself move in what looks like a photograph.

Written by mosheladanga

May 29, 2008 at 7:59 PM

Posted in Reflections

Initial Play: Ellipses in Code

leave a comment »

After burning my neurons on trying to learn coding by reading Ira Greenberg’s book on one hand and Reas’ & Fry’s book on the other, I decided to just play around with a piece of code to get the hang of the syntax of Processing.

So here are sketches that I modified from an example in one of the books and turned it into something that harks back to the strange 70’s experiments with optical phenomena (that sounds quite serious, but I assure you, these things are really just for fun:)) The original was a basic program for creating animated squares, and it does it by using arrays. I wanted to understand how an array works, because in the books, the video manipulation programs work with pixel arrays to manipulate and utilise video feeds. So here’s to all the pleasures of being a beginner- Cheers!

*(to see how it really is, just copy and paste the code into a Processing sketch and run it)

Simple expanding ellipse:

int num = 1;
int[] ex = new int[num];
int[] ey = new int[num];

void setup() {
size(1000,1000);
noFill();
}
void draw() {
background(0);
stroke(255);
noFill();
smooth();
strokeWeight(1);
for (int i=0; i<num; i++) {
ex[i] = ex[i]+1;
ey[i] = ey[i]+1;
if (ex[i]+ey[i]>1999) {
ex[i] = 0;
ey[i] = 0;
}
ellipse(500,500,ex[i],ey[i]);
}
}

Ellipse Pulse:

int num = 1;
int[] ex = new int[num];
int[] ey = new int[num];

void setup() {
size(1000,1000);
noFill();
}
void draw() {
background(0);
stroke(255);
noFill();
smooth();
for (int i=0; i<num; i++) {
ex[i] = ex[i]+1;
ey[i] = ey[i]+1;
if (ex[i]+ey[i]>1999) {
ex[i] = 0;
ey[i] = 0;
}
strokeWeight(ex[i]%9);
ellipse(500,500,ex[i],ey[i]);
}
}

Ellipse Pulse 02:

int num = 1;
int[] ex = new int[num];
int[] ey = new int[num];

void setup() {
size(1000,1000);
noFill();
}
void draw() {
background(0);
stroke(255);
noFill();
smooth();
for (int i=0; i<num; i++) {
ex[i] = ex[i]+1;
ey[i] = ey[i]+1;
if (ex[i]+ey[i]>1999) {
ex[i] = 0;
ey[i] = 0;
}
strokeWeight(ex[i]%9);
ellipse(500,500,ex[i],ey[i]);
strokeWeight(ex[i]%11);
ellipse(200,200,ex[i],ey[i]);
strokeWeight(ex[i]%13);
ellipse(700,800,ex[i],ey[i]);
strokeWeight(ex[i]%7);
ellipse(400,30,ex[i],ey[i]);
}
}

Ellipse Pulse 03: (This one got my groove on, hehe)

int num = 1;
int[] ex = new int[num];
int[] ey = new int[num];

void setup() {
size(1000,1000);
noFill();
}
void draw() {
background(0);
stroke(255);
noFill();
smooth();
for (int i=0; i<num; i++) {
ex[i] = ex[i]+1;
ey[i] = ey[i]+1;
if (ex[i]+ey[i]>1999) {
ex[i] = 0;
ey[i] = 0;
}
strokeWeight(ex[i]%9);
ellipse(500,500,ex[i],ey[i]);
strokeWeight(ex[i]%11);
ellipse(500,500,ex[i]-100,ey[i]-100);
strokeWeight(ex[i]%13);
ellipse(500,500,ex[i]-200,ey[i]-200);
strokeWeight(ex[i]%7);
ellipse(500,500,ex[i]-300,ey[i]-300);
strokeWeight(ex[i]%11);
ellipse(500,500,ex[i]-400,ey[i]-400);
strokeWeight(ex[i]%13);
ellipse(500,500,ex[i]-500,ey[i]-500);
strokeWeight(ex[i]%7);
ellipse(500,500,ex[i]-600,ey[i]-600);
strokeWeight(ex[i]%11);
ellipse(500,500,ex[i]-700,ey[i]-700);
strokeWeight(ex[i]%13);
ellipse(500,500,ex[i]-800,ey[i]-800);
strokeWeight(ex[i]%7);
ellipse(500,500,ex[i]-900,ey[i]-900);
}
}

Ellipse Pulse 04:

int num = 1;
int[] ex = new int[num];
int[] ey = new int[num];

void setup() {
size(screen.width,screen.height);
noFill();
}
void draw() {
background(0);
stroke(255);
noFill();
smooth();
for (int i=0; i<num; i++) {
ex[i] = ex[i]+1;
ey[i] = ey[i]+1;
if (ex[i]+ey[i]>1999) {
ex[i] = 0;
ey[i] = 0;
}
strokeWeight(ex[i]%9);
ellipse(screen.width/2,500,ex[i],ey[i]);
strokeWeight(ex[i]%11);
ellipse(screen.width/2,500,ex[i]-100,ey[i]-100);
strokeWeight(ex[i]%13);
ellipse(screen.width/2,500,ex[i]-200,ey[i]-200);
strokeWeight(ex[i]%7);
ellipse(screen.width/2,500,ex[i]-300,ey[i]-300);
strokeWeight(ex[i]%11);
ellipse(screen.width/2,500,ex[i]-400,ey[i]-400);
strokeWeight(ex[i]%13);
ellipse(screen.width/2,500,ex[i]-500,ey[i]-500);
strokeWeight(ex[i]%7);
ellipse(screen.width/2,500,ex[i]-600,ey[i]-600);
strokeWeight(ex[i]%11);
ellipse(screen.width/2,500,ex[i]-700,ey[i]-700);
strokeWeight(ex[i]%13);
ellipse(screen.width/2,500,ex[i]-800,ey[i]-800);
strokeWeight(ex[i]%7);
ellipse(screen.width/2,500,ex[i]-900,ey[i]-900);
strokeWeight(ex[i]%11);
ellipse(screen.width/2,500,ex[i]-150,ey[i]-150);
strokeWeight(ex[i]%13);
ellipse(screen.width/2,500,ex[i]-250,ey[i]-250);
strokeWeight(ex[i]%7);
ellipse(screen.width/2,500,ex[i]-350,ey[i]-350);
strokeWeight(ex[i]%11);
ellipse(screen.width/2,500,ex[i]-450,ey[i]-450);
strokeWeight(ex[i]%13);
ellipse(screen.width/2,500,ex[i]-550,ey[i]-550);
strokeWeight(ex[i]%7);
ellipse(screen.width/2,500,ex[i]-650,ey[i]-650);
strokeWeight(ex[i]%11);
ellipse(screen.width/2,500,ex[i]-750,ey[i]-750);
strokeWeight(ex[i]%13);
ellipse(screen.width/2,500,ex[i]-850,ey[i]-850);
strokeWeight(ex[i]%7);
ellipse(screen.width/2,500,ex[i]-950,ey[i]-950);
}
}

Then I wanted something more simple, so I returned to the initial sketch I made, incorporating floats for the factors that would affect the size of the ellipses. Maybe using the sin() is a long-winded way compared to using random(), but I think the resulting rhythm is more interesting.

Ripple 03:

int num = 1;
int[] ex = new int[num];
int[] ey = new int[num];

void setup() {
size(screen.width,screen.height);
noFill();
}
void draw() {
background(0);
stroke(255);
noFill();
smooth();
for (int i=0; i<num; i++) {
ex[i] = ex[i]+1;
ey[i] = ey[i]+1;
if (ex[i]>screen.height) {
ex[i] = -ex[i];
ey[i] = -ey[i];
}
strokeWeight(.50);
ellipse(screen.width/2,screen.height/2,ex[i],ey[i]);
float e1 = sin(ex[i])/.001;
float e2 = sin(ey[i])/.001;
ellipse(screen.width/2,screen.height/2,e1+ex[i],e2+ey[i]);

}
}

Eclipse:

I wanted to experiment with tying in some lines into the sketch, but still follow the overall aesthetic. I know it’s quite gloomy and gothic, but hey, we’re in London baby:)

*please click on the images to see in full, they’re barely seen in my equally gothic black page background

int num = 1;
int[] ex = new int[num];
int[] ey = new int[num];

void setup() {
size(screen.width,screen.height);
noFill();
}
void draw() {
background(0);
stroke(255);
noFill();
smooth();
for (int i=0; i<num; i++) {
ex[i] = ex[i]+1;
ey[i] = ey[i]+1;
if (ex[i]>screen.height) {
ex[i] = -ex[i];
ey[i] = -ey[i];
}
float e1 = sin(ex[i])/.009;
float e2 = sin(ey[i])/.0001;
if (e1+e2>screen.width+screen.height) {
e1 = -e1;
e2 = -e2;
}
strokeWeight(random(.1,100)%.3);
ellipse(screen.width/2,screen.height/2,ex[i],ey[i]);
strokeWeight(random(.1,100)%.3);
ellipse(screen.width/2,screen.height/2,e1+ex[i],e2+ey[i]);
line(random(1,1650),random(1,1050),e1,e2);

}
}

What struck me about thinking in math is that you go into this state where you have to to think conceptually, in the purest sense of the word. Since the processing sketch is like a perpetual machine, the data you feed in is not really data per se, but instructions. I know for the programmers out there this is a so what moment, but for a beginner like me, it is the point where I got it.

Written by mosheladanga

May 20, 2008 at 9:27 PM

Posted in Reflections