## Why we need arrays

```// Is there a better way to have multiple particles?   float px0 = 200; float py0 = 200; float px1 = 200; float py1 = 200; float px2 = 200; float py2 = 200;   void setup(){ size(400,400); }   void draw(){ background(255); fill(255,0,0);   px0 += random(-2,2); py0 += random(-2,2); ellipse(px0,py0,10,10);   px1 += random(-2,2); py1 += random(-2,2); ellipse(px1,py1,10,10);   px2 += random(-2,2); py2 += random(-2,2); ellipse(px2,py2,10,10); }```

## Macaroni Clock

```// A clock made of annular sections. // Demonstrates: // -- Use of beginShape()/endShape() with for{} // -- Calculation of current time // -- Proportions (60 seconds = 360 degrees) // -- Custom methods: the macaroni() function   void setup(){ size(300,300); }   void draw(){ background(180); noStroke(); smooth();   float cx = width/2; float cy = height/2; float a0 = -90; float angDeg, angRad; float x,y;   // Clock frame fill(0); macaroni (100,120,a0,a0+360,cx,cy,60);   // Second fill(255,210,44); float fractionThruTheMinute = second()/60.0; //0...1 angDeg = a0 + fractionThruTheMinute*360.0; macaroni ( 80, 100, /* inner & outer radii */ a0, angDeg, /* start & end angles, in degrees */ cx, cy, /* center coordinates */ second()); /* resolution */   // Minute fill(44,161,255); float fractionThruTheHour = minute()/60.0; //0...1 angDeg = a0 + fractionThruTheHour*360.0; macaroni ( 60, 80, /* inner & outer radii */ a0, angDeg, /* start & end angles, in degrees */ cx, cy, /* center coordinates */ minute()); /* resolution */   // Hour fill(234,28,28); int h = hour()%12; float fractionThruTheHalfDay = h/12.0; //0...1 angDeg = a0 + fractionThruTheHalfDay*360.0; macaroni ( 40, 60, /* inner & outer radii */ a0, angDeg, /* start & end angles, in degrees */ cx, cy, /* center coordinates */ hour()*5); /* resolution */ }       //========================================== void macaroni ( float r1, float r2, /* inner & outer radii */ float a1, float a2, /* start & end angles, in degrees */ float cx, float cy, /* center coordinates */ int res){ /* resolution */   beginShape(TRIANGLE_STRIP); for (int i=0; i<=res; i++){ float frac = (float)i/(float)res; // 0..1 float thetaDeg = a1 + frac*(a2-a1); float x1 = cx + r1 * cos(radians(thetaDeg)); float y1 = cy + r1 * sin(radians(thetaDeg)); vertex(x1, y1);   float x2 = cx + r2 * cos(radians(thetaDeg)); float y2 = cy + r2 * sin(radians(thetaDeg)); vertex(x2, y2); } endShape(); }```

## Regular clock

```void setup(){ size(300,300); }   void draw(){ background(255); smooth();   float sr = 100; float mr = 80; float hr = 50; float cr = 210;     float cx = width/2; float cy = height/2; float r = 100;   strokeWeight(5); ellipse(cx,cy, cr,cr);   float angDeg, angRad; float x,y;     float a0 = -90; float fractionThruTheMinute = second()/60.0; //0...1 angDeg = a0 + fractionThruTheMinute*360.0; angRad = radians(angDeg); x = cx + sr * cos(angRad); y = cy + sr * sin(angRad); strokeWeight(0.5); line(cx,cy, x,y);   float fractionThruTheHour = minute()/60.0; //0...1 angDeg = a0 + fractionThruTheHour*360.0; angRad = radians(angDeg); x = cx + mr * cos(angRad); y = cy + mr * sin(angRad); strokeWeight(2.5); line(cx,cy, x,y);   int h = hour()%12; float fractionThruTheHalfDay = h/12.0; //0...1 angDeg = a0 + fractionThruTheHalfDay*360.0; angRad = radians(angDeg); x = cx + hr * cos(angRad); y = cy + hr * sin(angRad); strokeWeight(4); line(cx,cy, x,y);   }```

## Macaroni (annular section)

```//========================================== // THIS IS ONLY THE MACARONI FUNCTION // YOU GOTTA USE IT YOUSEF void macaroni ( float r1, float r2, /* inner & outer radii */ float a1, float a2, /* start & end angles, in degrees */ float cx, float cy, /* center coordinates */ int res){ /* resolution */   beginShape(TRIANGLE_STRIP); for (int i=0; i<=res; i++){ float frac = (float)i/(float)res; // 0..1 float thetaDeg = a1 + frac*(a2-a1); float x1 = cx + r1 * cos(radians(thetaDeg)); float y1 = cy + r1 * sin(radians(thetaDeg)); vertex(x1, y1);   float x2 = cx + r2 * cos(radians(thetaDeg)); float y2 = cy + r2 * sin(radians(thetaDeg)); vertex(x2, y2); } endShape();   }```

## Generate a spiral

The following example generates a spiral.
This code example is worth studying for several reasons:

• It demonstrates the trigonometric math used to generate circles, namely sin(), cos()
• It illustrates the use of the radians() function, which converts an angular measurement in degrees to an angular measurement in radians (which is required for sin() and cos()).
• It illustrates that circle-generating math can be used for something other than “just” circles.
• It demonstrates a way of using beginShape()/endShape() with a for{} loop, in order to computationally generate and render a series of points.
```// GENERATE A SPIRAL   size(300,300); background(255);   float centerX = width/2; float centerY = height/2; float radius = 0;   float nLoops = 3; float nDegreesPerLoop = 360; float nDegreesTotal = nLoops * nDegreesPerLoop;   noFill(); beginShape();   for (float angleDeg=0; angleDeg<nDegreesTotal; angleDeg++){ float angleRad = radians(angleDeg); // the radians version of that angle float x = centerX + radius * cos(angleRad); float y = centerY + radius * sin(angleRad); vertex(x,y); radius += 0.1; // increase the radius for each point! } endShape();```

## Quick side note on Assignment 406: Auto-load result

It turns out to be easy for Processing to load images from remote web sites. Unfortunately this functionality is usually blocked for Applets, due to Java’s security restrictions. (There are some tricky ways of getting around this.) Nonetheless, this functionality is not blocked for programs running within the Processing environment itself, or in standalone executables exported from Processing. For Assignment 406, you can automatically load the PNG generated by the Google Chart API, as follows:

```PImage pimg; void setup(){ size(300,100); String googurl = "http://chart.apis.google.com/chart?cht=p3&chd=t:7,13&chs=300x100&chl=Placebo|Ersatzspieler"; byte sts[] = loadBytes(googurl); saveBytes("chart.png", sts); pimg = loadImage("chart.png"); int n = googurl.length(); println(n); } void draw(){ image(pimg,0,0,300,100); }```

## Notes from Wednesday, Sept. 24

Beginnings of a circular clock:

```void setup(){ size(200,200); }   void draw(){ background(255); ellipse(100,100, 160,160);   float fractionOfAMinute = second()/60.0; float degs = fractionOfAMinute * 360.0; float x = 80 * cos(radians(degs)); float y = 80 * sin(radians(degs)); line (100,100, 100+x,100+y); }```

Progress Bar:

```// PROGRESS BAR   boolean bScreenIsWhite = true; boolean bTaskInProgress = false; int clickTime = 0;   int taskCompletionTime = 120; int barW = 150;   //------------------------------------- void setup(){ size(300,300); }   //------------------------------------- void draw(){ if (bScreenIsWhite){ background(255); } else { background(0); }   fill(64); rect(75,75, barW,50);   int elapsed = frameCount - clickTime; if (bTaskInProgress){ if (elapsed > taskCompletionTime){ bScreenIsWhite = !bScreenIsWhite; bTaskInProgress = false; } else { float fractionComplete = (float)elapsed/(float)taskCompletionTime; float rw = fractionComplete * barW; fill(192); rect(75,75, rw,40); } } }   //------------------------------------- void mousePressed(){ clickTime = frameCount; bTaskInProgress = true; }```

Simple Clock:

```// VERY simple clock void setup(){ size(300,300); strokeWeight(5); }   void draw(){ background(255); int h = hour(); int m = minute(); int s = second();   line(0,50, h,50); line(0,100, m,100); line(0,150, s,150); }```

## Dashed Line example

```// DASHED LINE float dashLength = 8; // pixels   void setup(){ size(300,300); }   void draw(){ background(255); dashedLineYinz (150,150, mouseX, mouseY); dashedLineYinz (0,0, mouseX, mouseY); }     //====================================================== // Here's the dashedLine function we wrote in class. void dashedLineYinz (float x0, float y0, float x1, float y1){ stroke(0); smooth();   // How many ticks do we want? float lineLength = getLength(x0,y0, x1,y1); int nTicks = (int) (lineLength / dashLength);   // Add an extra tick for aesthetic reasons, // if the number of ticks is even (this guarantees // there are solid dashes on both ends of the line) if (nTicks%2 == 0){ nTicks++; }   for (int i=0; i<nTicks; i++){ if (i%2 == 0){ float t = (float)i/ (float)nTicks; // 0....1 float u = (float)(i+1)/(float)nTicks; float px = interpolate (x0, x1, t); float py = interpolate (y0, y1, t); float qx = interpolate (x0, x1, u); float qy = interpolate (y0, y1, u); line(px,py, qx,qy); } } }   //====================================================== // Here's the interpolate function we wrote in class. float interpolate (float v1, float v2, float t){ float vi = v1 + (v2 - v1)*t; return vi; }   //====================================================== // Here's the getLength function we wrote in class. float getLength (float x1, float y1, float x2, float y2){ float dx = x2-x1; float dy = y2-y1; float L = sqrt(dx*dx + dy*dy); return L; }     //====================================================== // This function is syntactically compatible with the others // but just draws a plain old line. void dashedLineBogus (float x0, float y0, float x1, float y1){ stroke(0); smooth(); line(x0,y0, x1,y1); }   //====================================================== // This function is syntactically compatible with the others. // It's another version of the "dashedLine" function that // I had written earlier. It does not call the getLength() // or interpolate() functions; rather, it embeds their code. // void dashedLine(float x0, float y0, float x1, float y1){ stroke(0); smooth();   // Compute the length of the total line // using the Pythagorean theorem, C = sqrt(A*A + B*B). float dx = x1-x0; // difference in X values float dy = y1-y0; // difference in Y values float lineLength = sqrt(dx*dx + dy*dy);   // The number of dashes is the lineLength divided by the dashLength. int nDashes = (int)(lineLength/dashLength);   // If the number of dashes is even, the last dash will be blank. // Add an extra dash if this is the case. if (nDashes%2 == 0){ nDashes++; }   // For each dash for (int i=0; i<nDashes; i++){   // Only draw even dashes -- odd ones are not drawn (blank). if (i%2 == 0){   // To compute the start and end point of the i'th dash. // We first have to compute the fractions representing // the percentage of the way across the line, // where the dash starts and ends. ("Interpolation") // We use the pattern: p = p0 + (p0-p1)*fraction. float fraction_i = (float)i /(float)nDashes; float fraction_j = (float)(i+1)/(float)nDashes;   // Compute the start point of the i'th dash. float pxi = x0 + (x1-x0)*fraction_i; float pyi = y0 + (y1-y0)*fraction_i;   // Compute the end point of the i'th dash float pxj = x0 + (x1-x0)*fraction_j; float pyj = y0 + (y1-y0)*fraction_j;   // Draw the i'th dash line(pxi,pyi, pxj,pyj); } } }```

## getLength function (distance between two points)

```float getLength (float x1, float y1, float x2, float y2){ float dx = x2-x1; float dy = y2-y1; float L = sqrt(dx*dx + dy*dy); return L; }```