I really like the style of this project. Gustavo Henrique, a 3D Artist, motion designer, and art director, creates many different small 3D models that are usually buildings and often “toy-like”. The color and texture of the 3D models make the images more believable and they feel more like real toys or blocks. I believe that this work was probably created in some 3D computer modeling software such as Blender, Maya, or Autodesk Fusion. These programs allow you to make 3D objects on the computer and then render them with different textures, materials, lighting, and camera angles. I think the creator’s love for muted and soft colors as well as his love for miniature forms really show in these works. As well, his minimalist style really shows in these works.
Author: Janet Peng
Janet Peng Project 05 –Wallpaper
var type;
var color;
var bigness;
function setup() {
createCanvas(600, 480);
background('#BFDDDA');
noStroke();
}
function draw() {
for (var c = 0; c < 12; c ++) {
for (var r = 0; r < 8; r ++) {
type = random([1, 2, 3]);
color = random(['#92B2C0', '#79A594', '#467E9B'])
bigness = random(20, 80)
pattern (c * 60, r * 70, bigness, type, color);
}
}
for (var col = 0; col < 8; col ++) {
for (var row = 0; row < 6; row ++) {
// draw grapes
var wide = random(7, 12);
var high = random(10, 14);
if (((col + row) % 2) === 0){
grapes(col * 85, row * 90, wide, high, '#FF5061');
} else {
grapes(col * 85, row * 90, wide, high, '#FF6A4D');
}
}
}
noLoop();
}
function grapes(x, y, h, w, color) {
// leaf and stem
fill('#4B4F4E');
push();
translate(x + w / 2, y - h * 1.5)
rotate(radians(15));
rect(0, 0, h / 3, w / 1.5);
pop();
fill('#F7CD62');
push();
translate(x, y - h)
rotate(radians(300));
ellipse(0, 0, h / 1.5, w);
pop();
// grape
fill(color);
for (var i = 0; i < 4; i++) {
// first and third row
if ((i === 0) || (i === 2)){
for (var j = 0; j < 2; j++) {
ellipse(x + w * j, y + h * i, w, h);
}
} else if (i === 1) {
for (var j = 0; j < 3; j++) {
ellipse(x + w * (j - 0.5), y + h * i, w, h);
}
} else {
ellipse(x + w * 0.5, y + h * i, w, h);
}
}
}
function pattern(x, y, s, type, color) {
fill(color);
// oval
if (type === 1) {
ellipse(x, y, s * 1.3, s);
// arc
} else if (type === 2) {
arc(x, y, s * 2, s, QUARTER_PI, PI + QUARTER_PI, CHORD);
// other arc
} else {
arc(x, y, s, s, PI + QUARTER_PI, PI * 2 + QUARTER_PI, CHORD);
}
}
I started by thinking of a theme. I decided I wanted to do fruit and make it feel playful. Then I came up with some ideas for foreground designs and some abstract shapes for background designs. When making the fruit, the raspberries looked like grapes so I made them grapes instead.
Janet Peng-LookingOutwards-04
The project Sorting by Ren Yuan provides an innovative intersection between sound, visualization, and algorithmic thinking. The project represents different sorting algorithms using both visuals and sounds. These pair well together to increase the appeal of the sorting algorithm. As well, it makes sorting seem very technical and complicated. I really like this project because it uses sound in a way I never expected. Sorting seems very far detached from the world of “Art and Music” so I found it surprising that this project merged the two. I believe there are three animations representing the sorting in progress. As well, I believe the sounds represent different parts in the sorting process. For example, the short beep-y sounds probably represent a comparison between two numbers being made the long swooping sound probably represents that the sorting has been completed. Using the sorting algorithm of choice, these visuals and sounds are probably mapped to different steps as the computer loops through the algorithm. It’s clear that the creator is from a more technical field because of the way the visuals and sounds end up being represented. I believe they do not represent sorting in a way that can be understood by someone without prior exposure. Therefore, the creator might have designed this with a specific audience in mind.
Janet Peng Project 04 – String Art
function setup() {
createCanvas(400, 300);
}
function draw() {
// outer curves
drawCurve(0, 0, 0, 200, 12, 6, 40, 'upRight', monochromeColor());
drawCurve(width, 0, width, 200, 10, 5, 60, 'upLeft', monochromeColor());
drawCurve(width, 100, width, height, 8, 4, 60, 'downLeft', monochromeColor());
drawCurve(0, 100, 0, height, 6, 3, 80, 'downRight', monochromeColor());
// inner curves
drawCurve(80, 80,
80, height / 2,
10, 6, 13, 'upRight', monochromeColor());
drawCurve(width - 80, 80,
width - 80, height / 2,
8, 5, 15, 'upLeft', monochromeColor());
drawCurve(width - 80, height / 2,
width - 80, height - 80,
6, 4, 19, 'downLeft', monochromeColor());
drawCurve(80, height / 2, 80,
height - 80, 5,
3, 24, 'downRight', monochromeColor());
// curves in the middle
drawCurve(width / 2, 0, width / 2, height, 20, 10, 40, 'upRight', monochromeColor());
drawCurve(width / 2, 0, width / 2, height, 20, 10, 40, 'upLeft', monochromeColor());
drawCurve(width / 2, 0, width / 2, height, 20, 10, 40, 'downLeft', monochromeColor());
drawCurve(width / 2, 0, width / 2, height, 20, 10, 40, 'downRight', monochromeColor());
noLoop();
}
function monochromeColor(){
return color(255, random(120, 200), random(120, 200))
}
// larger xstep = larger width
// larger ystep = larger height
function drawCurve(x1, y1, x2, y2, xstep, ystep, numOfLines, direction, color){
var i = 0
for (i = 0; i < numOfLines; i ++){
stroke(color);
line(x1, y1, x2, y2);
if (direction === 'downRight'){
// x1 stays the same, y1 increases
// y2 stays the same, x2 increases
y1 += ystep;
x2 += xstep;
} else if (direction === 'upRight'){
y2 -= ystep;
x1 += xstep;
} else if (direction === 'downLeft'){
y1 += ystep;
x2 -= xstep;
} else if (direction === 'upLeft'){
y2 -= ystep
x1 -= xstep
}
}
}
I started by experimenting with curves and how controlling what and how much I added and subtracted from affected the curve (its direction, density, width, height, etc.). This led me to writing a function to draw a curve given different parameters (x1, y1, x2, y2, xstep, ystep, number of lines, direction, color). Finally, I sketched out some curve designs and recreated it using the function I wrote.
Janet Peng-LookingOutwards-03
The Vespers project by Neri Oxman and The Mediated Matter Group at MIT created in 2016 feature three sets of five masks each. These masks represent the death masks used in the ancient times to protect spirits traveling to the afterlife. Each set has a theme, past, present, and future. The masks featured in Vespers take a new spin on this old artifact as they are 3D printed and generated computationally from data. This is one of the reasons I really like the project; I like how it takes a new concept and makes it feel new and enjoyable to for a modern audience. I also really enjoy the natural and complex form the masks take on. They’re unlike anything I’ve every seen but I feel like I can understand the emotion behind them and can see their relationship to death. The death masks are “entirely-data driven” and “digitally generated”. They rely heavily on algorithms that generate geometries and colors. I think the algorithms and data are based on cellular growth as the geometries in the masks look naturally generated. The creator’s artistic sensibilities manifest in the unique use of a data set in order to produce a historical artifact.
Janet Peng Project 03 – Dynamic Drawing
function setup() {
createCanvas(640, 480);
}
function draw() {
background(158, 189, 204);
// makes the ellipse size depend on the position of the mouse
var w = mouseX / 5;
var h = mouseY / 5;
// makes blue of ellipse depend on mouseX and be at least 140
// makes red of ellipse depend on mouseY and be at least 180
var colorX = mouseX / 10 + 140;
var colorY = mouseY / 5 + 180;
// square rotation depends on mouseX, rows alternate between
// clockwise and counter clockwise
var cwR = mouseX / 5;
var ccwR = 360 - mouseX / 5;
// square sides are at least 50 and depend on mouseY
var squareSide = 50 + mouseY / 10;
var squareMove = mouseX / 10 - 60
// squares
fill(255);
stroke(255);
// row 1
push();
rectMode(CENTER);
translate(160 + squareMove, 120);
rotate(radians(cwR));
rect(0, 0, squareSide, squareSide);
pop();
push();
rectMode(CENTER);
translate(320 + squareMove, 120);
rotate(radians(ccwR));
rect(0, 0, squareSide, squareSide);
pop();
push();
rectMode(CENTER);
translate(480 + squareMove, 120);
rotate(radians(ccwR));
rect(0, 0, squareSide, squareSide);
pop();
// row 2
push();
rectMode(CENTER);
translate(160 - squareMove, 240);
rotate(radians(ccwR));
rect(0, 0, squareSide, squareSide);
pop();
push();
rectMode(CENTER);
translate(320 - squareMove, 240);
rotate(radians(cwR));
rect(0, 0, squareSide, squareSide);
pop();
push();
rectMode(CENTER);
translate(480 - squareMove, 240);
rotate(radians(ccwR));
rect(0, 0, squareSide, squareSide);
pop();
// row 3
push();
rectMode(CENTER);
translate(160 + squareMove, 360);
rotate(radians(cwR));
rect(0, 0, squareSide, squareSide);
pop();
push();
rectMode(CENTER);
translate(320 + squareMove, 360);
rotate(radians(ccwR));
rect(0, 0, squareSide, squareSide);
pop();
push();
rectMode(CENTER);
translate(480 + squareMove, 360);
rotate(radians(ccwR));
rect(0, 0, squareSide, squareSide);
pop();
// ellipse colors
fill(colorY, 240, colorX);
stroke(colorY, 240, colorX);
// ellipses
// row 1
ellipse(64, 0, h, w);
ellipse(192, 0, h, w);
ellipse(320, 0, h, w);
ellipse(448, 0, h, w);
ellipse(576, 0, h, w);
// row 2
ellipse(0, 120, w, h);
ellipse(128, 120, w, h);
ellipse(256, 120, w, h);
ellipse(384, 120, w, h);
ellipse(512, 120, w, h);
ellipse(640, 120, w, h);
// row 3
ellipse(64, 240, h, w);
ellipse(192, 240, h, w);
ellipse(320, 240, h, w);
ellipse(448, 240, h, w);
ellipse(576, 240, h, w);
// row 4
ellipse(0, 360, w, h);
ellipse(128, 360, w, h);
ellipse(256, 360, w, h);
ellipse(384, 360, w, h);
ellipse(512, 360, w, h);
ellipse(640, 360, w, h);
// row 5
ellipse(64, 480, h, w);
ellipse(192, 480, h, w);
ellipse(320, 480, h, w);
ellipse(448, 480, h, w);
ellipse(576, 480, h, w);
}
I wanted to capture a few common movements with my dynamic drawing (rotation, translation, growth/shrinking, color change). I also wanted to create a repetitive pattern that changed depending on what row it was in. My initial inspirations were a pattern with dots.
Janet Peng-Looking Outwards-02
Flight Patterns from Aaron Koblin on Vimeo.
This project is called Flight Patterns and it’s by Aaron Koblin. I believe it was created in 2009 (10 years ago). The piece visualizes the movement of airplanes over North America over time. I really appreciate the simplicity of the piece and how it affectively visualizes important data without being confusing or overwhelming. As well, even though it’s just data, it’s beautiful and mesmerizing to stare at. It creates a strong emotional reaction for me as I can feel myself traveling from place to place on a plane when looking at the piece. It reminds me of the airport and how it feels to go someplace new and return home afterwards. The piece was created by parsing and plotting data from the Federal Aviation Administration using Processing, a Javascript web application framework. The creator’s artistic sensibilities manifest in the algorithm by being able to simplify and visualize large groups of data in a way that can be effectively coded in a visual manner.
Janet Peng Project 02 – Variable Face
var faceWidth = 120;
var faceHeight = 100;
var earRotation = 20;
var eyeSize = 10;
var cheekSize = 10;
var r = 244;
var g = 235;
var b = 130;
function setup() {
createCanvas(480, 640);
}
function draw() {
background (255, 255, 220);
// face
fill(r, g, b);
stroke(r, g, b);
ellipse(width / 2, height / 2, faceWidth, faceHeight);
// right ear
push();
translate(width / 2 + faceWidth / 3, height / 2 - faceHeight / 2);
rotate(radians(earRotation));
fill(r, g, b);
stroke(r, g, b);
ellipse(0, 0, 20, 70)
fill(60);
stroke(60);
arc(0, 0, 20, 70, PI + 1.2, 2 * PI - 1.2, OPEN)
pop();
// left ear
push();
translate(width / 2 - faceWidth / 3, height / 2 - faceHeight / 2);
rotate(radians(-earRotation));
fill(r, g, b);
stroke(r, g, b);
ellipse(0, 0, 20, 70)
fill(60);
stroke(60);
arc(0, 0, 20, 70, PI + 1.2, 2 * PI - 1.2, OPEN)
pop();
// eyes
fill(60);
stroke(60);
ellipse(width / 2 - faceWidth / 4, height / 2, eyeSize, eyeSize)
ellipse(width / 2 + faceWidth / 4, height / 2, eyeSize, eyeSize)
// nose
fill(60);
stroke(60);
triangle(width / 2 - faceWidth / 35, height / 2 + faceHeight / 20,
width / 2 + faceWidth / 35, height / 2 + faceHeight / 20,
width / 2, height / 2 + faceHeight / 12,);
// cheeks
fill(247, 98, 52);
stroke(247, 98, 52);
ellipse(width / 2 - faceWidth / 2.8, height / 2 + faceHeight / 6, cheekSize, cheekSize)
ellipse(width / 2 + faceWidth / 2.8, height / 2 + faceHeight / 6, cheekSize, cheekSize)
// hat
fill(58, 53, 50);
stroke(58, 53, 50);
arc(width / 2, height / 2 - faceHeight / 2.3, 45, 40, PI, 0);
ellipse(width / 2, height / 2 - faceHeight / 1.6, 6, 4);
fill(84, 79, 74);
stroke(84, 79, 74);
ellipse(width / 2, height / 2 - faceHeight / 2.3, 40, 10);
}
function mousePressed() {
// on click variables are randomly reassigned
faceWidth = random(100, 150);
faceHeight = random(100, 120);
earRotation = random (5, 60);
eyeSize = random(5, 20);
cheekSize = random(5, 20);
r = random (230, 255);
g = random (215, 235);
b = random (110, 130);
}
Janet Peng – Looking Outwards – 01
Play Work Build is an exhibit in The National Building Museum in Washington, DC. The exhibit is about the history of construction and block-based toys. It includes the Imagination Playground; a very unique way children can interact with (and destroy) building blocks (by standing and moving in front of a screen). I find this project inspiring because it revolutionizes the idea of playing this block which is a very old-school and non-techy-y activity. This project reinvents the toy and makes something that could be seen as boring seem interesting. I believe this project required the team at the rockwellgroup to write custom scripts that allows the projection to randomly generate block forms depending on the size and position of the person interacting with the projection. The creators were probably inspired by other interactive exhibit designs that use motion tracking to turn gestures into visual experiences.
Janet Peng Project 01 – Face
var verCenter = 300
function setup() {
createCanvas(500, 500);
}
function draw() {
// background
// bush
fill(86, 137, 124);
stroke(86, 137, 124);
ellipse(280, 390, 380, 250)
ellipse(80, 390, 200, 150)
ellipse(450, 400, 200, 200)
// ground
fill(73, 104, 96);
stroke(73, 104, 96);
rect(0, 400, 500, 100);
// hair (behind)
fill(51, 119, 135);
stroke(51, 119, 135);
ellipse(253, 230, 70, 90);
// legs
fill(51, 119, 135);
stroke(51, 119, 135);
quad(190, 340, 250, 340, 240, 430, 185, 430);
quad(245, 340, 310, 340, 315, 430, 260, 430);
// arms
push();
fill(174, 214, 175);
stroke(174, 214, 175);
translate(300, 290);
rotate(radians(-32));
ellipse(0, 0, 40, 90);
pop();
push();
fill(174, 214, 175);
stroke(174, 214, 175);
translate(200, 290);
rotate(radians(32));
ellipse(0, 0, 40, 90);
pop();
// body
fill(86, 178, 156);
stroke(86, 178, 156);
arc(250, 330, 120, 175, PI, 0);
push();
fill(86, 178, 156);
stroke(86, 178, 156);
translate(220, 330)
rotate(radians(20))
ellipse(0, 0, 60, 70);
pop();
push();
fill(86, 178, 156);
stroke(86, 178, 156);
translate(278, 330)
rotate(radians(-5))
ellipse(0, 0, 65, 75);
pop();
push();
fill(86, 178, 156);
stroke(86, 178, 156);
translate(250, 345)
rotate(radians(15))
ellipse(0, 0, 40, 20);
pop();
// head
fill(174, 214, 175);
stroke(174, 214, 175);
ellipse(250, 200, 80, 90);
ellipse(250, 240, 30, 30);
// hair (top)
push();
fill(51, 119, 135);
stroke(51, 119, 135);
translate(227, 170)
rotate(radians(-45))
ellipse(0, 0, 50, 25);
pop();
push();
fill(51, 119, 135);
stroke(51, 119, 135);
translate(268, 175)
rotate(radians(50))
ellipse(0, 0, 55, 35);
pop();
fill(51, 119, 135);
stroke(51, 119, 135);
ellipse(248, 158, 45, 20);
fill(51, 119, 135);
stroke(51, 119, 135);
ellipse(282, 198, 20, 45);
// glasses
fill(174, 214, 175);
stroke(65);
rect(212, 198, 20, 15);
rect(248, 198, 20, 15);
line(232, 203, 248, 203);
// eyes
fill(65);
stroke(65);
ellipse(218, 205, 5, 5);
ellipse(255, 205, 5, 5);
// eyebrows
fill(65);
stroke(65);
triangle(220, 200, 215, 201, 223, 201);
triangle(257, 200, 252, 201, 260, 201);
// mouth
fill(174, 214, 175);
stroke(65);
arc(240, 220, 10, 5, 0, 2, OPEN);
}