lass-reading01

  1. The Critical Engineer recognises that each work of engineering engineers its user, proportional to that user's dependency upon it. 

This tenet of The Critical Engineering Manifesto states that a critical engineer must note how engineering has the ability to "train" its user once the user begins to rely on it. I found this tenet to be interesting because it phrases our dependency on technology in a way that is new and almost frightening. It is true that we are engineered by works of engineering, even though we usually think of ourselves as the engineers. As engineers, it is important to have foresight about how the things we make will affect the user, and to pay attention to how we ourselves are affected by technology. This almost suggests through transitivity that we can engineer others with our work, which is a dangerous thought to have.

Examples of people being engineered by works of engineering are prevalent throughout our lives. Personally, I feel as though I am heavily engineered by my computer. I use it for work, communication, and entertainment among many other things. All of the things I can do on my computer affect the daily routine of my life. Checking emails, submitting assignments, and even making art depend so much on this work of engineering that I rely on.

dinkolas-Interruptions

Observations of Molnár's Interruptions

  1. Each line is centered on a lattice point of a grid
  2. Each line is rotated about its center
  3. Some lines are missing, mostly in clumps, not purely random
  4. The average rotation is vertical (or horizontal in one of them), and only some lines deviate very far from vertical
  5. The lines are arranged in a square with a side length of approximately 56
  6. The length of the lines is twice the distance between the centers of neighboring lines
  7. The amount that each line is rotated also appears to depend on location, with clumps of highly rotated lines and clumps of less rotated lines.
  8. The lines are black on a white background
  9. There is a blank margin approximately 2 to 3 lines long around the piece (and a date/number in the bottom left)
  10. The ratio of missing/present lines is small.

Re-code (Click!)

Process

I started out with the observations listed above, and then coded the first draft. For the randomness of the rotations, after only a few modifications, I got to where it is now, which includes a random normal distribution multiplied with Perlin noise. However, getting the placement and quantity of missing lines took several more modifications to get where it is now. It has multiple layers of scaled, added and multiplied noise, including a pure random input to make it rougher around the edges. I was surprised to learn how many layers of randomness and noise were required to get the look I wanted. It's hard to tell after looking at so many iterations, but I think there is a more natural quality to Molnár's Interruptions compared to my own; I would be curious to see the algorithm she used.

casher-IterationExercise

 

var boolDoRefresh;
 
function setup() {
  createCanvas(400, 400);
	background('white');
  boolDoRefresh = true;
}
 
function draw() {
  if (boolDoRefresh) {
		background('white');
		for (var x = 0; x <= width; x += 50) {
			for (var y = 0; y <= width; y+= 50) {
 
				var maybeACircle = int(random(0,10));
				strokeWeight(1.5);
				if (maybeACircle == 0) {
					fill('blue');
					ellipse(x+23, y+23, 45, 45);
				}
				else {
					fill('white');
					rect(x, y, 45, 45);
				}
			}
		}
    boolDoRefresh = false;
	}
}
 
function mousePressed() {
  boolDoRefresh = true;
}

ocannoli-IterationExercise

var boolDoRefresh;
 
function setup() {
  createCanvas(400, 400);
  boolDoRefresh = true;
}
 
function draw() {
  if (boolDoRefresh) {
		background(255,255,255);
    stroke(51);
		strokeWeight(4);
		var gridSize=8;
		for(var i=0, x=10;i<=gridSize;i++, x+=50){
			for(var k=0,y=10;k<=gridSize;k++,y+=50)
			{
				var r=random(3);
        if(r<0.3){
          ellipse(x+10,y+10,20,20);
        }
        else{
        rect(x,y,20,20);
        }
			}
		}
    boolDoRefresh = false;
  }
}
 
function mousePressed() {
  boolDoRefresh = true;
}

 

ocannoli-Reading01

In tenet four of the Critical Engineering Manifesto, its states that in order for one to be a critical engineer, one must consider implications of their work. Moreover, progressing technology or trying something just because one can is dangerous if the repercussions of one's actions are not considered beforehand. Especially in the areaing of fast technological advances, it is vital that a creator understand the impact that their programs, work, experiments, ideas, etc. can have on others and society as a whole. For example, this becomes essential during the discussion of A.I. when considering morality, impact on jobs, society, our laws etc. A critical engineer must understand and weigh the importance of the progress with the effects of the creations impact.

 

dinkolas-Intersections

Lines are stored in point-slope form, intersections are calculated with slope-intercept form, and points are calculated using the parametric form.

I used lots of information from the p5.js website's Reference section, and lots of my knowledge of intersections comes from the Khan Academy Pixar in a Box Rendering series.

var slider;
var lines;
var tstep;
var t;
var intersections
 
function setup() {
  createCanvas(720, 480);
  slider = createSlider(1,1000,10);
  slider.position(10, 10);
  t = 0;
  tstep = 2;
  angleMode(DEGREES);
  intersections = [];
  lines = []
  recalculate();
  stroke(255);
  strokeWeight(1)
  textSize(15);
}
 
function mouseReleased() {
  recalculate();
}
 
function recalculate() {
  background(255);
  t = 0;
  var m1,m2,b1,b2,x,y,a1,a2,t1,t2,line1,line2;
  lines = []
  intersections = []
  for (var i = 0; i < slider.value(); i += 1) {
    lines.push([random(720), random(480), tan(random(-89,89))])
  }
  for (var ln1 = 0; ln1 < lines.length - 1; ln1 += 1) {
    for (var ln2 = ln1+1; ln2 < lines.length; ln2 += 1) {
      line1 = lines[ln1];
      line2 = lines[ln2];
      m1 = line1[2];
      m2 = line2[2];
      b1 = line1[1]-m1*line1[0];
      b2 = line2[1]-m2*line2[0];
      x = (b2-b1)/(m1-m2);
      y = m1*x + b1;
      t1 = sqrt(pow(x-line1[0],2) + pow(y-line1[1],2));
      t2 = sqrt(pow(x-line2[0],2) + pow(y-line2[1],2));
      intersections.push([x,y,max(abs(t1),abs(t2))]);
    }
  }
}
 
function position(ln, T) {
  var a = 1 / sqrt(pow(ln[2],2)+1);
  var b = ln[0];
  var c = sqrt(1-pow(a,2)) * abs(ln[2])/ln[2];
  var d = ln[1];
  return [a*T + b, c*T + d];
}
 
function draw() {
  var p1, p2, intersection;
  t += 2;
  noStroke();
  fill(0);
  for (var i = 0; i < intersections.length; i += 1) {
    intersection = intersections[i]
    if (abs(t) - tstep < intersection[2] && intersection[2] <= abs(t)) {
      ellipse(intersection[0], intersection[1], 10, 10);
    }
  }
  stroke(240,30,50);
  for (var j = 0; j < lines.length; j += 1) {
    ln = lines[j]
    p1 = position(ln, t);
    p2 = position(ln, -t)
    line(p1[0], p1[1], p2[0], p2[1]);
  }
  noStroke();
  fill(0);
  rect(0,0,200,45);
  fill(255);
  text(slider.value(), 150, 27)
}

Spoon-IterationExcercise

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
// using starter code for "Embedded Iteration + Randomness"
var boolDoRefresh;
 
function setup() {
  createCanvas(625, 625);
  strokeWeight(5);
  boolDoRefresh = true;
}
 
function draw() {
  if(boolDoRefresh) {
    for(var x = 50; x < 625; x += 75) {
      for(var y = 50; y < 625; y += 75) {
        drawItemAtPosition(x, y);
      }
    }
    boolDoRefresh = false;
  }
}
 
function mousePressed() {
  boolDoRefresh = true;
}
 
function drawItemAtPosition(x, y) {
  //draws an item with a center on the position given.
  var drawYellow = random(255) > 235;
  if(drawYellow) fill('#FFC600');
  else fill('#FFFFFF');
  rect(x - 25, y - 25, 50, 50);
}

harsh-Intersections

// First, create each line
// 		- line is constrained in length, and saved as [x1,y1],[x2,y2]
//		- draw the line
// Second, for each line, run algorithm to find int point
//		- save point to point masterlist
//    - draw point masterlist
 
 
var boolDoRefresh;
var numLinesSlider;
var lineLengthSlider;
 
function setup() {
	createCanvas(720, 400);
	numLinesSlider = createSlider(0,50,10);
	numLinesSlider.position(20,20);
 
	lineLengthSlider = createSlider(0,400,200);
	lineLengthSlider.position(20,40);
	background(255);
	boolDoRefresh = true;
}
 
 
function draw() {
	if (boolDoRefresh) {
		background(204, 255, 204)
 
		var lines = [];
		var lineLength = lineLengthSlider.value();
		var numLines = numLinesSlider.value();
		text("Number of Lines = "+ numLines.toString(), 30 + numLinesSlider.width, 35);
		text("Line Length = "+ lineLength.toString(), 30 + lineLengthSlider.width, 55);
 
		for (var i = 0; i < numLines; i++) {
			var curLine = makeLine(lineLength);
			lines.push(curLine);
			push();
			stroke(102, 204, 255);
			strokeWeight(2);
			line(curLine[0][0], curLine[0][1], curLine[1][0], curLine[1][1]);
			pop();
		}
 
 
		var points = [];
		for (var j = 0; j < lines.length; j++) {
			for (var k = 0; k < lines.length; k++) {			
				if (j === k) {
					continue;
				}		
				else {
					var line1 = lines[j];
					var line2 = lines[k];
					var curPoint = findIntersection(line1, line2);		
					if (curPoint != false) {
						points.push(curPoint);
						push();
						noStroke();
						fill(255, 153, 0,50);
						ellipse(curPoint[0], curPoint[1], 20, 20);
						pop();
					} 
				}
			}
		}
 
		var numIntersections = points.length;
		text("Intersections: "+ numIntersections.toString(),625,380);
		boolDoRefresh = false;
	}		
}
 
function mousePressed() {
	boolDoRefresh = true;
}
 
function makeLine(length) {
	var x1 = random(length, width - length);
	var y1 = random(length, height - length);
	var randAngle = Math.round(random(0, 360));
	var xLength = Math.cos(randAngle) * length;
	var yLength = Math.sin(randAngle) * length;
	var x2 = x1 + xLength;
	var y2 = y1 + yLength;
	var curLine = [
		[x1, y1],
		[x2, y2]
	];
	return curLine;
}
 
 
function findIntersection(line1, line2) {
	// line intercept math by Paul Bourke http://paulbourke.net/geometry/pointlineplane/
	// Determine the intersection point of two line segments
 
	var x1 = line1[0][0]
	var y1 = line1[0][1]
	var x2 = line1[1][0]
	var y2 = line1[1][1]
 
	var x3 = line2[0][0]
	var y3 = line2[0][1]
	var x4 = line2[1][0]
	var y4 = line2[1][1]
 
	var denominator = ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1))
 
	if (denominator === 0) {
		return false;
	} 
 
		var ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator
		var ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denominator
 
		if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {
			return false;
		} 
 
			var x = x1 + ua * (x2 - x1)
			var y = y1 + ua * (y2 - y1)
			return [x, y];
}

harsh-IterationExercise

var boolDoRefresh;
 
function setup() {
  createCanvas(400, 400);
	background(255);
  boolDoRefresh = true;
}
 
function draw() {
	var border = 4;
	var numRects = 20;
	var gridWidth = width/numRects;
	var gridHeight = height/numRects;
	var numCircles = numRects;
 
	var rectGrid = [];
	var randomNums =[];
 
 
  if (boolDoRefresh) {
 
		background(255, 153, 153);
 
		for(var k=0; k<numCircles; k++){
			var newRandomNumX = Math.round(random(0,numRects));
			var newRandomNumY = Math.round(random(0,numRects));
			randomNums.push([newRandomNumX,newRandomNumY]);
		}		
		for(var i=0; i<numRects; i++){		
			for(var j=0; j<numRects; j++){
				var rowCol = [i,j];	
				var isCircle = false;
 
				for(var k=0; k<randomNums.length-1;k++){
					var curRandom = randomNums[k];					
					if(curRandom[0] == rowCol[0] && curRandom[1] == rowCol[1]){
						isCircle = true;
					}				
				}
 
				if(isCircle == false){
					push();
					noStroke();
					fill(255, 255, 153);
					rect(i*gridWidth+border,j*gridHeight+border,gridWidth-border*2,gridHeight-border*2);
					pop();
				}
 
				else{
					push();
					noStroke();
					fill(0, 102, 153);
					ellipse(i*gridWidth+gridWidth/2,j*gridHeight+gridWidth/2,gridWidth/2,gridHeight/2);
					pop();
				}
			}
		}
    boolDoRefresh = false;
	}
}
 
function mousePressed() {
  boolDoRefresh = true;
}

dinkolas-IterationExercise

var s = 15; //spacing
var d = 25; //diameter
var front; //colors
var back;
var shadow;
var drawBool;
 
function setup() {
  createCanvas(10 * d + 11 * s, 10 * d + 11 * s);
  front = color(245, 230, 240);
  back = color(200, 150, 160);
  shadow = color(150, 120, 140);
  drawBool = true;
}
 
function drawCircle(x, y) {
  noStroke()
  fill(shadow);
  ellipse(x, y, d, d);
  fill(back);
  ellipse(x - 5, y + 6, d, d);
  noFill()
  stroke(front)
  strokeWeight(10)
  ellipse(x, y, d + 10, d + 10);
}
 
function drawSquare(x, y) {
  noStroke()
  fill(shadow);
  rect(x, y, d, d);
  fill(back);
  rect(x - 9, y + 10, d, d);
  noFill()
  stroke(front)
  strokeWeight(16)
  rect(x - 3, y - 3, d + 6, d + 6);
}
 
function mousePressed() {
  drawBool = true;
}
 
function draw() {
  if (drawBool) {
    background(front);
    for (var i = 0; i < 10; i = i + 1) {
      for (var j = 0; j < 10; j = j + 1) {
        if (random(20) >= 1) {
          drawSquare(s + (d + s) * i, s + (d + s) * j);
        } else {
          drawCircle(s + d / 2 + (d + s) * i, s + d / 2 + (d + s) * j)
        }
      }
    }
    drawBool = false;
  }
}