{"id":383,"date":"2012-11-10T19:18:33","date_gmt":"2012-11-10T19:18:33","guid":{"rendered":"http:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/?p=383"},"modified":"2012-11-11T16:59:47","modified_gmt":"2012-11-11T16:59:47","slug":"nature-vs-machine","status":"publish","type":"post","link":"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/2012\/11\/10\/nature-vs-machine\/","title":{"rendered":"Nature vs Machine"},"content":{"rendered":"<p>Making something seem natural can be a difficult thing. What does it mean for something to be natural. I think that naturally occurring things can also have seemingly unnatural properties. Take crystals for instance. If one had never seen a crystal before in their life and had made it a while in a mechanized society I suspect they would find it hard to believe that the crystal was natural. Another instance is of things on a micro scale. Again the objects would seem unreal and man made.<\/p>\n<p>The first thought that I had in making something natural was to make something like an ant farm with connecting and wandering tunnels. The following is a result of my pursuit of an ant farm.<br \/>\n<script type=\"application\/processing\">\r\nArrayList<Point2D> points = new ArrayList<Point2D>();\r\nint MAXPOINTS = 1000;\r\nboolean shouldDraw = true;\r\nvoid setup(){\r\n  size(500,500);\r\n  background(0);\r\n  points.add(new Point2D(width\/2,height\/2));\r\n  stroke(255);\r\n  for(int i = 0; i < points.size(); i++)\r\n  {\r\n    points.get(i).paint();\r\n  }\r\n  colorMode(HSB,100);\r\n}\r\n\r\nvoid draw(){\r\n  if(shouldDraw){\r\n    \/\/Generate new points\r\n    for(int i = 0; i < points.size(); i++)\r\n    {\r\n      if(random(0,1.0) > .98){ \/\/ 10% chance of split\r\n        points.add(new Point2D(points.get(i)));\r\n      }\r\n    }\r\n      for(int i = 0; i < points.size(); i++)\r\n    {\r\n      if(points.get(i).isOutside()){\r\n        points.remove(i);\r\n      }\r\n    }\r\n    if(points.size() > MAXPOINTS)\r\n    {\r\n      points.subList(0,points.size()-MAXPOINTS).clear();\r\n    }\r\n    \/\/Move Points\r\n    for(int i = 0; i < points.size(); i++)\r\n    {\r\n      Point2D p = points.get(i);\r\n      p.addX(random(-10.0,10.0));\r\n      p.addY(random(-10.0,10.0));\r\n      p.paint();\r\n    }\r\n  }\r\n  \r\n}\r\n\r\nclass Point2D{\r\n  float x,y,lastx,lasty;\r\n  Point2D(float x,float y){\r\n    this.x = x;\r\n    this.y = y;\r\n    this.lastx = x;\r\n    this.lasty = y;\r\n  }\r\n  \r\n  Point2D(Point2D p){\r\n    this.x = p.x;\r\n    this.y = p.y;\r\n    this.lastx = x;\r\n    this.lasty = y;\r\n  }\r\n  \r\n  float getX(){\r\n    return this.x;\r\n  }\r\n  \r\n  float getY(){\r\n    return this.y;\r\n  }\r\n  \r\n  void addX(float inc){\r\n    this.lastx = this.x;\r\n    this.x += inc;\r\n    \r\n  }\r\n  \r\n  void addY(float inc){\r\n    this.lasty = this.y;\r\n    this.y += inc;\r\n  }\r\n  \r\n  void paint(){\r\n    line(this.x,this.y,this.lastx,this.lasty);\r\n  }\r\n  \r\n  boolean isOutside(){\r\n    return (this.x > width || this.x < 0 || this.y > height || this. y < 0);\r\n  }\r\n  \r\n}\r\n\r\nvoid mouseClicked(){\r\n  if(mouseButton == LEFT){\r\n    stroke(random(0,100),random(0,100),100,random(0,100));\r\n    points.clear();\r\n    points.add(new Point2D(width\/2,height\/2));\r\n  }\r\n  else if (mouseButton == RIGHT){\r\n    shouldDraw = !shouldDraw;\r\n  }\r\n  else \/\/Center\r\n  {\r\n    \/\/save(\"cats.jpg\");\r\n  }\r\n}\r\n<\/script><br \/>\nAs you can see it looks nothing like an ant farm. Essentially what is going on in this is a point is initialized then has a probability of duplicating. The point and potentially its duplicate then move a random distance in a random direction. To ensure that the animation always runs smoothly, first, points off the screen are deleted, and second, if there are more than N points then we delete the oldest points till there are only N. N is a configurable number here.<\/p>\n<p>The next script I wrote tried again to realign with the ant farm idea. I definatly was closer but I think I may have gotten it upside down.<br \/>\n<script type=\"application\/processing\">\r\nArrayList<Point2D> points = new ArrayList<Point2D>();\r\nint MAXPOINTS = 1000;\r\nboolean shouldDraw = true;\r\nvoid setup(){\r\n  size(500,500);\r\n  smooth();\r\n  background(0);\r\n  points.add(new Point2D(width\/2,height));\r\n  stroke(255);\r\n  for(int i = 0; i < points.size(); i++)\r\n  {\r\n    points.get(i).paint();\r\n  }\r\n  colorMode(HSB,100);\r\n}\r\n\r\nvoid draw(){\r\n  if(shouldDraw){\r\n    \/\/Generate new points\r\n    for(int i = 0; i < points.size(); i++)\r\n    {\r\n      if(random(0,1.0) > .95){ \/\/ 10% chance of split\r\n        points.add(new Point2D(points.get(i)));\r\n      }\r\n    }\r\n      for(int i = 0; i < points.size(); i++)\r\n    {\r\n      if(points.get(i).isOutside()){\r\n        points.remove(i);\r\n      }\r\n    }\r\n    if(points.size() > MAXPOINTS)\r\n    {\r\n      points.subList(0,points.size()-MAXPOINTS).clear();\r\n    }\r\n    \/\/Move Points\r\n    for(int i = 0; i < points.size(); i++)\r\n    {\r\n      Point2D p = points.get(i);\r\n      p.addX(p.getHeading());\r\n      p.addY(random(-10.0,0));\r\n      p.paint();\r\n    }\r\n  }\r\n  \r\n}\r\n\r\nclass Point2D{\r\n  float x,y,lastx,lasty;\r\n  float heading;\r\n  Point2D(float x,float y){\r\n    this.x = x;\r\n    this.y = y;\r\n    this.lastx = x;\r\n    this.lasty = y;\r\n    this.heading = random(-10.0,10.0);\r\n    \r\n  }\r\n  \r\n  Point2D(Point2D p){\r\n    this.x = p.x;\r\n    this.y = p.y;\r\n    this.lastx = x;\r\n    this.lasty = y;\r\n    this.heading = random(-10.0,10.0);\r\n  }\r\n  \r\n  float getX(){\r\n    return this.x;\r\n  }\r\n  \r\n  float getY(){\r\n    return this.y;\r\n  }\r\n  \r\n  void addX(float inc){\r\n    this.lastx = this.x;\r\n    this.x += inc;\r\n    \r\n  }\r\n  \r\n  void addY(float inc){\r\n    this.lasty = this.y;\r\n    this.y += inc;\r\n  }\r\n  \r\n  float getHeading(){\r\n    return this.heading;\r\n  }\r\n  \r\n  void paint(){\r\n    line(this.x,this.y,this.lastx,this.lasty);\r\n  }\r\n  \r\n  boolean isOutside(){\r\n    return (this.x > width || this.x < 0 || this.y > height || this. y < 0);\r\n  }\r\n  \r\n}\r\n\r\nvoid mouseClicked(){\r\n  if(mouseButton == LEFT){\r\n    stroke(random(0,100),random(0,100),100,random(0,100));\r\n    points.clear();\r\n    points.add(new Point2D(width\/2,height));\r\n  }\r\n  else if (mouseButton == RIGHT){\r\n    shouldDraw = !shouldDraw;\r\n  }\r\n  else \/\/Center\r\n  {\r\n    \/\/save(\"cats.jpg\");\r\n  }\r\n}\r\n<\/script><br \/>\nWe now have some sort of growth maybe like a tree. When you click (hopefully) the animation will start over with a new color. I think you can get some pretty cool colors all things said and done with this.<\/p>\n<p>I also wanted to have something chase the mouse around the screen. I though it might be interesting to have waves following the mouse that varied orthogonal to the vector pointing to the mouse location from the current draw location. My first attempt did not work out as well as I hoped.<br \/>\n<script type=\"application\/processing\">\r\nArrayList<Point2D> points = new ArrayList<Point2D>();\r\nArrayList<Float> randoms = new ArrayList<Float>();\r\nint MAXPOINTS = 10;\r\nboolean shouldDraw = true;\r\nfloat phi = 0;\r\nvoid setup(){\r\n  size(500,500);\r\n  smooth();\r\n  background(0);\r\n  stroke(255);\r\n  for(int i = 0; i < MAXPOINTS; i++)\r\n  {\r\n    points.add(new Point2D(width\/2,height));\r\n\/\/points.add(new Point2D(random(width),random(height)));\r\n  }\r\n  for(int i = 0; i <MAXPOINTS; i++)\r\n  {\r\n     randoms.add(random(0,100)); \r\n  }\r\n  colorMode(HSB,100);\r\n}\r\n\r\nvoid draw(){\r\n  if(shouldDraw){\r\n    phi += 1;\r\n    for(int i = 0; i < points.size(); i++)\r\n    {\r\n      Point2D p = points.get(i);\r\n      float xPos = p.getX();\r\n      float yPos = p.getY();\r\n      float xdif = mouseX - xPos;\r\n      float ydif = mouseY - yPos;\r\n      float magn = sqrt(xdif*xdif+ydif*ydif);\r\n      \/\/These now define a unit vector\r\n      xdif \/= magn;\r\n      ydif \/= magn;\r\n      \/\/To find a perpendicular unit vector\r\n      \/\/negate one of the components and switch them\r\n      float nos = noise(randoms.get(i)+frameCount);\r\n      p.addX(-18*nos*ydif+3*xdif);\r\n      p.addY(18*nos*xdif+3*ydif);\r\n      stroke((randoms.get(i)+phi)%100,100,100,50);\r\n      p.paint();\r\n    }\r\n  }\r\n}\r\n\r\nclass Point2D{\r\n  float x,y,lastx,lasty;\r\n  float heading;\r\n  Point2D(float x,float y){\r\n    this.x = x;\r\n    this.y = y;\r\n    this.lastx = x;\r\n    this.lasty = y;\r\n    this.heading = random(-10.0,10.0);\r\n    \r\n  }\r\n  \r\n  Point2D(Point2D p){\r\n    this.x = p.x;\r\n    this.y = p.y;\r\n    this.lastx = x;\r\n    this.lasty = y;\r\n    this.heading = random(-10.0,10.0);\r\n  }\r\n  \r\n  float getX(){\r\n    return this.x;\r\n  }\r\n  \r\n  float getY(){\r\n    return this.y;\r\n  }\r\n  \r\n  void addX(float inc){\r\n    this.lastx = this.x;\r\n    this.x += inc;\r\n    \r\n  }\r\n  \r\n  void addY(float inc){\r\n    this.lasty = this.y;\r\n    this.y += inc;\r\n  }\r\n  \r\n  float getHeading(){\r\n    return this.heading;\r\n  }\r\n  \r\n  void paint(){\r\n    line(this.x,this.y,this.lastx,this.lasty);\r\n  }\r\n  \r\n  boolean isOutside(){\r\n    return (this.x > width || this.x < 0 || this.y > height || this. y < 0);\r\n  }\r\n  \r\n}\r\n\r\nvoid mouseClicked(){\r\n  if(mouseButton == LEFT){\r\n  }\r\n  else if (mouseButton == RIGHT){\r\n    shouldDraw = !shouldDraw;\r\n  }\r\n  else \/\/Center\r\n  {\r\n    \/\/save(\"cats.jpg\");\r\n  }\r\n}\r\n<\/script><br \/>\nAs you can see the lines move radially to the mouses location rather than having the variation orthogonal to the vector mouse location. It still is a pretty interesting effect and I rather liked the way you could make the lines compress and grow depending on how you used the mouse.<\/p>\n<p>Finally I actually got the lines to move in the way I originally intended. Here is the result:<br \/>\n<script type=\"application\/processing\">\r\nArrayList<Point2D> points = new ArrayList<Point2D>();\r\nArrayList<Float> randoms = new ArrayList<Float>();\r\nint MAXPOINTS = 10;\r\nboolean shouldDraw = true;\r\nfloat phi = 0;\r\nfloat time = 0;\r\nvoid setup(){\r\n  size(500,500);\r\n  smooth();\r\n  background(0);\r\n  stroke(255);\r\n  for(int i = 0; i < MAXPOINTS; i++)\r\n  {\r\n    points.add(new Point2D(width\/2,height));\r\n\/\/points.add(new Point2D(random(width),random(height)));\r\n  }\r\n  for(int i = 0; i <MAXPOINTS; i++)\r\n  {\r\n     randoms.add(random(0,MAXPOINTS*10)); \r\n  }\r\n  colorMode(HSB,100);\r\n}\r\n\r\nvoid draw(){\r\n  if(shouldDraw){\r\n    phi += 1;\r\n    time += .01;\r\n    Point2D p = points.get(0);\r\n    float xPos = p.getX();\r\n    float yPos = p.getY();\r\n    float xdif = mouseX - xPos;\r\n    float ydif = mouseY - yPos;\r\n    float magn = sqrt(xdif*xdif+ydif*ydif);\r\n    \/\/These now define a unit vector\r\n    xdif \/= magn;\r\n    ydif \/= magn;\r\n    p.addX(xdif);\r\n    p.addY(ydif);\r\n    colorMode(RGB,255);\r\n    stroke(255);\r\n    \/\/p.paint();\r\n    colorMode(HSB,100);\r\n    for(int i = 1; i < points.size(); i++)\r\n    {\r\n      Point2D p2 = points.get(i);\r\n      \/\/To find a perpendicular unit vector\r\n      \/\/negate one of the components and switch them\r\n      float nos = noise(randoms.get(i)+time);\r\n      p2.setX(100*(nos-.5)*ydif+p.getX());\r\n      p2.setY(-100*(nos-.5)*xdif+p.getY());\r\n      stroke((randoms.get(i)+phi)%100,100,100,50);\r\n      p2.paint();\r\n    }\r\n  }\r\n}\r\n\r\nclass Point2D{\r\n  float x,y,lastx,lasty;\r\n  float heading;\r\n  Point2D(float x,float y){\r\n    this.x = x;\r\n    this.y = y;\r\n    this.lastx = x;\r\n    this.lasty = y;\r\n    this.heading = random(-10.0,10.0);\r\n    \r\n  }\r\n  \r\n  Point2D(Point2D p){\r\n    this.x = p.x;\r\n    this.y = p.y;\r\n    this.lastx = x;\r\n    this.lasty = y;\r\n    this.heading = random(-10.0,10.0);\r\n  }\r\n  \r\n  float getX(){\r\n    return this.x;\r\n  }\r\n  \r\n  float getY(){\r\n    return this.y;\r\n  }\r\n  \r\n  void addX(float inc){\r\n    this.lastx = this.x;\r\n    this.x += inc;\r\n    \r\n  }\r\n  \r\n  void addY(float inc){\r\n    this.lasty = this.y;\r\n    this.y += inc;\r\n  }\r\n  \r\n  void setX(float x){\r\n    this.lastx = this.x;\r\n    this.x = x;\r\n    \r\n  }\r\n  \r\n  void setY(float y){\r\n    this.lasty = this.y;\r\n    this.y = y;\r\n  }\r\n  \r\n  \r\n  float getHeading(){\r\n    return this.heading;\r\n  }\r\n  \r\n  void paint(){\r\n    line(this.x,this.y,this.lastx,this.lasty);\r\n  }\r\n  \r\n  boolean isOutside(){\r\n    return (this.x > width || this.x < 0 || this.y > height || this. y < 0);\r\n  }\r\n  \r\n}\r\n\r\nvoid mouseClicked(){\r\n  if(mouseButton == LEFT){\r\n  }\r\n  else if (mouseButton == RIGHT){\r\n    shouldDraw = !shouldDraw;\r\n  }\r\n  else \/\/Center\r\n  {\r\n    \/\/save(\"cats.jpg\");\r\n  }\r\n}\r\n<\/script><br \/>\nThis fulfilled my goal though I found it annoying the way that each line was not moving quite the way I wanted it too. I envisioned it such that each varying stream would move at a constant &#8220;speed.&#8221; However if the mouse is close to the location the lines are being drawn and move around the animation can move very quickly.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Making something seem natural can be a difficult thing. What does it mean for something to be natural. I think that naturally occurring things can also have seemingly unnatural properties. Take crystals for instance. If one had never seen a &hellip; <a href=\"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/2012\/11\/10\/nature-vs-machine\/\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":13,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":[],"categories":[1],"tags":[],"_links":{"self":[{"href":"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/wp-json\/wp\/v2\/posts\/383"}],"collection":[{"href":"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/wp-json\/wp\/v2\/users\/13"}],"replies":[{"embeddable":true,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/wp-json\/wp\/v2\/comments?post=383"}],"version-history":[{"count":10,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/wp-json\/wp\/v2\/posts\/383\/revisions"}],"predecessor-version":[{"id":419,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/wp-json\/wp\/v2\/posts\/383\/revisions\/419"}],"wp:attachment":[{"href":"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/wp-json\/wp\/v2\/media?parent=383"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/wp-json\/wp\/v2\/categories?post=383"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.joshuarosenstock.com\/teaching\/IMGD3x00_B12\/wp-json\/wp\/v2\/tags?post=383"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}