Tagged: loops

thabir – LookingOutwards04

The artist I chose to write about this week is a sculptor named Reuben Margolin, specializing in kinetic sculpture. Never having been to art school (but being trained in painting in two different schools of technique), Margolin’s work seems naive to the discussions and discourse of the art world, instead focussing on the singular issue of observation vs representation. Having graduated with a major in english, after having partially studied math, geology, and anthropology, Margolin was first drawn to kinetic sculpture when he observed the sinusoidal motions of a caterpillar. The representation of this form of cyclical motion, among others, plays an important part in his work.

Margolin’s sculptures are all mostly made of wood dowels and pulley systems, hang from the ceiling, and are in some sort of sinusoidal motion. His first sculptures literally seem like manifestations of caterpillars (such as the one in the gifs below). He then started making planar and circular waves, such as the ones above. Many of his sculptures model other cyclical motions such as the falling of drops into a water body, or the motion of running water around a paddle. In this respect, they actually remind me of the work we were looking at in the animation and loops week, since they seem to be using a physical analogue to easing functions to make motion feel organic.

In the talk linked below, Margolin goes into detail about the evolution of his process as well as his motivations. He talks about how he gains inspiration from the desire to represent cyclical motion in the form of sinusoidal models. Each of his sculptures is, in a way, his method of understanding the world outside him and trying to bring order to his senses. He then goes on to further develop this distinction by drawing the contrast between the Charles Cecil Studios in Florence and the Imperial Academy of Arts in St Petersburg. In the former, he was taught to observe the world through the play of light, and reproduce exactly what he saw. In the latter, he was taught how to build up his subject structurally from what he knows to be true about it, focussing on a sense of mass and solidity.

For him, these two approaches represent the two ways of viewing the world. One relies on the senses, focussing on what makes itself observable to us, while the other is an act of questioning, where we attempt to superimpose a model on the world as it exists: observation vs representation. I found this to be uncannily similar to the concept of my clock from last week, where I was exploring the difference between the human abstraction of cyclically recurring time units and the actual cyclical events these units were meant to measure. Margolin’s work also lies within this dialectic of the viscerality of motion vs its underlying order. This was one of the main reasons that this project struck me. Also, the slow, cyclical motions and the intricate machinery of each sculpture makes it absolutely mesmerizing to watch.

Before posting this, I wondered for a while whether this body of work could truly be categorized under the heading of new media art. It is completely analog and could technically have been build in the 19th century. However, I thought back to the reading by Philip Galanter and remembered that a work was generative whenever it handed over autonomy to a process that could in essence be simulated by code. And then I realized that all of the elaborate wood constructions were merely an analog way for Margolin to set up his system, design his algorithm, write his code, and that by setting the mobile in motion, he is essentially “running” his structure, handing over autonomy to a combination of sinusoidal waves of varying periods which could most definitely be represented using code. Therefore, in my opinion, this does in fact fall under the umbrella of generative art, even though it is completely analog.

thabir – Scope

thabir-praxinoscope-output

I was extremely interested in the behavior of circles for this weeks assignments. I wanted to see how I could make them move and interact with each other. To this end, I made a small personal circle library with a Circle class and some methods that allowed me to stretch circles, join circles, and pull circles apart.

I then used this library to implement a design which consists of circles bouncing inside of another circle. I then also implemented a method which allows you to pull one circle out of the other while making it appear like there is some kind of cohesive force between them. I was inspired by bubbles and water droplets.

Somethings I wanted to accomplish but wasn’t able to, was to calculate intersection areas inside the large black circle and color an intersection black if it fell inside an odd number of circles and white otherwise. However, I wasn’t able to think of an efficient way to do this.

These were some of my preparatory sketches:

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
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
class Circle {
  int x;
  int y;
  float r;
  color c;
 
  int[][] samplePoints = new int[120][2];
 
  Circle(int a, int b, float d, color e) {
    x = a;
    y = b;
    r = d;
    c = e;
 
    //sample points from the circle
    for(int i=0; i<samplePoints.length; i++) {
      float angle = radians(i*(360.0/samplePoints.length));
      samplePoints[i][0] = x + round(cos(angle)*r);
      samplePoints[i][1] = y + round(sin(angle)*r);
    }
  }
 
  void move(int a, int b) {
    x = a;
    y = b;
 
    //sample points from the circle
    for(int i=0; i<samplePoints.length; i++) {
      float angle = radians(i*(360.0/samplePoints.length));
      samplePoints[i][0] = x + round(cos(angle)*r);
      samplePoints[i][1] = y + round(sin(angle)*r);
    }
  }
 
  void Resize(float a) {
    r = a;
 
    //sample points from the circle
    for(int i=0; i<samplePoints.length; i++) {
      float angle = radians(i*(360.0/samplePoints.length));
      samplePoints[i][0] = x + round(cos(angle)*r);
      samplePoints[i][1] = y + round(sin(angle)*r);
    }
  }
 
  //projects circle rotated around y axis
  void projectCircle(float angle) {
    fill(c);
    ellipse(x, y, ((cos(angle)*r)*2), (r*2));
  }
 
  void drawCircle() {
    fill(c);
    ellipse(x, y, (r*2), (r*2));
  }
 
}
 
 
//connects circles at the same y coordinate with the same radius with C1 being to the left of C2
void connectCircles(Circle C1, Circle C2) {
  C1.drawCircle();
  fill(C1.c);
  int topLeftX = C1.samplePoints[91][0];
  int topLeftY = C1.samplePoints[91][1];
  int xDistance = C2.samplePoints[31][0] - topLeftX;
  int yDistance = C2.samplePoints[31][1] - topLeftY;
  rect(topLeftX, topLeftY, xDistance, yDistance);
  C2.drawCircle();
}
 
//time is a ratio between 0 and 1 and angle is between -89 and 90
void splitCircle(Circle C1, Circle C2, int angle, float d1, float d2, float time) {
  int dist1 = round(d1*time);
  int dist2 = round(d2*time);
  pushMatrix();
  translate(C1.x, C1.y);
  rotate(radians(angle));
  Circle newC1 = new Circle(-dist1, 0, C1.r, C1.c);
  Circle newC2 = new Circle(dist2, 0, C2.r, C2.c);
  connectCircles(newC1, newC2);
  popMatrix();
}
 
void joinCircle(Circle C1, Circle C2, int angle, float d1, float d2, float time) {
  int dist1 = round(d1*time);
  int dist2 = round(d2*time);
  int x = round(cos(radians(angle))*d1);
  int y = round(sin(radians(angle))*d1);
  pushMatrix();
  translate(C1.x+x, C1.y+y);
  rotate(radians(angle));
  Circle newC1 = new Circle(round(dist1-d1), 0, C1.r, C1.c);
  Circle newC2 = new Circle(round(d2-dist2), 0, C2.r, C2.c);
  connectCircles(newC1, newC2);
  popMatrix();
}
 
//credit to Paul Bourke's method of finding the intersection points of 2 circles
float[] drawIntersectionCircles(Circle C1, Circle C2, float roffset) {
  float r0 = C1.r+roffset; float r1 = C2.r+roffset;
  int x0 = C1.x; int x1 = C2.x;
  int y0 = C1.y; int y1 = C2.y;
  int d = abs(y0 - y1);
  int x1fin = 0; int y1fin = 0; int x2fin = 0; int y2fin = 0;
  float a = (pow(r0, 2)-pow(r1, 2)+pow(d, 2))/(2*d);
  float h = sqrt(pow(r0, 2)-pow(a, 2));
  float x2 = x0 + (a*(x1-x0)/d);
  float y2 = y0 + (a*(y1-y0)/d);
  if(d<=C1.r+C2.r) {
    x1fin = round(x2 + (h*(y1-y0))/d);
    x2fin = round(x2 - (h*(y1-y0))/d);
    y1fin = round(y2 + (h*(x1-x0))/d);
    y2fin = round(y2 - (h*(x1-x0))/d);
    noFill();
    float angle1 = atan(((y1fin-y1)*1.0)/(x1fin-x1)) + PI;
    float angle2 = atan(((y1fin-y0)*1.0)/(x1fin-x0)) + PI;
    arc(x1fin, y1fin, 2*roffset, 2*roffset, angle1, angle2);
    float angle3 = atan(((y2fin-y1)*1.0)/(x2fin-x1));
    float angle4 = atan(((y2fin-y0)*1.0)/(x2fin-x0));
    arc(x2fin, y2fin, 2*roffset, 2*roffset, angle4, angle3);
    float[] angles = new float[2]; angles[0] = angle1; angles[1] = angle3;
    return angles;
  }
  else {
    float[] angles = new float[2]; angles[0] = 3*PI; angles[1] = 3*PI;
    return angles;
  }
}
 
int num = 10;
int r0 = 30;
int rblob = 10;
Circle[] circles = new Circle[0];
 
void init() {
  for(int i=0; i<num; i++) {
    if(i==0) {
      Circle C = new Circle(0, 0, r0, color(0));
      circles = (Circle[])append(circles, C);
    }
    else {
      int r = round(circles[i-1].r * (2.0/3));
      Circle C = new Circle(r-r0, 0, r, color(255));
      circles = (Circle[])append(circles, C);
    }
  }
}
 
void drawBlob(int whichFrame) {
  int y = (2*(r0/3)+15)/5;
  int r = rblob/5;
  Circle C = new Circle(0, 0, rblob, color(255));
  if(whichFrame<5) {
    C.y = (r0/2) + ((whichFrame+1)*y);
    float angles[] = drawIntersectionCircles(circles[0], C, 80.0);
    if(angles[0]<=2*PI && angles[1]<=2*PI) {
      angles[0] = (PI-angles[0])*(-1);
      angles[1] = PI+angles[1];
      arc(C.x, C.y, 2*C.r, 2*C.r, angles[0], angles[1]);
    }
    else C.drawCircle();
  }
  else {
    C.y = (r0/2)+(4*y);
    C.r = rblob - ((whichFrame-4)*r);
    C.drawCircle();
  }
}
 
void drawArtFrame (int whichFrame) {
  pushMatrix();
  rotate(PI/2);
  if(frameCount==1) init();
 
  strokeWeight(2);
  circles[0].drawCircle();
  for(int i=1; i<num; i++) { int rCenter = round(r0 - circles[i].r); float centerAngle = 360.0/(i+1); float sideAngle = radians((180-centerAngle)/2); float sideLength; if (sideAngle>0) sideLength = (rCenter * sin(radians(centerAngle)))/sin(sideAngle);
    else sideLength = rCenter * 2.0;
    float perimeter = sideLength * (i+1);
    float step = perimeter/10.0;
    float exteriorAngle = PI-(2*sideAngle);
 
    pushMatrix();
    translate(-rCenter, 0);
    rotate(-1*sideAngle);
    int current = 0;
    for(int j=0; j<((whichFrame-i+11)%10); j++) {
      if(floor(current+step)<=sideLength) {
        current = floor(current+step);
      }
      else {
        float increment = step - (sideLength - current);
        translate(round(sideLength), 0);
        rotate(exteriorAngle);
        current = floor(increment);
      }
    }
    circles[i].x = current;
    circles[i].drawCircle();
    popMatrix();
  }
  popMatrix();
 
  pushMatrix();
  rotate(PI);
  drawBlob(whichFrame);
  popMatrix();
  drawBlob((whichFrame+5)%10);
}