creating interactive type #4 3-dimensional type
This issue is part of the series: creating interactive type #1 interactive type light #2 timed type #3 evolving type #4 3-dimensional type #5 outline-generated type
introduction The booklet series »creating interactive type« introduces how to design interactive and responsive type. Visual attributes of typefaces, like style, colour or size, have always given an additional meaning to the text’s content. Interactivity can take this formaspect to another level. By adding behaviour, letter shapes are able to respond to time and usage and make this process part of the given information. The described interactive type applications are built with the opensource programming language Processing, that was in particular developed for designers and artists. Because of its clear structure, it is quite accessible to the ones with no or only little programming skills. Beginners are able to write their own programmes after only a few minutes of instructions. This issue »3D type« builds on the codes of the issue »evolving type« and introduces how to create letter shapes that are formed of threedimensional interactive elements. Applications and codes can be viewed and copied from www.StefanieSchwarz-GraphicDesign.de/interactive-type.html
step 1 / designing grid-based letter forms In order to make it easier, to define the coordinates of the interactive elements, that will form the letters, a grid is set up suggesting the element’s positions.
step 2 / coding grid-based letters To translate the grid-letters to codes, first the ellipse() function is used, which will later be replaced by a more complex and interactive element. The first two parameters set the location of the ellipse, the third and forth set the width and the height.
size (300, 700); background(255); fill(0); noStroke(); // declare variable for diameter int d = 24; // build letter I ellipse(72, 113, d, d); ellipse(132, 113, d, d); ellipse(192, 113, d, d); ellipse(132, 193, d, d); ellipse(132, 270, d, d); ellipse(132, 350, d, d); ellipse(132, 429, d, d); ellipse(132, 507, d, d); ellipse(72, 586, d, d); ellipse(132, 586, d, d); ellipse(192, 586, d, d);
step 3 / coding a 3D element The following example shows how to create an element that goes in the third-dimension. The 2D coordinate system, defined by x- and y-values, is extended by z-coordinates that represent the values for depth and thus add volume to a form. Therefore the size() function, that sets the size of the display window, is added by a third parameter, named P3D, which is a renderer that enables to draw 3D shapes. The code uses the cosine and sinus function, cos() and sin(), in relation to the radius in order to draw a 3D spiral. The rotate functions, rotateY and rotateX, enables to look at the shape from different perspectives and is influenced by the position of the mouse.
void setup() { size(1000, 700, P3D); } void draw() { background(255); int radius = 100; // size of spiral // define spiral‘s position translate(width/2, height/2, 0); rotateY(mouseX * 0.005); rotateX(mouseY * 0.005); float float float float float
s = 0; t = 0; lastx = 0; lasty = 0; lastz = 0;
while (t < 180) { s += 18; t += 1; // convert angles to radians float radianS=radians(s); float radianT=radians(t);
â&#x2030;Ľ
float thisx = 0 + (radius * cos(radianS) * sin(radianT)); float thisy = 0 + (radius * cos(radianS) * sin(radianT)); float thisz = 0 + (radius * cos(radianT)); // draw and connect points if (lastx != 0) { // != means not equal to line(thisx, thisy, thisz, lastx, lasty, lastz); } lastx = thisx; lasty = thisy; lastz = thisz; } }
step 4 / adding randomness In order to make the 3D element look more complex and voluminous the random() function is added to the cosine and sinus function that describe the spiral.
void setup() { size(1000, 700, P3D); // stroke colour, 2nd number for transparency stroke(0, 50); } void draw() { background(255); int radius = 120; // size of spiral translate(500, 300, 0); // spiralâ&#x20AC;&#x2DC;s position rotateY(mouseY*0.006); rotateX(mouseX*0.008); float float float float float
s = 0; t = 0; lastx = 0; lasty = 0; lastz = 0;
while (t < 500) { // define density of strokes s += 25; t += 0.4; // convert angles to radians float radianS=radians(s);
â&#x2030;Ľ
float radianT=radians(t); // add random values to define spiral float thisx = 0 + (radius * cos(radianS) * sin(radianT) + random(50)); float thisy = 0 + (radius * cos(radianS) * sin(radianS) + random(50)); float thisz = 0 + (radius * cos(radianT) + random(20)); // draw and connect points if (lastx != 0) { strokeWeight(1); line(thisx, thisy, thisz, lastx, lasty, lastz); strokeWeight(2); point (thisx, thisy, thisz); } lastx = thisx; lasty = thisy; lastz = thisz; } }
step 5 / coding a 3D letter The positions defined in step 2, with a static ellipse, are now used for placing the 3D spiral in order to form a letter. To simplify the code, the spiral is defined as a function, named drawSpiral, that can be run many times within the programme. Another simplification is achieved by using the translate() function that defines a position relative to the previous one, instead of referring to the 0,0 coordinate each time.
void setup() { size (1300, 745, P3D); stroke(0, 50); } void draw() { background(255); // draw letter I translate(550, 100); drawSpiral(); translate(0, 78); drawSpiral(); translate(0, 78); drawSpiral(); translate(0, 78); drawSpiral(); translate(0, 78); drawSpiral(); translate(0, 78); drawSpiral(); translate(0, 78);
â&#x2030;Ľ
drawSpiral(); translate(-62, 0); drawSpiral(); translate(124, 0); drawSpiral(); translate(0, -468); drawSpiral(); translate(-124, 0); drawSpiral(); } void drawSpiral() { int radius = 60; rotateY(mouseY*0.0005); rotateX(mouseX*0.0001); float float float float float
s = 0; t = 0; lastx = 0; lasty = 0; lastz = 0;
while (t < 500) { s += 25; t += 0.4;
â&#x2030;Ľ
float radianS=radians(s); float radianT=radians(t); float thisx = 0 + (radius * cos(radianS) * sin(radianT) + random(50)); float thisy = 0 + (radius * cos(radianS) * sin(radianS) + random(50)); float thisz = 0 + (radius * cos(radianT) + random(20)); if (lastx != 0) { strokeWeight(1); line(thisx, thisy, thisz, lastx, lasty, lastz); strokeWeight(2); point (thisx, thisy, thisz); } lastx = thisx; lasty = thisy; lastz = thisz; } }
references Reas, C. & Fry, B. (2007) Processing: a programming handbook for visual designers and artists. Cambridge: MIT Press. Pearson, M. (2011) Generative art: a practical guide using Processing. Shelter Island: Manning Publications. www.processing.org concept and design Stefanie Schwarz www.stefanieschwarz-graphicdesign.de Central Saint Martins College of Arts and Design London, June 2012