lemonbear-MolnarRecode

Molnar “Searching for Paul Klee” Observations:

  1. The piece is a grid of many squares
  2. The squares have different things happening inside of them
  3. Sometimes there are sub-rectangles, sub-squares, or sub-triangles within these squares, but never any other subdivisions
  4. There are only diagonal lines drawn with differing densities
  5. These diagonal lines are oriented in different directions
  6. There are also implied curves due to the fact that some of these diagonal lines will vary angles within a subspace
  7. Nearly all of the time there are 2 sub rectangles at differing orientations within a cell
  8. However, there are also (not… infrequently) triangles composing half a rectangle (these also often come in pairs).
  9. There are sometimes other triangles, like those which occupy half a square and those which are a fourth of the square, but in a different orientation
  10. Often, these half-rectangle triangles meet in the middle. I didn’t code this super well

I made the actual SVG way too big (~20 MB) to upload to WordPress, so here is the link to download it from Drive.

Here is an (almost) full pixel screenshot:

Here is a close up pixel screenshot:

I actually probably spent more time on this than my line walk (oops). I found it to be a really engaging exercise! I only wrote about 6 observations before getting bored and starting the code, and during the programming process I made way more minute observations than I did while just looking at it (my ten listed observations don’t encapsulate the full extent of everything I observed and implemented). Here is my code:

// Uses https://github.com/zenozeng/p5.js-svg to export SVG.
// noprotect
function setup() {
  createCanvas(816*4, 1056*4, SVG); 
  noLoop(); 
}

function makeSubsection(x1, y1, pixelDim, rot, type) {
  var x2 = 0;
  var y2 = 0;
  if (rot == 0) {
    //top
    x2 = x1 + pixelDim;
    y2 = y1 + pixelDim/2;
  }
  else if (rot == 1) {
    //bottom
    x2 = x1 + pixelDim;
    y1 += pixelDim/2;
    y2 = y1 + pixelDim/2;

  }
  else if (rot == 2) {
    //left
    x2 = x1 + pixelDim/2;
    y2 = y1 + pixelDim;
  }
  else if (rot == 3) {
    //right
    x1 += pixelDim/2;
    x2 = x1 + pixelDim/2;
    y2 = y1 + pixelDim;
  }
  var density = Math.floor(Math.pow(Math.random(), 1) * 12);
  var xMargin = (x2-x1+1)/density;
  var yMargin = (y2-y1+1)/density;
  if (type < .75) { //half rectangle
    var direction = Math.floor(Math.random()*2);
    // console.log(rot);
    // console.log(x1, y1, x2, y2);
    if (direction == 0) {
      for (var i = x1; i < x2; i+=xMargin) {
        for (var j = y1; j < y2; j+=yMargin) { line(i, j, i+xMargin, j+yMargin); } } } else { for (var i = x2; i > x1; i-=xMargin) {
        for (var j = y1; j < y2; j+=yMargin) {
          line(i, j, i-xMargin, j+yMargin);
        }
      }
    }
    if (rot == 3 && Math.random() < 0.1) {
      x1 -= pixelDim/2;
      y2 -= pixelDim/2;
      xMargin = (x2-x1+1)/density;
      yMargin = (y2-y1+1)/density;
      for (var n = 0; n < density; n++) {
        line(x1+n*xMargin, y1, x2-pixelDim/2, y1+(n+1)*yMargin)
      }
      x1 += pixelDim/2;
      x2 += pixelDim/2;
      for (var n = 0; n < density; n++) {
        line(x1+n*xMargin, y2, x2-pixelDim/2, y1+(n-1)*yMargin)
      }
    }
  }
  else if (type < .9) { //half triangle in half rectangle 
    var direction = Math.floor(Math.random()*4);
    if (direction == 0) {
      for (var n = 0; n < density; n++) {
        //upper-right
        line(x1+n*xMargin, y1, x2, y2-n*yMargin);
      }
    }
    else if (direction == 1) {
      for (var n = 0; n < density; n++) {
        //lower-right
        line(x1+n*xMargin, y2, x2, y1+n*yMargin);
      }
    }
    else if (direction == 2) {
      for (var n = 0; n < density; n++) {
        //lower-left
        line(x1, y1+n*yMargin, x2-n*xMargin, y2);
      }
    }
    else if (direction == 3) {
      for (var n = 0; n < density; n++) {
        //upper-left
        line(x2-n*xMargin, y1, x1, y2-n*yMargin);
      }
    }
  }
  else if (type < 1) {
    if (rot == 0) {
      for (var n = 0; n < density; n++) {
        //top
        line(x1+n*xMargin, y1, x2-pixelDim/2+n*xMargin/2, y2-n*yMargin);
      }
    }
    else if (rot == 1) {
      for (var n = 0; n < density; n++) {
        //bottom
        line(x1+n*xMargin, y2, x2-pixelDim/2+n*xMargin/2, y1+n*yMargin);
      }
    }
    else if (rot == 2) {
      for (var n = 0; n < density; n++) {
        //left
        line(x1, y1+n*yMargin, x2-n*xMargin, y2-pixelDim/2+n*yMargin/2);
      }
    }
    else if (rot == 3) {
      for (var n = 0; n < density; n++) {
        //right
        line(x2, y1+n*yMargin, x1+n*xMargin, y2-pixelDim/2+n*yMargin/2);
      }
    }  
  }
}

function draw() {

  var squaresWide = 8.5*4;
  var squaresHigh = 11*4;
  
  var pixelDim = width/squaresWide;

  for (var x = 0; x < squaresHigh; x++) {
    for (var y = 0; y < squaresWide; y++) {
      var rot1 = Math.floor(Math.random() * 4);
      var rot2 = (rot1 + Math.floor(Math.random() * 3) + 1)%4;
      console.log(rot1, rot2);
      var type = (Math.random());
      makeSubsection(x*pixelDim, y*pixelDim, pixelDim, rot1, type);
      makeSubsection(x*pixelDim, y*pixelDim, pixelDim, rot2, type);
      
    }
  } 
  // saveSVG("molnar_redraw_v3.svg");
}

lsh-MolnarRecode

1. Some of the lines are orthogonal to each other.
2. Some of the lines make a triangle filling half of the cell.
3. Some lines seem to be darker than the others.
4. Some of the patterns seem to have the same “scale” but less distance between lines.
5. There seems to be multiple scales of grids interacting.
6. Some cells overlap creating a cross hatch.
7. Some angles made a “wide” diamond, while others make a “tall” diamond.
8. Several of the interactions near the center almost form a curve.
9. The largest shape seems to be “16” small blocks (4 big blocks) in the top left corner.
10. It “feels” like there is more void than line.


I think I spent too much time working at a small scale in this work. In the end I don’t feel like I captured the general feel because I focused on little segments. I also spent a lot of time fighting with texturesjs, which was probably time I should have spent in a tool with which I was more familiar. Overall this drawing feels too heavy and I don’t think I captured the angles or interactions all that well.

const width = 761;
const height = width;

function generateRandomNumbers({ num_squares, N }) {
  const m = new Map();
  const out = [];
  while (out.length  d[0]))
  .range([0, width]);
const sy = d3
  .scaleBand()
  .domain(idx.map((d) => d[1]))
  .range([height, 0]);

const t1 = textures.lines().size(5).strokeWidth(1).orientation("2/8");
const t2 = textures.lines().size(5).strokeWidth(1).orientation("6/8");
const t3 = textures.lines().size(25).strokeWidth(1).orientation("7/8");
const t4 = textures.lines().size(25).strokeWidth(1).orientation("1/8");
const t5 = textures.lines().size(50).strokeWidth(1).orientation("5/8");
const t6 = textures.lines().size(50).strokeWidth(1).orientation("3/8");


function generate() {
  const svg = d3.create("svg").attr("width", width).attr("height", height);
  [t1, t2, t3, t4, t5, t6].forEach((t) => svg.call(t));

  svg.select(`pattern#${t4.id()}`).attr("patternTransform", "translate(3)");

  svg
    .selectAll(".rect38")
    .data(generateRandomNumbers({ num_squares, N: 500 }))
    .join("rect")
    .attr("fill", t1.url())
    .attr("x", ([x, _]) => sx(x))
    .attr("y", ([_, y]) => sy(y))
    .attr("width", sx.bandwidth())
    .attr("height", sy.bandwidth());

  svg
    .selectAll(".rect78")
    .data(generateRandomNumbers({ num_squares, N: 500 }))
    .join("rect")
    .attr("fill", t2.url())
    .attr("x", ([x, _]) => sx(x))
    .attr("y", ([_, y]) => sy(y))
    .attr("width", sx.bandwidth())
    .attr("height", sy.bandwidth());

  svg
    .selectAll(".rect2x")
    .data(generateRandomNumbers({ num_squares, N: 300 }))
    .join("rect")
    .attr("fill", t3.url())
    .attr("x", ([x, _]) => sx(x))
    .attr("y", ([_, y]) => sy(y))
    .attr("width", sx.bandwidth())
    .attr("height", sy.bandwidth());

  svg
    .selectAll(".rect22x")
    .data(generateRandomNumbers({ num_squares, N: 300 }))
    .join("rect")
    .attr("fill", t4.url())
    .attr("x", ([x, _]) => sx(x))
    .attr("y", ([_, y]) => sy(y))
    .attr("width", sx.bandwidth())
    .attr("height", sy.bandwidth());

  svg
    .selectAll(".rect4x")
    .data(generateRandomNumbers({ num_squares, N: 300 }))
    .join("rect")
    .attr("fill", t5.url())
    .attr("x", ([x, _]) => sx(x) * 2)
    .attr("y", ([_, y]) => sy(y) * 2)
    .attr("width", sx.bandwidth())
    .attr("height", sy.bandwidth());

  svg
    .selectAll(".rect4x2")
    .data(generateRandomNumbers({ num_squares, N: 300 }))
    .join("rect")
    .attr("fill", t6.url())
    .attr("x", ([x, _]) => sx(x) * 2)
    .attr("y", ([_, y]) => sy(y) * 2)
    .attr("width", sx.bandwidth())
    .attr("height", sy.bandwidth());

  return svg.node();
}

generate();

Krib – Drawing Machines

Drawing machine that is not useful.

[videopack id=”236″]https://courses.ideate.cmu.edu/60-428/f2021/wp-content/uploads/2021/09/Drawing-with-machine-1.mov[/videopack]

[videopack id=”238″]https://courses.ideate.cmu.edu/60-428/f2021/wp-content/uploads/2021/09/Drawing-with-machine-2.mov[/videopack]

Iteration #1

Iteration #2

Iteration #3