dinkolas-LostrittoReading

The A computer cannot draw section is pretty interesting to me, because it offers a very confident ontology of drawings. The distinction that an image can be composed of parts, whereas a drawing necessitates comprehension by a viewer (and is thus never complete) is something I hadn’t thought to apply to drawings before. There  are many edge cases that muddle this distinction, and I’m sure that this quality could be intentionally defied by making “drawings” that are merely a means of computer to computer communication, but nonetheless we would hope to call real drawings. Ultimately I’m not as confident in this non-property as Lostritto. However, it is funny how the noun drawing has an ‘ing’ in it; maybe a drawing has always implicitly been a process, not an object.

dinkolas – MolnarRecode

I dunno if I’m crazy, but I think the p5 svg thing breaks the pop() function, so I learned how to invert my goddang transformations.

let dosvg = true;
const edgeRoom = 30;
const Wm = 12;
const Hm = 12;
const Lm = 40;
const Sw = dosvg ? 0.8 : 0.015;

function diags(d) {
  push();
  let dangus = randomHalf();
  
  for (let i = -d + 1; i < d; i++) {
    let x0 = constrain(map(i, 0, d, 0, 1), 0, 1);
    let x1 = constrain(map(i, 0, d, 1, 2), 0, 1);
    let y0 = constrain(map(i, -d, 0, 1, 0), 0, 1);
    let y1 = constrain(map(i, 0, d, 1, 0), 0, 1);
    if (isNaN(x0) || isNaN(x1) || isNaN(y0) || isNaN(y1)) console.log('dingus');
    strokeWeight(Sw);
    line(x0,y0,x1,y1);
  }
  unRandomHalf(dangus);
  pop();
}

function halfdiags(d) {
  push();
  let dangus = randomHalf();
  
  for (let i = 0; i < d; i++) {
    let x0 = constrain(map(i, 0, d, 0, 1), 0, 1);
    let x1 = constrain(map(i, 0, d, 1, 2), 0, 1);
    let y0 = constrain(map(i, -d, 0, 1, 0), 0, 1);
    let y1 = constrain(map(i, 0, d, 1, 0), 0, 1);
    if (isNaN(x0) || isNaN(x1) || isNaN(y0) || isNaN(y1)) console.log('dingus');
    strokeWeight(Sw);
    line(x0,y0,x1,y1);
    
  }
  unRandomHalf(dangus);
  pop();
}

function tri(d) {
  push();
  let dangus = randomHalf();
  
  for (let i = 0; i < d; i++) {
    let x0 = constrain(map(i, 0, d, 0, 1), 0, 1);
    let x1 = constrain(map(i, 0, d, 0.5, 1), 0, 1);
    let y0 = 0; //constrain(map(i, -d, 0, 1, 0), 0, 1);
    let y1 = constrain(map(i, 0, d, 1, 0), 0, 1);
    if (isNaN(x0) || isNaN(x1) || isNaN(y0) || isNaN(y1)) console.log('dingus');
    strokeWeight(Sw);
    line(x0,y0,x1,y1);
  }
  
  unRandomHalf(dangus);
  pop();
}

function f0() {
  diags(2);
}
function f1() {
  diags(5);
}
function f2() {
  diags(7);
}
function f3() {
  diags(11);
}

function f4() {
  halfdiags(2);
}
function f5() {
  halfdiags(5);
}
function f6() {
  halfdiags(7);
}
function f7() {
  halfdiags(11);
}

function f8() {
  halfdiags(1);
}

function f9() {
  tri(5);
}
function f10() {
  tri(7);
}

function f11() {
  diags(4);
}
function f12() {
  halfdiags(4);
}

function para(d) {
  push();
  let dangus = randomQuarter();
  
  for (let i = 1; i < d; i++) {
    let x0 = map(i, 0, d, 0, 1);
    let x1 = 1;
    let y0 = 0;
    let y1 = map(i, 0, d, 0, 1);
    if (isNaN(x0) || isNaN(x1) || isNaN(y0) || isNaN(y1)) console.log('dingus');
    strokeWeight(Sw);
    line(x0,y0,x1,y1);
  }
  
  unRandomQuarter(dangus);
  pop();
}

function f13() {
  para(3);
}
function f14() {
  para(5);
}

let sectionFunctions = [f0, f1, f1, f2, f2, f3, f4, f5, f5, f6, f6, f7, f8, f0, f1, f1, f2, f2, f3, f4, f5, f5, f6, f6, f7, f8, f9, f10, f11, f12, f0, f1, f1, f2, f2, f3, f4, f5, f5, f6, f6, f7, f8, f0, f1, f1, f2, f2, f3, f4, f5, f5, f6, f6, f7, f8, f9, f10, f11, f12, f13, f14];

function setup() {
  if (dosvg) createCanvas(2*edgeRoom + Wm*Lm, 2*edgeRoom + Hm*Lm, SVG);
  else createCanvas(2*edgeRoom + Wm*Lm, 2*edgeRoom + Hm*Lm);
  noLoop();
}

function draw() {
  drawVera();
  /*push();
  translate(10,100);
  scale(0.99,0.5);
  line(0,0,width,height);
  pop();*/
}

function drawVera() {
  //let bg = 240;
  //background(bg);
  clear();
  stroke(0);
  //strokeWeight(0.015);
  strokeWeight(Sw);
  noFill();
  for (let i = 0; i < Hm; i++) {
    for (let j = 0; j < Wm; j++) {
      /*line(edgeRoom + j*Lm, edgeRoom + i*Lm,
          edgeRoom + j*Lm + Lm*0.6, edgeRoom + i*Lm + Lm*0.8);*/
      push();
      translate(edgeRoom + j*Lm, edgeRoom + i*Lm);
      scale(Lm);
      //line(0,0,0.8,0.8);
      drawSection();
      
      scale(1/Lm);
      translate(-edgeRoom - j*Lm, -edgeRoom - i*Lm);
      pop();
    }
  }
  //fill(bg);
  //noStroke();
  //rect(0,0,edgeRoom,height);
  //rect(width - edgeRoom,0,edgeRoom,height);
}

function keyPressed() {
  saveSVG("vera.svg");
}

function drawSection() {
  //line(0, 0, 0.8, 0.8);
  let r = Math.random();
  let numSections = r < 0.02 ? 0 : r < 0.1 ? 1 : r < 0.8 ? 2 : 3;
  for (let s = 0; s < numSections; s++) {
    let i = Math.floor(Math.random() * sectionFunctions.length);
    let f = sectionFunctions[i];
    f();
  }
}

function randomHalf() {
  let vertical = Math.random() < 0.5 ? 1 : 0;
  let horizontal = 1 - vertical;
  let offset = Math.random() < 0.5 ? 1 : 0;
  let fh = Math.random() < 0.5; //flip horizontal
  let fv = Math.random() < 0.5; //flip vertical
  
  scale(1 - 0.5*vertical, 1 - 0.5*horizontal);
  translate(vertical * offset, horizontal * offset);
  if (fh) {
    scale(-1, 1);
    translate(-1, 0);
  }
  if (fv) {
    scale(1, -1);
    translate(0, -1);
  }
  
  return {vertical, horizontal, offset, fh, fv};
}

function unRandomHalf(dangus) {
  let {vertical, horizontal, offset, fh, fv} = dangus;
  
  if (fv) {
    translate(0, 1);
    scale(1, -1);
  }
  if (fh) {
    translate(1, 0);
    scale(-1, 1);
  }
  translate(-vertical * offset, -horizontal * offset);
  scale(1 / (1 - 0.5*vertical), 1 / (1 - 0.5*horizontal));
}

function randomQuarter() {
  let x = Math.random() < 0.5 ? 1 : 0;
  let y = Math.random() < 0.5 ? 1 : 0;
  let f1 = Math.random() < 0.5;
  let f2 = Math.random() < 0.5;
  
  scale(0.5,0.5);
  translate(x, y);
  if (f1) {
    scale(-1, 1);
    translate(-1, 0);
  }
  if (f2) {
    scale(1, -1);
    translate(0, -1);
  }
  
  return {x, y, f1, f2};
}

function unRandomQuarter(z) {
  let {x, y, f1, f2} = z;
  
  if (f2) {
    translate(0, 1);
    scale(1, -1);
  }
  if (f1) {
    translate(1, 0);
    scale(-1, 1);
  }
  translate(-x, -y);
  scale(2,2);
}

 

dinkolas – LineWalk

I wanted to try to do a random walk weighted to walk through an image. The line mostly retains its velocity from step to step, but slightly steers towards bright areas. To be honest, it’s not much different from a pure random walk, and I had hoped to have the walks resemble to images much more. I intend to work more on it to improve the results…

const dosvg = false;
let img;

function preload() {
  img = loadImage('elephant.jpg');
}

function setup() {
  createCanvas(img.width, img.height, SVG);
  noLoop();
  img.loadPixels();
}

function draw() {
  if (!dosvg) image(img, width/4, height/4, width/2,height/2);
  let pvs = [];
  //console.log(img);
  for (let i = 0; i < img.pixels.length; i+=4) {
    pvs.push(img.pixels[i]);
  }
  //console.log(pvs);
  let index = sampleList(pvs);
  let loc = getLoc(index);
  stroke(255,0,0);
  strokeWeight(10);
  //point(loc.x, loc.y);
  let r = 5;
  let circle_r = 30;
  let theta = 0;
  
  stroke(255, 0,0);
  strokeWeight(1);
  
  for (let i = 0; i < 5000; i++) { let circle = getCircle(loc, theta, circle_r); let weighted = weightList(circle, t => t /*4*(t-0.5)**2*/);
    let circleIndex = sampleList(weighted);
    //let circleIndex = maxIndex(weighted);
    let targetTheta = theta + map(circleIndex, 0, circle.length, 0, 2*PI);
    
    
    let diff = ((targetTheta - theta) % TWO_PI + TWO_PI) % TWO_PI;
    if (diff > PI) diff -= TWO_PI;
    theta = (theta + 0.2*diff) % TWO_PI;
    let newLoc = {x: loc.x + r * Math.cos(theta), y: loc.y + r * Math.sin(theta)};
    line(map(loc.x, 0, width, width*0.25, width*0.75),
         map(loc.y, 0, height, height*0.25, height*0.75), 
         map(newLoc.x, 0, width, width*0.25, width*0.75), 
         map(newLoc.y, 0, height, height*0.25, height*0.75));
    loc = newLoc;
  }
}

function maxIndex(l) {
  let m = -Infinity;
  let id = 0;
  for (let i = 0; i < l.length; i++) { if (l[i] > m) {
      m = l[i];
      id = i;
    }
  }
  return id;
}

function weightList(l, f) {
  let w = [];
  for (let i = 0; i < l.length; i++) {
    let t = map(i, 0, l.length - 1, 0, 1);
    w.push(l[i] * f(t));
  }
  return w;
}

function getCircle(loc, theta, r) {
  let vs = [];
  for (let i = 0; i < 32; i++) { let angle = theta + map(i, 0, 32, 0, 2*PI); let l = {x: loc.x + r * Math.cos(angle), y: loc.y + r * Math.sin(angle)}; let index = getIndex(l); if (index === -1) { vs.push(0); } else { vs.push(1 - (img.pixels[index] / 255.0)); } } return vs; } function getLoc(i) { return {x: i % img.width, y: Math.floor(i / img.width)}; } function getIndex(loc) { if (loc.x >= img.width || loc.y >= img.height ||
     loc.x < 0 || loc.y < 0) return -1;
  return Math.floor(loc.x) + img.width * Math.floor(loc.y);
}

function keyPressed() {
  saveSVG("dingus.svg");
}

function sampleList(l) {
  let v = l[0];
  if (v < 0) console.log('negative!!!');
  let cumsum = [v];
  let sum = v;
  for (let i = 1; i < l.length; i++) {
    let v = l[i];
    if (v < 0) console.log('negative!!!');
    sum += v;
    cumsum.push(sum);
  }
  let t = sum * Math.random();
  //TODO: binary search
  for (let i = 0; i < cumsum.length; i++) { if (cumsum[i] >= t) return i;
  }
  console.log('shouldnt hapen');
  return cumsum.length - 1;
}

 

dinkolas – PlotterTwitter

Plotter twitter is technically quite interesting, there’s lots of cool algorithms at play, interesting glitches with pens running out of ink, experiments with different media, etc. But for me the vast majority of the work was just that – technically interesting – nothing more. As art, maybe some of the pieces made me feel awe at the precision of the lines, or dread of the task of executing the drawings which is interesting because it implies an empathy for the machines, or just aesthetic enjoyment. But again, my reaction was mostly the same as how I react to reading clever code/algorithms.

Several works by Licia He showed up in the hashtag, and I appreciate the combination of the imprecise nature of watercolor with the precision of the machine. This is also reinforced by the titles of the works, which are sort of conversational and comforting.

dinkolas – Drawing Machine

Initially it was just a paper cylinder with a spinning marker.

[videopack id=”152″]https://courses.ideate.cmu.edu/60-428/f2021/wp-content/uploads/2021/09/IMG_0225.mov[/videopack]

The addition of more elaborate machinery, adding sheering motion to the cylinder, made the results worse.

[videopack id=”155″]https://courses.ideate.cmu.edu/60-428/f2021/wp-content/uploads/2021/09/IMG_0228.mov[/videopack]