Mark Napier’s 3 Dots code is expansive; some 600 odd lines are spread over three files, and he uses several additional external libraries as well.[13] Even more than Snibbe, Napier makes use of object-oriented strategies. With the Bitmap255 object he creates a visual system capable of drawing translucent lines. In SpringyObject he creates sub-classes for springs and masses that behave according to the laws of physics. An instance of the SpringyObject is a particular system of masses and springs whose elements, locations and velocities can be simulated over time. In the main body of code Napier sets up an instance of such a system (SpringyDots): one fixed mass and a group of 3 movable masses connected by three springs, of varying tension. The spring to the fixed mass is not made visible.
class SpringyDots extends SpringyObject {
public SpringyDots() {
// Three masses connected by springs
Spring s;
Mass m0 = new Mass(300, 270); // center point (fixed)
Mass m1 = new Mass(170, 320); // left
Mass m2 = new Mass(300, 320); // middle
Mass m3 = new Mass(360, 320); // right
add(m0);
add(m1);
add(m2);
add(m3);
m0.setMovable(false);
m0.setMass(2);
m1.setMass(2);
m2.setMass(5);
m3.setMass(3);
s = new Spring(m0, m2);
s.setVisible(false);
s.springConstant = 500; // very mushy
add(s);
s = new Spring(m1, m2);
s.springConstant = 1000; // medium
add(s);
s = new Spring(m2, m3);
s.springConstant = 3000; // stiffer
add(s);
}
}
The “paint” method of “SpringyDotsPanel” is called in an infinite loop:
public void paint(Graphics g) {
Spring s = null;
Mass m = null;
int r = 0;
// Move the dots a step
dots.move();
// Draw trails into image
for (int i=0; i< springs.size(); i++){
s = (Spring)springs.elementAt(i);
if (s.visible) {
BMP.drawLine(
(int)s.mass1.x,
(int)s.mass1.y,
(int)s.mass2.x,
(int)s.mass2.y );
}
}
// Draw image to screen
BMP.paint(g);
// Switch drawing from dark to lite periodically
if (counter-- <= 0) {
if (BMP.targetColorValue == 0.0F)
BMP.targetColorValue = 255.0F;
else
BMP.targetColorValue = 0.0F;
counter = 40000;
}
// draw springs to screen
g.setColor(Color.green);
for (int i=0; i< springs.size(); i++) {
s = (Spring)springs.elementAt(i);
if (s.visible) {
g.drawLine(
(int)s.mass1.x,
(int)s.mass1.y,
(int)s.mass2.x,
(int)s.mass2.y );
}
}
// draw masses: larger mass makes bigger circle
g.setColor(Color.cyan);
for (int i=0; i< masses.size(); i++) {
m = (Mass)masses.elementAt(i);
r = m.m;
g.drawOval((int)(m.x - r), (int)(m.y - r) ,r*2, r*2);
}
}
It decrements a counter variable from 40,000 and it moves the mass and spring system and redraws its new positions. It draws the trace of each location of the visible springs, and switches colors between black and white each time the counter reaches 0.
Teasing the logic of Napier’s piece from its hundreds of lines of codes is more difficult and time consuming than in the other pieces discussed here, but the organization of the code into a hierarchical system of objects with discrete concerns and purposes makes it somewhat easier. Still, it is difficult to make the leap from an understanding of these individual systems to the subtle beauty created by the synergistic combination of the visual system and the physics simulation. Again, the experience of the piece is a more direct route to an understanding of the works procedural logic.
I encounter three dots in a static state: four objects at rest, three linked by lines. It is an invitation to my mouse; so, I click and drag each in turn. The unlinked circle remains where I place it, but the ganged objects continue to move along paths, which balance the play of my movements against their own internal logic of constraint and attraction. I have set the group in motion, but their animation continues without the necessity for my subsequent intervention. I can, by moving the objects, test the efficacy of further intercession, but I discover that though my introduction of variations in initial conditions results in possibly infinite differences in the particulars of the animation, the character of the visual output remains consistent, and the development of the system, according to its internal logic, holds my fascination even without further intervention.
There are clearly two systems at play here, the system of motion of the objects and the visual system of their traces. The former provides a source of three distinct continuous, sinuous lines, eccentric orbits that develop over time, while the later joins those lines in an unending series of translucent threads. As the piece runs, the motion of the objects leave an increasingly complex and layered mass of lines that take on the appearance of depth and shape in space. Intersecting paths create regions of density that delineate those shapes. Depth becomes a function of time and I look back into the system’s history seeing its tendencies, its gravitational foci. As soon as the preferred regions of space are obliterated by the aggregate opacity of the lines, a reversal occurs and the traces assert their legibility as darkness instead of light. When the darkness has consumed these same regions the applet reverses course again.
This piece differs from Wattenberg’s and Snibbe’s in that the user is presented not with a series of instantiations from which they may infer the rules of the system, but rather a continuous development of a single instance from which the user can derive the logic of the system by thoughtful observation over time. In either case the reasoning is inductive, but the nature of the viewers insertion into the system is different. In this piece the user need not call up each instance through interaction. Although the user contributes to the setting of the initial conditions to which a chaotic system is sensitive, the conditions set in the code itself, by the author, are determinative of the outcome to an even greater degree. The temporal dimension is what allows for the unfolding of an empathetic relationship to the applet’s system to develop. The subtle properties of the piece’s visual system accrue over time so that the user’s interventions are devalued. The modularity of the total system allows for the marriage of the simulation with the display, which together produce the temporal dependence and the shallow interactivity.[14] The mechanism of viewership, however, is not really different. The fascination of the work lies in the apprehension of its procedural logics, physical and visual, as well as the relationship between them.
[13] Code libraries are standardized sets of tools that accomplish common programming tasks and can be incorporated into the code so that they don’t have to be programmed from scratch by the author.
[14] The severability of these two logics is underlined by Wattenberg’s “remix commentary,” a hybrid of Snibbe’s and Napier’s pieces which although interesting for just this reason, is less successful in its visual or cybernetic impact. (http://artport.whitney.org/commissions/codedoc/Remix/NapierSnibbe.html)