svitoora – 02 Looking Outwards

Digitally generated column head.

Michael Hansmeyer‘s Generative Columns 

The artist worked alone to digitally generate these column, but collaborated with others to technically execute these into physical objects. Each column starts off with a cube. The cube is then algorithmically folded along certain “humanly invisible” spots. These “humanly invisible” spots refers to the mathematical maxima or minima on the surfaces of the object based on certain mathematical interpretations such as: tangency, tension, normals ,etc.

Digitally generated column physically existing thanks to laser-cutting.

Columns are exemplars of the century. From the Chinese to the Greeks, columns carry with them the aesthetic and moral values of the culture at a given point in time. Task with the job to design columns for 21st century, Hansmeyer decided to digitally generate these column and made them from stacking laser cut paper. According to Hansmeyer, the 21st century can be classified by the rise of the Digital Age and algorithms, therefore columns that are permuted and generated digitally by the computer to exemplify this era’s aesthetic seems appropriate.

Algorithmically generated details of the column. Architecturally, these fine details would be humanly impossible to plan and render, but currently it’s made possible by the computer.

svitoora – 02 Variable Face

Supawat’s Portrait

// 
// Supawat Vitoorapakorn
// Svitoora@andrew.cmu.edu
// Section E
// 
// Variable Portrait
// This code is a spin-off of the variable face example on:
// https://courses.ideate.cmu.edu/15-104/f2017/week-2-due-sep-8/

// Global Setup
	// Global
	var width = 480;
	var height = 640;
	var BLACK = "#5c5e60";
	var BG = "#ebe7e0"
	var SKIN = "#fffbf3"

	// Simple beginning template for variable face.
	var eyeSize_cur = 20;
	var faceWidth_cur = 125;
	var faceHeight_cur = 150;
	var hat_height = -faceHeight_cur + .825 * height;
	var hat_width = faceWidth_cur * 1.25;
	var eye_blacksize = .75;
	var hat_max_cur = height * .20;
	var face_top = (height * .5) - faceHeight_cur
	var mustache_y_cur = (height / 2) + eyeSize_cur * 1.5
	var mustache_low_cur = mustache_y_cur + 10
	var mustache_width_cur = faceWidth_cur / 4;
	var mustache = false

	// Declaring Variable to be assigned in setup
	var eyeSize_next;
	var hat_max_next;
	var faceWidth_next;
	var faceHeight_next;
	var mustache_width_next;
	var mustache_low_next;
	var mustache_width_next;
	var mustache_ratio;
	var click = 0;

function setup() {
	createCanvas(480, 640);
	// Specified next iteration to avoid random in global 
	eyeSize_next = random(10, 30);
	faceWidth_next = random(75, 200);
	faceHeight_next = random(100, 200);
	hat_max_next = height * .1;
	face_top = (height * .5) - faceHeight_cur;
	mustache_low_next = mustache_y_cur + random(10, 30);
	mustache_width_next = faceWidth_cur * random(.1, .3);
	mustache_ratio = 1.1;
	mustache_y_next = (height / 2) + eyeSize_next * random(1, 2)
	mustache_choice = [false, false, true]; // 1/3 chance of getting mustache
}

function draw() {
	background(BG);
	stroke(BLACK);

	// Animation's Derivative for non-linear transition
		var d_faceWidth = (Math.abs(faceWidth_cur - faceWidth_next)) / 4;
		var d_faceHeight = (Math.abs(faceHeight_cur - faceHeight_next)) / 15;
		var d_eyeSize = (Math.abs(eyeSize_cur - eyeSize_next)) / 20;
		var d_hat_max = (Math.abs(hat_max_cur - hat_max_next)) * .25;
		var d_mustache_low = (Math.abs(mustache_low_cur - mustache_low_next)) /
			40;
		var d_mustache_width = (Math.abs(mustache_width_cur -
			mustache_width_next)) / 8;

	// Adding back derivative for non-linear animation
		// facewidth
		if (faceWidth_cur > faceWidth_next) {
			faceWidth_cur = faceWidth_cur - d_faceWidth;
		} else {faceWidth_cur = faceWidth_cur + d_faceWidth;}

		// faceHeight
		if (faceHeight_cur > faceHeight_next) {
			faceHeight_cur = faceHeight_cur - d_faceHeight;
		} else {faceHeight_cur = faceHeight_cur + d_faceHeight;}

		// eyeSize
		if (eyeSize_cur > eyeSize_next) {
			eyeSize_cur = eyeSize_cur - d_eyeSize;
		} else {eyeSize_cur = eyeSize_cur + d_eyeSize;}

		// Hat Max
		if (hat_max_cur > hat_max_next) {
			hat_max_cur = hat_max_cur - d_hat_max;
		} else {hat_max_cur = hat_max_cur + d_hat_max;}

		// Mustache Low
		if (mustache_low_cur > mustache_low_next) {
			mustache_low_cur = mustache_low_cur - d_mustache_low;
		} else { mustache_low_cur = mustache_low_cur + d_mustache_low;}

		// mustache_width
		if (mustache_width_cur > mustache_width_next) {
			mustache_width_cur = mustache_width_cur - d_mustache_width;
		} else {mustache_width_cur = mustache_width_cur + d_mustache_width;}

	// Draw
		// Face
		fill(SKIN);
		strokeWeight(1);
		face_top = (height * .5) - faceHeight_cur;
		strokeWeight(0);
		fill(SKIN);
		ellipse(width / 2, height / 2, faceWidth_cur, faceHeight_cur);
		strokeWeight(1);
		fill(SKIN);

		// Eye Whites
		var eyeLX = width / 2 - faceWidth_cur * 0.25;
		var eyeRX = width / 2 + faceWidth_cur * 0.25;
		ellipse(eyeLX, height / 2, eyeSize_cur, eyeSize_cur);
		ellipse(eyeRX, height / 2, eyeSize_cur, eyeSize_cur);
		noFill();

		// Eye Black
		fill(BLACK);
		ellipse(eyeLX, height / 2,
			eyeSize_cur * eye_blacksize, eyeSize_cur * eye_blacksize);
		ellipse(eyeRX, height / 2,
			eyeSize_cur * eye_blacksize, eyeSize_cur * eye_blacksize);

		// Hat
		rectMode(CENTER);
		hat_height = Math.abs(((height / 2) - eyeSize_cur * 2), face_top)
		hat_width = faceWidth_cur * 1.25;
		rect(width / 2, hat_height, hat_width, 1);

		// Hat Line
		rectMode(CORNERS);
		rect((width / 2) - faceWidth_cur / 2, hat_height,
			(width / 2) + faceWidth_cur / 2, hat_max_cur);

		// Brow
		noFill();
		arc(eyeLX, height / 2 - eyeSize_cur * .75,
			eyeSize_cur * 1.25, eyeSize_cur * 1.25,
			PI + ((2 * PI) * .10), 0 - ((2 * PI) * .10));
		arc(eyeRX, height / 2 - eyeSize_cur * .75,
			eyeSize_cur * 1.25, eyeSize_cur * 1.25,
			PI + ((2 * PI) * .10), 0 - ((2 * PI) * .10));

		// nose
		line(width / 2, (height / 2) + eye_blacksize * 1.2,
			width / 2, (height / 2) + eyeSize_cur);
		rectMode(CORNERS);
		rect((width / 2) - faceWidth_cur * .05, (height / 2) + eyeSize_cur,
			(width / 2) + faceWidth_cur * .05, (height / 2) + eyeSize_cur);

	// Moustache or No Moustache
		if (mustache == false) {
			// Mouth
			arc(width / 2, height / 2 + faceHeight_cur * .20,
				faceWidth_cur * .3, faceWidth_cur * .3,
				0 + ((2 * PI) * .1), PI - ((2 * PI) * .1));
		} else {
			// Mustache
			fill(BLACK);
			var mustache_y = (height / 2) + eyeSize_cur * 1.75
			quad((width / 2) - mustache_width_cur, mustache_y,
				(width / 2) + mustache_width_cur, mustache_y,
				(width / 2) + mustache_width_cur * mustache_ratio,
				mustache_low_cur,
				(width / 2) - mustache_width_cur * mustache_ratio,
				mustache_low_cur);}
}

function mousePressed() {
	// when the user clicks, the next face is randomly generated
	// and eased into via animation
	faceWidth_next = random(75, 200);
	faceHeight_next = random(100, 200);
	eyeSize_next = random(10, 30);
	eye_blacksize = random(.25, .75);
	hat_max_next = random(height * .1, hat_height - 60);
	mustache_y_next = (height / 2) + eyeSize_next * random(1, 2)
	mustache_low_next = mustache_y_next + random(20, 40);
	mustache_width_next = faceWidth_next * random(.1, .3);
	mustache_ratio = random(1, 2);
	mustache_width_cur = mustache_width_cur / 2; // Fans stache out
	mustache = random(mustache_choice);
	click += 1; // tacks amount of clicks
}

As a design and HCI student, one simple method I learn to humanize screen based technology is to make graphic transition less “jarring”. In real life, nature does not just change its shape based on an interaction. Nature morphs, pops, and grows into its next form; nature transitions. And within those transitions are specific qualities and characteristics that brings life and animate the dead into life.

To achieve this vivacity, I created a program that introduces an axis of time. A current state and next state variable is created, and every 60 fps the current state approaches the next state variable. Instead of using the traditional approach of +=1 which results in a linear transition, I created a differences variable(∆) that eases the transition by adding in a fraction of the difference between the current and next state. In pseudo-code, while(cur_state ≠ next state){ cur_state±(∆state*some fraction)}.

In actual code:


Looking back at this, the transition code part of this could be re-written as a function with multiple inputs to clean up the program as such:


Lastly, I chose warm monochromatic color scheme to make my generative appear warm and inviting.

Grays with warm tints and shades to convey warmth.

Initial hand sketch from sketchbook:

 

SaveSave

SaveSave

SaveSave

SaveSave

SaveSave

svitoora – 01 Portrait

I first started off with hand sketch:

Hand Sketch

The hand sketch is then vectorized in Sketch with simple geometric shapes keeping in mind that this will be written with code.

Vectorizing Sketch

The program is constructed proportions. Every variable is based on the width (w) and height (h) of the canvas. Half way through writing the program, I realized that it would be efficient to be able to visually see the proportions of the screens I am working with, so I quickly wrote a program.

Coding with proportions.

Because the code is based of proportions rather than pixels, I can quickly mirror my facial features with 1-.xx. Just as I leave traces of sketch marks on my drawings, here I’ve chosen to leave the traces of code I’ve used to proportionally construct my drawing.

Supawat’s Portrait

// 
// Supawat Vitoorapakorn
// Svitoora@andrew.cmu.edu
// Section E
// 
// Self Portrait of Supawat Vitoorapakorn

// Global

    s = .65
    var w = 768*(600/768);
    var h = 1024*(650/768);

// Face Var
    var f_w = (424/768) *w;     //face width
    var f_h = (553/1024)*h;     //face height

// Neck Var
    var neck_w = .27;
    var neck_y = .75;
    var neck_h = .1;
    var neck_w2 = .365;

// V-neck Var
    var v_x1 = (w/2) - (neck_w/2)*w ;
    var v_x2 = (w/2) + (neck_w/2)*w;
    var v_x3 = (w/2);

    var v_yshift = 0;

    var v_y2 = .795*h; 
    var v_y1 = v_y2+((83/h)*h);
    var v_y3 = v_y1

// Color
    var SKIN = "#ffe4b2";
    var T_SHIRT = "#5C5C5C";
    var BLACK = (0,0,0);
    var SKIN_GLASS = "#ffe9c1";
    var RED = "#ed2024";
    var SHADOW = 255*.125;

// MAIN FUNCTION
function setup() {
    createCanvas(w,h);
    background(255);
    rectMode(CORNER);

// Backdrop
    fill(0);
    noStroke();
    noFill();
    strokeWeight(1);
    fill(216, 216, 216);
    rectMode(CORNERS);
    rect(w*.015, (.075)*h, w*(1-.015), h*.915);
    rectMode(CORNER);

// Neck
    noStroke();
    fill(SKIN);
    rectMode(CORNERS);
    rect(w*neck_w2, h*.7, w*(1-neck_w2),h*.8)
    rectMode(CORNER);
    
// Shirt
    fill(T_SHIRT);
    neck_size = .36;
    quad(   neck_size*w,      .795*h,
            (1-neck_size)*w,  .795*h,
            (1-.015)*w, .915*h,
            .015*w,     .915*h);

// V_Neck
    fill(SKIN)
    triangle(   v_x1, v_y2,         // left
                v_x3, v_y1,         // mid
                v_x2, v_y2);        // right

// Neck Shadow
    neck_shadowH = (143.9/h)*h;
    neck_y = h*.6175;

    var n_x1 = w*.5 + (neck_w*w)*.5;
    var n_x2 = w*.5 - (neck_w*w)*.5;
    var n_x3 = w*.5 + (neck_w*w)*.5;
    var n_x4 = w*.5 - (neck_w*w)*.5;

    var n_y1 = 0+neck_y;
    var n_y2 = 0+neck_y;
    var n_y3 = neck_shadowH+neck_y;
    var n_y4 = (neck_shadowH-(1/25)*h)+neck_y;

    fill(0,0,0,SHADOW)
    quad(   n_x1,n_y1,
            n_x2,n_y2,
            n_x4,n_y4,
            n_x3,n_y3
        );
      
// Face
    noStroke();
    fill(SKIN);
    ellipse(w*.5,h*.475,f_w,f_h);

// Hair
    fill(BLACK);
    h_y = h*.33
    h_h = -h*.175

    var h_x1 = w*.5 + (neck_w*w)*.9;        // Right Base
    var h_x2 = w*.5 - (neck_w*w)*.9;        // Left Base
    var h_x3 = w*.5 + (neck_w*w)*1.33;      // Right Tip
    var h_x4 = w*.5 - (neck_w*w)*.77;        // Left Tip

    var h_y1 = h_y;
    var h_y2 = h_y+20;
    var h_y3 = h_y+h_h;        // Right Tip
    var h_y4 = h_y+h_h*.9;     // Left Tip


    quad(   h_x1,h_y1,
            h_x2,h_y2,
            h_x4,h_y4,
            h_x3,h_y3
        );

// Facial Features
    // Facial Features Left
        var glass_size = .20;
        var nose_bridge = .13;
        var eye_size = .04;
        var eye_y = .51;
        var side = 1;       //1 for left; -1 for right

        // Glasses Bottom Shadow
        var shadow_yshift = .015;
        noStroke();
        rectMode(CORNERS);
        fill(0,0,0,SHADOW);
        rect(   .223*w,  side*((.485+shadow_yshift)*h),
                (1-.223)*w,          (eye_y+shadow_yshift)*h);

        // Glass Frame
        fill(SKIN_GLASS);
        strokeWeight(10);
        stroke(BLACK);
        strokeJoin(ROUND);
        arc(     w*(.5-nose_bridge), h*(.5),     //+nose bridge to flip
                 w*glass_size, w*glass_size,
                 0-(1/15*PI), PI+(1/15*PI),
                 CHORD);

        // Eyes Round
        fill(BLACK);
        noStroke();
        arc(     w*(.5-nose_bridge), h*(eye_y),     //+nose bridge to flip
                 w*eye_size, w*eye_size,
                 0-(1/15*PI), PI+(1/15*PI),
                 CHORD);

        // Eyes Line
        strokeWeight(5);
        stroke(BLACK);
        strokeCap(SQUARE);
        line(   (.5-nose_bridge-.05)*w,h*(eye_y-.001),
                (.5-nose_bridge+.05)*w,h*(eye_y-.001));

        // Glasses Side
        rectMode(CORNERS);
        strokeJoin(MITER);
        rect(   side*(.223*w),side*(.485*h),
                .27*w, eye_y*h);
        rectMode(CORNER);

        rectMode(CORNER);
        // Top Shadow
        strokeWeight(15);
        stroke(0,0,0,SHADOW);
        line(   (side*.28)*w, .48*h,
                (side*.46)*w, .48*h);

        // Eyebrow
        var e_x1 = (side*.27)*w;
        var e_y1 = .46*h;

        var e_x2 = (side*.335)*w;
        var e_y2 = .44*h;

        var e_x3 = (side*.45)*w;
        var e_y3 = .45*h;

        // strokeWeight(7.5);
        stroke(BLACK);
        line(   e_x1,   e_y1,
                e_x2, e_y2      );
        
        line(   e_x2-(3*side),e_y2,
                e_x3, e_y3          );
    // Facial Features Right
        var side = -1;       //1 for left; -1 for right

        // Glass Frame
        fill(SKIN_GLASS);
        strokeWeight(10);
        stroke(BLACK);
        strokeJoin(ROUND);
        arc(     w*(.5+nose_bridge), h*(.5),     //+nose bridge to flip
                 w*glass_size, w*glass_size,
                 0-(1/15*PI), PI+(1/15*PI),
                 CHORD);
        // Eyes Round
        fill(BLACK);
        noStroke();
        arc(     w*(.5+nose_bridge), h*(eye_y),     //+nose bridge to flip
                 w*eye_size, w*eye_size,
                 0-(1/15*PI), PI+(1/15*PI),
                 CHORD);

        // Eyes Line
        strokeWeight(5);
        stroke(BLACK);
        strokeCap(SQUARE);
        line(   (.5+nose_bridge-.05)*w,h*(eye_y-.001),
                (.5+nose_bridge+.05)*w,h*(eye_y-.001));

        // Glasses Side
        rectMode(CORNERS);
        strokeJoin(MITER);
        rect(   (1-.223)*w,.485*h,
                (1-.27)*w, eye_y*h);
        rectMode(CORNER);

        //Cast Shadow
        rectMode(CORNER);
        // Top Shadow
        strokeWeight(15);
        stroke(0,0,0,SHADOW);
        line(   (1-.28)*w, .48*h,
                (1-.46)*w, .48*h);

        // Eyebrow
        var e_x1 = (1-.27)*w;
        var e_y1 = .46*h;

        var e_x2 = (1-.335)*w;
        var e_y2 = .44*h;

        var e_x3 = (1-.45)*w;
        var e_y3 = .45*h;


        // strokeWeight(7.5);
        stroke(BLACK);
        line(   e_x1,   e_y1,
                e_x2, e_y2      );
        
        line(   e_x2-(3*side),e_y2,
                e_x3, e_y3          );
    // Facial Features Symetrical
        // Glasses Side
        var side = 1;
        noStroke();
        fill(BLACK);
        rectMode(CORNERS);
        strokeJoin(MITER);
        rect(   (.5-.03)*w,  (.485*h),
                (.5+.03)*w, eye_y*h);
        rectMode(CORNER);

        // Nose .
        var nose_y = .63;
        var nose_width = .025

        strokeWeight(7.5)
        stroke(BLACK);
        line(   (.5-nose_width)*w,  nose_y*h,
                (.5+nose_width)*w,  nose_y*h);

        // Mouth .
        var mouth_y = nose_y+.05;
        var mouth_width = .035*1.5

        strokeWeight(7.5)
        stroke(BLACK);
        line(   (.5-mouth_width)*w,  mouth_y*h,
                (.5+mouth_width)*w,  mouth_y*h);

        // Mouth Shadow
        var mouth_shadow_y = nose_y+.05+.02;
        var mouth_shadow_width = .035*.75

        strokeWeight(7.5)
        stroke(0,0,0,25);
        line(   (.5-mouth_shadow_width)*w,  mouth_shadow_y*h,
                (.5+mouth_shadow_width)*w,  mouth_shadow_y*h);

// Hair Side
    strokeWeight(0);
    noStroke();
    fill(0,0,0);
    quad    (w*.275, h*.34,
            w*.24,  h*.45,
            w*.215,  h*.47,
            w*.20,  h*.37);

    quad    (w*(1-.275), h*.32,
            w*(1-.24),  h*.45,
            w*(1-.215),  h*.47,
            w*(1-.2),  h*.35);
}
// Creates Mouse Guider
    function draw() {
        setup();
        noStroke();
        fill(255,240,0,255*.30);
        ellipse(mouseX, mouseY, 200, 200);
        var X = (mouseX/w).toFixed(3);
        var Y = (mouseY/h).toFixed(3);
        var XY = str("("+X+","+Y+")");
        fill(RED);
        textSize(24);
        strokeWeight(1);
        text(XY,mouseX,mouseY);
    }

SaveSave

SaveSave

SaveSave

svitoora – 01 Looking Outwards

Laurie Anderson (Generative Portrait) Diana Lange

Laurie Anderson (Generative Portrait) Diana Lange

This generative project is created alone by the artist, specifically with Processing. To the best of my knowledge, the author uses an image process module to help define the nodes by which the segments are connected. Diana Lange is inspired by nature and nature’s process. To me, this portrait reminds of a handmade nail and thread algorithmic portrait. The future where this portrait points to is one where our identity our digitalized. What does it mean to have our identity digitized, and can one truly have an identity in a digitalized age?