ocannoli-LookingOutwards03.

Fragments of RGB is an interactive installation made by Onformative which experiments with the concept of human perception. In this work, projected light points on an LED screen react to the viewer of the work by changing the content as they approach. I find the concept and the commentary of the piece extremely interesting and intriguing to consider the relativity of the world based on our perceptions. Although the topic is large and broad, the execution of the piece is very elegant and communicates that idea subtly but clearly. I appreciated how the creator of the piece left the message they were trying to communicate not be simply stated but required to be discovered through interaction which I think makes the piece more powerful. However, I think the piece could have been stronger if there was something that indicated a bit clearer that the viewer was in the variable controlling the perspective changes but there is equally something to be said about elegant simplicity. Overall, I thought it was extremely inspiring how combing RGB values and having human influenced transformation of the perspective had not only an extremely beautiful result but also carried a lot of meaningful commentary.

ocannoli-viewing04

According to Warburton, spectacle refers to the type of art that tries new things in the realm of digital media more for the sake of commercial novelty rather than to address issues or discuss implications. Speculation refers to digital media that aims to address possibly some of the oblique areas spectacle art does not however it often is guilty of disregarding the impact of the practice.

As discussed in Friday's lecture about multi-user environments, the nVidia Holodeck project I believe is a spectacle type projects. Although the project utilizes new technology to discuss the how this interactivity is an important element they are advancing, the use of technology and new VR equipment feels novel for the sake of novelty. Essentially, not saying whether or not it was a good project, just simply addressing its commercialization and lack of content brings up a lot of material to talk about. Given these opinions there is definitely a quality of expertise, refinement, and skill that went into making this environment to the quality it is; however, the project seems to lack much depth in regards to discussing any topic along the lines of outsourced labor, supply chains or other gray areas that obviously were an important part of a project of this scale.  Therefore due to the projects innovation, skill, and lack of an overall discussion of theory of digital practice, this project leans more toward spectacle a

 

ocannoli-clock

Big Brother's Clock

Replacing Minutes with Seconds View:

Explanation:

From the beginning, I knew I wanted to experiment with time unconventionally because I love the relativity of time and how it is interpreted.  I began to mess around with the concept of taking time and making each minute into a year by adding the hours and minutes to create the decade in the 1900s. Although it is not an "accurate" representation of time, I liked that it furthered the idea of time's interpretive nature. Originally, I was thinking of sampling a song from a certain year and possibly using APIs to gain access to a variety of music. However, as I experimented with how to compute the year, I was fascinated that although there are technically 24 hours in a day and 60 minutes in a hour, the clock never reaches this technically real but not real time. Furthermore, when inserted into my formula of computing the year, this "ideal" year was 1984. I found that an extremely interested premise that time somewhat revolved around this number and subsequently considering that time revolved around the ideas about society and humanity within the novel. From here, my concept shifted from music to literature considering the significance of the book 1984. Although not complex in code, each book was picked to embody some of the morals shown in 1984.  Each book serves an important purpose and therefore the projection of time through these books is personal and biased based on my experiences. Overall, "Big Brother's Clock" was made through an exploration of the conceptual more than the visual or mathematical.

//The Clock of 1984
PImage bookBack;
int circleX, circleY;
int circleSize = 50;
color circleColor;
color currentColor;
boolean circleOver = false;
int visible; 
 
 
void setup() {
  size(800, 570);
  bookBack=loadImage("oldBook.jpg");
  circleColor = color(255);
  currentColor=color(209, 142,8);
  circleX = 180;
  circleY = 70;
  visible=-1; 
  ellipseMode(CENTER);
}
 
void draw() {
  image(bookBack,0,0);
 
  //All 83 Books
   String[] books = {"The Wonderful Wizard of Oz",
    "The First Men in the Moon",
    "Just So Stories",
    "The People of the Abyss",
    "The Tale of Peter Rabbit\nand Benjamin Bunny",
    "The Gift of the Magi",
    "The Future in America:\nA Search After Realities",
    "Cautionary Tales for Children",
    "The Man Who Was Thursday",
    "The Machine Stops",
    "Howards End",
    "The Secret Garden",
    "The Problems of Philosophy",
    "The Google Book",
    "The Beasts of Tarzan",
    "The Metamorphosis",
    "Relativity: The Special\nand the General Theory",
    "His Family",
    "The Decline of the West:\nPerspectives of world-history",
    "Strange News from Another Star",
    "The Age of Innocence",
    "How to Analyze\nPeople on Sight",
    "The Velveteen Rabbit",
    "The Ego and the Id",
    "So Big",
    "The Great Gatsby",
    "Winnie-the-Pooh",
    "Being and Time",
    "Nadja",
    "Is Sex Necessary? Or,\nWhy You Feel the Way You Do",
    "The Mysterious Universe",
    "The Story of Babar,\nthe Little Elephant",
    "Journey to the End\nof the Night",
    "Lord Edgware Dies",
    "The Logic of\nScientific Discovery",
    "It Can't Happen Here",
    "How to Win Friends\nand Influence People",
    "The Hobbit",
    "The Sword in the Stone",
    "The Secret Life\nof Walter Mitty",
    "Portrait of the\nArtist as a Young Dog",
    "The Garden of Forking Paths",
    "The Stranger",
    "The Little Prince",
    "What Is Life?",
    "Animal Farm",
    "The Common Sense Book\nof Baby and Child Care",
    "The Age of Anxiety",
    "No Longer Human",
    "Death of a Salesman",
    "The Martian Chronicles",
    "The Catcher in the Rye",
    "The Borrowers",
    "Fahrenheit 451",
    "Lord of the Flies",
    "I can jump puddles",
    "Aniara",
    "The Cat in the Hat",
    "The Computer and the Brain",
    "Sweet Bird of Youth",
    "The Weirdstone of Brisingamen",
    "James and the Giant Peach",
    "A Wrinkle in Time",
    "Where the Wild Things Are",
    "The Giving Tree",
    "The Autobiography of Malcolm X",
    "Rosencrantz and\nGuilderstern Are Dead",
    "The Medium is the Massage:\nAn Inventory of Effects",
    "Do Androids Dream\nof Electric Sheep?",
    "Slaughterhouse-Five",
    "Fantastic Mr. Fox",
    "A Happy Death",
    "Frog and Toad Together",
    "Momo",
    "The Chocolate War",
    "Tuck Everlasting",
    "The Alteration",
    "Bridge to Terabithia",
    "The World According to Garp",
    "The Neverending Story",
    "Cosmos: A Personal Voyage",
    "A Light in the Attic",
    "Life, the\nUniverse and Everything",
    "Pet Sematary"
   };
 
 
  // Fetch the current time
  int H = hour();
  int M = minute();
  int arrSpot = H+M;
  int year = 1900 + (H + M);
 
 
 
  noStroke();
  PFont font = createFont("BonvenoCF-Light.otf",32);
  textFont(font); 
  fill(255,255,255);
  textSize(20);
  String currTimeString = "19: " + (H) + "+" + nf(M, 2);
  if (visible>0){
  text(currTimeString, 10, 25);
  text("Hour: " + H, 10, 50);
  text("Minute: " + M, 10, 75);
  text(year, 10, 100);
  }
  textSize(25);
  text(books[arrSpot], 300,80);
 
  update(mouseX, mouseY); 
  if (circleOver) {
    fill(currentColor);
  } else {
    fill(circleColor);
  }
  ellipse(circleX, circleY, circleSize, circleSize);
  fill(51); 
  textSize(7);
  text("   Clock\nBreakdown", circleX-19,circleY-5); 
  text("   Clock\nBreakdown", circleX-19.5,circleY-5); 
}
 
 
//Code Modified From Processing Site
void update(int x, int y) {
  if ( overCircle(circleX, circleY, circleSize) ) {
    circleOver = true;
  }
  else{
    circleOver=false; 
  }
}
 
void mousePressed() {
  if (circleOver) {
    visible=visible*-1; 
    color temp= circleColor;
     circleColor=currentColor;
     currentColor=temp; 
  }
}
boolean overCircle(int x, int y, int diameter) {
  float disX = x - mouseX;
  float disY = y - mouseY;
  if (sqrt(sq(disX) + sq(disY)) < diameter/2 ) {
    return true;
  } else {
    return false;
  }
}
 
//Image Credits: BuyBackdrops.com
//https://www.buy-backdrop.com/bmz_cache/e/e7d916a4073273331838331e718c7a53.image.300x200.jpg

 

 

ocannoli-Reading03

Although I find the notion of first word art and last word art interesting, I am of the belief that everything is inspired by something and that no work of art is exactly the same as the next. Therefore, it is hard for me to locate a position even along the spectrum since I see it more as a continuum of thought constantly going forward and back, following and breaking form. Even direct copy and pasted code can be different due to the creator, intention, or context in which it was made. This being said, in such a fast paced and constantly changing technological society, novelty is a quality highly valued by a lot of people. Typically, novelty for the sake of novelty does not age well; however, when novelty comes about in the process of creating something one is extremely passionate about or during the process of problem solving, the chances for that technology aging well is greater. Overall, I believe that it is difficult to confine any art form into specific categories for there are so many possibilities and outliers that need to be considered especially regarding the topic of novelty in technology.

ocannoli-LookingOutwards02

Roger Water's project "A Journey into Hyperland" is a 360 VR live experience where the user can fly around an environment and launch items and creatures in order to interact. An aspect of this piece that is so fascinating is that many aspects of the environment such as shape, colors, mountain and marine shape are all determined in real time by the music of band Niagra. I admire the simplicity and elegance of the execution of the design but I also admire the concept of a generative environment spawning from music. Considering that the program reacts differently based on time and location of the user, I suppose that the algorithm behind the work was definitely heavily guided by the idea of generativity rather than it being added later or as an extra experiment. I believe Water did a pretty great job having an effective complexity considering a random environment that looks very clean yet is powered by a song.

Click here to experience his project

ocannoli-AnimatedLoop

Sketches:

GIF:

Description:

In conceptualizing the piece, I had a lot of grand ideas about recreating something in 8-Bit from the original Legend of Zelda game or making a pong-like loop with new colors. Mainly, I was experimenting with circles and opacity to ultimately just mess around. There were many experiments with small pong sized rotating circles and creating weird shapes but eventually my sketches ended up morphing into to creating a minimalist start button for a game. I used PennerEaseOutExpo easing function for the background white circle to create a slight scrolling effect and add more movement. Admittedly, I did not spend as much time as I wished I could on the project; therefore, I'm not very proud of the results, but it was a good introduction to start thinking about experimenting with graphics and the many possibilities regarding such. I feel like I succeeded in some aesthetic aspects and creating a good basis but not the strongest for a final product.

Code:

// Global variables. 
String  myNickname = "nickname"; 
int     nFramesInLoop = 120;
int     nElapsedFrames;
boolean bRecording; 
 
//===================================================
void setup() {
  size (640, 640); 
  bRecording = false;
  nElapsedFrames = 0;
}
//===================================================
void keyPressed() {
  if ((key == 'f') || (key == 'F')) {
    bRecording = true;
    nElapsedFrames = 0;
  }
}
 
//===================================================
void draw() {
 
  // Compute a percentage (0...1) representing where we are in the loop.
  float percentCompleteFraction = 0; 
  if (bRecording) {
    percentCompleteFraction = (float) nElapsedFrames / (float)nFramesInLoop;
  } else {
    percentCompleteFraction = (float) (frameCount % nFramesInLoop) / (float)nFramesInLoop;
  }
 
  // Render the design, based on that percentage. 
  renderMyDesign (percentCompleteFraction);
 
  // If we're recording the output, save the frame to a file. 
  if (bRecording) {
    saveFrame("frames/" + myNickname + "_frame_" + nf(nElapsedFrames, 4) + ".png");
    nElapsedFrames++; 
    if (nElapsedFrames >= nFramesInLoop) {
      bRecording = false;
    }
  }
}
 
//===================================================
void renderMyDesign (float percent) {
  background (5, 44, 64);
  smooth(); 
  stroke (0, 0, 0); 
  strokeWeight (2); 
  // Here, I assign some handy variables. 
  float cx = 100;
  float cy = 100;
    //----------------------
   //Here's a sigmoidally-moving pink square!
   //This uses the "Double-Exponential Sigmoid" easing function 
   //from https://github.com/golanlevin/Pattern_Master
  float eased = function_PennerEaseOutExpo (percent); 
  float yPosition2 = map(eased, 0, 1, 0, 640); 
  noStroke();
  fill (255, 255, 255);
  yPosition2=yPosition2-600;
  for(int j=0; j<=9;j++){
    int rX=-40;
    for(int i=0; i<10; i++){
    rX=rX+90;
    if(i!=2 && i!=3 && i!=4){
    ellipse (rX, yPosition2, 15, 15);
    }
    }
    yPosition2+=120;
  }
  //----------------------
  // Here's a pulsating ellipse
  float ellipsePulse = sin ( 1.0 * percent * TWO_PI); 
  float ellipseW = map(ellipsePulse, -1, 1, 200, 400); 
  float ellipseH = map(ellipsePulse, -1, 1, 200, 400); 
  float ellipseColor = map(ellipsePulse, -1, 1, 239, 200); 
  float ellipsePulse2 = sin ( 2.0 * percent * TWO_PI); 
  float ellipseW2 = map(ellipsePulse2, -1, 1, 200, 350); 
  float ellipseH2 = map(ellipsePulse2, -1, 1, 200, 350);
  float ellipsePulse3 = sin ( 1.7* percent * TWO_PI); 
  float ellipseW3= map(ellipsePulse3, -1, 1, 10, 250); 
  float ellipseH3 = map(ellipsePulse3, -1, 1, 10, 250);
  noStroke();
  fill (252, ellipseColor, ellipseColor, 70); 
  ellipse (325, 300, ellipseW, ellipseH); 
  ellipse (325, 300, ellipseW2-30, ellipseH2-30);  
  ellipse (325, 300, ellipseW2-30, ellipseH2-30);
}
//===================================================
// Taken from https://github.com/golanlevin/Pattern_Master
float function_PennerEaseOutExpo(float t) {
  //functionName = "Penner's EaseOut Exponential";
  return (t==1) ? 1 : (-pow(2, -10 * t) + 1);
}

 

ocannoli-Scope

Scope GIF:

Description:

My praxinoscope is a very simple design, centered around rotating circles. Initially, I was really inspired by planets and was thinking about maybe having a planet with a single asteroid. However, I thought that looked boring and decided to play around with rotation patterns and spirals. There is not much conceptually behind the design, instead it was mainly an experimentation with rotation patterns and how to make a trippy image that hurts your eyes.

Scope PDF:

ocannoli-praxinoscope-output

Scope Code:

import processing.pdf.*;
boolean bRecordingPDF = false;
 
float inch = 72; 
float diamArtInner = inch * 1.50; 
float diamArtOuter = inch * 4.80; 
float diamCutInner = inch * 1.41; 
float diamCutOuter = inch * 4.875; 
float holeDy = inch * 0.23;
float holeDx = inch * 0.20;
float holeD = inch * 0.1;
 
final int nFrames = 10; 
int myFrameCount = 0;
int exportFrameCount = 0; 
boolean bAnimate = true; 
boolean bExportFrameImages = false;
 
//-------------------------------------------------------
void setup() {
  size(792, 612); // 11x8.5" at 72DPI
  frameRate(15);
  smooth();
} 
 
//-------------------------------------------------------
void draw() {
  background(240); 
  if (bRecordingPDF) {
    beginRecord(PDF, "praxinoscope-output.pdf");
  }
 
  // Do all the drawing. 
  pushMatrix(); 
  translate(width/2, height/2);
  drawCutLines(); 
  drawGuides(); 
  drawAllFrames();
  popMatrix();
 
  if (bExportFrameImages) {
    // If activated, export .PNG frames 
    if (exportFrameCount < nFrames) { String filename = "frame_" + nf((exportFrameCount%nFrames), 3) + ".png"; saveFrame("frames/" + filename); println("Saved: " + filename); exportFrameCount++; if (exportFrameCount >= nFrames) {
        bExportFrameImages = false;
        exportFrameCount = 0;
      }
    }
  }
 
  if (bRecordingPDF) {
    endRecord();
    bRecordingPDF = false;
  }
}
 
 
//-------------------------------------------------------
void keyPressed() {
  switch (key) {
  case ' ': 
    // Press spacebar to pause/unpause the animation. 
    bAnimate = !bAnimate;
    break;
 
  case 'p': 
  case 'P':
    // Press 'p' to export a PDF for the Praxinoscope.
    bRecordingPDF = true; 
    break;
 
  case 'f': 
  case 'F': 
    // Press 'f' to export .png Frames (to make an animated .GIF)
    myFrameCount = 0; 
    exportFrameCount = 0; 
    bExportFrameImages = true;
    bAnimate = true; 
    break;
  }
}
 
//-------------------------------------------------------
void drawCutLines() {
  fill(0); 
  textAlign(CENTER, BOTTOM); 
  text("Praxinoscope Template", 0, 0-diamCutOuter/2-6); 
 
  stroke(0); 
  strokeWeight(1.0);
 
  noFill(); 
  if (!bRecordingPDF) {
    fill(255); 
  }
  ellipse(0, 0, diamCutOuter, diamCutOuter);
 
  noFill(); 
  if (!bRecordingPDF) {
    fill(240); 
  }
  ellipse(0, 0, diamCutInner, diamCutInner);
 
  noFill(); 
  ellipse(diamCutOuter/2 - holeDx, 0-holeDy, holeD, holeD); 
 
  line (diamCutInner/2, 0, diamCutOuter/2, 0);
}
 
//-------------------------------------------------------
void drawGuides() {
  // This function draws the guidelines. 
  // Don't draw these when we're exporting the PDF. 
  if (!bRecordingPDF) {
 
    noFill(); 
    stroke(128); 
    strokeWeight(0.2); 
    ellipse(0, 0, diamArtInner, diamArtInner); 
    ellipse(0, 0, diamArtOuter, diamArtOuter);
 
    for (int i=0; i<nFrames; i++) {
      float angle = map(i, 0, nFrames, 0, TWO_PI); 
      float pxi = diamArtInner/2 * cos(angle);
      float pyi = diamArtInner/2 * sin(angle);
      float pxo = diamArtOuter/2 * cos(angle);
      float pyo = diamArtOuter/2 * sin(angle);
      stroke(128); 
      strokeWeight(0.2);
      line (pxi, pyi, pxo, pyo);
    }
 
    // Draw the red wedge outline, highlighting the main view.
    int redWedge = 7; // assuming nFrames = 10
    for (int i=redWedge; i<=(redWedge+1); i++) {
      float angle = map(i, 0, nFrames, 0, TWO_PI); 
      float pxi = diamArtInner/2 * cos(angle);
      float pyi = diamArtInner/2 * sin(angle);
      float pxo = diamArtOuter/2 * cos(angle);
      float pyo = diamArtOuter/2 * sin(angle);
      stroke(255, 0, 0); 
      strokeWeight(2.0);
      line (pxi, pyi, pxo, pyo);
    }
    noFill(); 
    stroke(255, 0, 0); 
    strokeWeight(2.0);
    float startAngle = redWedge*TWO_PI/nFrames;
    float endAngle = (redWedge+1)*TWO_PI/nFrames;
    arc(0, 0, diamArtInner, diamArtInner, startAngle, endAngle); 
    arc(0, 0, diamArtOuter, diamArtOuter, startAngle, endAngle); 
 
 
    for (int i=0; i<nFrames; i++) {
      float angle = map(i, 0, nFrames, 0, TWO_PI); 
 
      pushMatrix();
      rotate(angle); 
      float originY = ((diamArtOuter + diamArtInner)/2)/2;
      translate(0, 0-originY); 
 
      noFill(); 
      stroke(128); 
      strokeWeight(0.2);
      line (-inch/2, 0, inch/2, 0); 
      line (0, -inch/2, 0, inch/2); 
 
      popMatrix();
    }
  }
}
 
//-------------------------------------------------------
void drawAllFrames() {
  for (int i=0; i<nFrames; i++) {
    float angle = map(i, 0, nFrames, 0, TWO_PI); 
    float originY = ((diamArtOuter + diamArtInner)/2)/2;
 
    pushMatrix();
    rotate(angle); 
    translate(0, 0-originY); 
    scale(0.8, 0.8); // feel free to ditch this 
 
    int whichFrame = i; 
    if (bAnimate) {
      whichFrame = (i+myFrameCount)%nFrames;
    }
    drawArtFrame (whichFrame); 
    // drawArtFrameAlternate (whichFrame); 
 
    popMatrix();
  }
  myFrameCount++;
}
 
 
//-------------------------------------------------------
void drawArtFrame (int whichFrame) { 
  // Draw the artwork for a generic frame of the Praxinoscope, 
  // given the framenumber (whichFrame) out of nFrames.
  // NOTE #1: The "origin" for the frame is in the center of the wedge.
  // NOTE #2: Remember that everything will appear upside-down!
 
  // Draw the frame number
  fill(0); 
  noStroke(); 
 
  // Draw a pulsating ellipse
  noFill(); 
  stroke(0);
  strokeWeight(1); 
  float t = map(whichFrame, 0, nFrames, 0, 1); 
  float diam = map(cos(t*TWO_PI), -1, 1, 25, 50); 
  ellipse(0, 0, diam, diam); 
 
  //rotating circle
  float radius = diam/2; 
  float rotatingArmAngle = (whichFrame*.1) * TWO_PI; 
  float px = 0 + radius*cos(rotatingArmAngle); 
  float py = 0 + radius*sin(rotatingArmAngle); 
  fill    (0); 
  stroke(51);
  ellipse(px, py, 8, 8);
 
  //rotating circle
  float rotatingArmAngle2 = (whichFrame*.1) * TWO_PI; 
  float px2 = 15 + radius*cos(rotatingArmAngle2); 
  float py2 = 15 + radius*sin(rotatingArmAngle2); 
  fill    (0); 
  stroke(51);
  ellipse(-px2, -py2, 8, 8);
 
  float px3 = -12 + radius*cos(rotatingArmAngle2); 
  float py3 = -20 + radius*sin(rotatingArmAngle2); 
  fill    (0); 
  stroke(51);
  ellipse(-px3, -py3, 8, 8);
 
  //rect figure
  float amplitude=100;
  float f=.1;
  float xR=160;
  float yR=(160)+amplitude*sin(f*whichFrame);
  rect(xR,yR,10,10); 
}
//-------------------------------------------------------
void drawArtFrameAlternate(int whichFrame) { 
  // An alternate drawing test. 
  // Draw a falling object. 
 
 
  // Draw a little splat on the frame when it hits the ground. 
  if (whichFrame == (nFrames-1)) {
    stroke(0, 0, 0); 
    strokeWeight(0.5); 
    int nL = 10;
    for (int i=0; i<nL; i++) {
      float a = HALF_PI + map(i, 0, nL-1, 0, TWO_PI);
      float cx = 12 * cos(a);
      float cy = 10 * sin(a); 
      float dx = 16 * cos(a);
      float dy = 13 * sin(a); 
      line (cx, 45+cy, dx, 45+dy);
    }
  }
 
  // Draw a little box frame
  fill(255); 
  stroke(0, 0, 0);
  strokeWeight(1); 
  rect(-5, -50, 10, 100); 
 
  // Make the puck accelerate downward
  float t = map(whichFrame, 0, nFrames-1, 0, 1); 
  float t2 = pow(t, 2.0); 
  float rh = 8 + whichFrame * 0.5; // wee stretch
  float ry = map(t2, 0, 1, 0, 100-rh) - 50; 
 
  noStroke(); 
  fill(0, 0, 0);
  rect(-5, ry, 10, rh);
}

 

ocannoli-Reading02

1A) Something that demonstrates effective complexity is some of the first Pixar animators used mathematics and fractal geometry to create realistic mountains. Although I could not find a great picture to highlight these first mountains since I watched in in a documentary, these mountains gives the appearance of looking seemingly more toward the side of total randomness and higher complexity even though it is derived from a pretty rigid formula. Therefore, it lies somewhat in the middle with pull toward total randomness.

1B) Regarding the problem that if generative art can "diminish the value of the art when unique objects can be mass‐produced?" I believe that although art can be produced on a mass scale, the value of the artist whether that be their individual artistic abilities or stylistic code does not diminish simply because generative art allows many unique objects to be created. Being massed produced and being unique are just some characteristics of a much more complicated system regarding the appreciation of art.

ocannoli-Interruptions.

  • The work is square
  • The work consists of various black lines on a white background
  • The lines are the same length
  • Many of the lines are at an angle
  • White spaces that lack black lines seem to occur to varying degrees
  • The lines are thin
  • The lines often touch one another to make diamond, square, and triangle shapesMany of the lines touch each other but not all
  • The lines seem random but also feel somewhat repetitive
  • The lines have a type of pattern involving either intersections, distance or the like

First I started with basic appearance based characteristics like the length of lines and colors. Then after some trial and error of creating random methods with the random function, I ended up creating a 50X50 grid of all lines then trying to accomplish their rotation. To figure out the rotation I ended up using perlin noise as the basis for that method. After tweaking some scaling, I attempted to add random spaces between the lines by skipping the creation of a line if the noise was in a certain small range. Although I did not complete it, at the end I was working on a method that would make sure all lines only intersected another line at its end point.

ocannoli-Intersections

Interactive Intersections:

Intersections Gif:

 function setup() {
  createCanvas(400, 400);
}
var boolDoRefresh;
 
function setup() {
  createCanvas(400, 400);
  boolDoRefresh = true;
}
 
class Line {
  constructor(x1, y1, x2, y2){
    this.x1 = x1;
    this.y1 = y1;
    this.x2 = x2;
    this.y2 = y2;
 }
	drawLine(){
    line(this.x1,this.y1,this.x2,this.y2);
  }  	
}
 
function draw() {
  if (boolDoRefresh) {
    background(51);
    stroke(220);
    allLines=[];
    intersectionCircles=[];
    for (var k = 0; k < 12; k++) {
      var a = random(400);
      var b = random(400);
      var c = random(400);
      var d = random(400);
      var nLine= new Line(a,b,c,d);
      allLines.push(nLine);
      allLines[k].drawLine();
    }
    for(var i=0; i<allLines.length-1; i++){
      for(var j=1; j<allLines.length-2;j++){
      if(allLines[i]!=allLines[j])
      {
        var intersect= intersects(allLines[i].x1,allLines[i].y1,allLines[i].x2,allLines[i].y2,allLines[j].x1,allLines[j].y1,allLines[j].x2,allLines[j].y2);
      	if (intersect!==false){
          stroke(240,220,40); 
          fill(240,220,40);
          ellipse(intersect.x,intersect.y,10,10);
        }
           }
      }
    }
  }
  boolDoRefresh = false
}
//formula from Paul Bourke
function intersects(x1, y1, x2, y2, x3, y3, x4, y4) {
  if ((x1 === x2 && y1 === y2) || (x3 === x4 && y3 === y4)) {
		return false;
  }
  denominator = ((y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1));
	if (denominator === 0) {
		return false;
	}
  let ua = ((x4 - x3) * (y1 - y3) - (y4 - y3) * (x1 - x3)) / denominator;
	let ub = ((x2 - x1) * (y1 - y3) - (y2 - y1) * (x1 - x3)) / denominator;
  if (ua < 0 || ua > 1 || ub < 0 || ub > 1) {
		return false
	}
  let x = x1 + ua * (x2 - x1)
	let y = y1 + ua * (y2 - y1)
 
	return {x, y}
}
 
function mousePressed() {
  boolDoRefresh = true;
}