Your browser does not support the canvas tag.

Week 4

Artists

A lot of you are looking up stuff in the API to use in your assignemnts. This is awesome! Here are some that stand out. frameRate, frameCount, noLoop(), while loops, millis, modulo and pgraphics. I've got something about all but pgraphic which is a bit more advanced than where we're at.

frameRate
A couple students used this to slow down their projects, and it makes sense. Changing the frameRate speeds up or slows down how fast the draw loops. The default if you don't set it is 60 frames per second. I see the simplicity in using frameRate but I don't like using it. I would rather use other methods to slow something down, because it limits your options. If your framerate is 12 then EVERYTHING slows down to 12 fps.

frameCount
Framecount is awesome and can be really useful. It's a number that counts every frame starting from the first time you run the program. You cannot change the frameCount, but you can easily access it. There's en example on how to use it in the modulo description.

While Loops
While loops are realtives to for loops. Like the for loop the program will stay in a while loop until the condition of the while has been met. Usually I use for loops - even though they look more complicated it's harder to have them crash. if you forget to iterate the variable in the while loop it will hang. It used to crash HARD - like "shut down you computer" hard, but not it just stops working like a normal crash. Y'all have it easy!

void setup(){
  size(500, 300); 
}

void draw(){
  background(200); 
  int i = 0; 
  while(i < 20){
    i ++; 
    ellipse(i * 20, 20, 20, 20); 
  }
}

millis();

Iterating an int is a fine way to create a timer, but if you need a timer that is accurate, you need to use millis().
Like frameCount millis() starts counting the moment you turn on your program and does not stop. You can't reset millis until you restart your program. The cool thing is millis() is tied to the clock on your computer, so no matter how much code you have it will still be accurate.

color RanColor;  
long timer; 
int interval = 1000; 

void setup() {
  size(300, 300); 
  RanColor = color(random(255), random(255), random(255));
  timer = millis(); 
}

void draw() {
  background (RanColor);
  if (millis() - timer > interval) {
    timer = millis(); 
    RanColor = color(random(255), random(255), random(255));
  }
}
To help understand the millis() think of a boat floating down a river. To measure how far the boat has gone, stick a pole onto the river bank where the boat currently is and measure how far the boat has traveled relative to the pole. When it has reached a pre-determined distance stick another pole in the bank and start again. In this analogy, millis() is the river. It is a constant that cannot be reset, but we can still use it to tell accurate time.

Note that we use a variable called a "long" instead of an int. Longs can be much larger numbers than ints. If we left the timer variable as an int it would work for several minutes before crashing.

Modulo %
A: The % is the symbol for Modulo which is a fancy way of saying "the remainder". The remainder is what's left over when you divide one number into another. For example, 22 % 9 would equal 4 because nine goes evenly into 22 twice (18) and 22 - 18 = 4.
If the number on the left side of the modulo is smaller than the right, (say 7 % 9) you are asking the program to divide 7 by 9. The result is 7 because nine goes into seven zero times with the remained of 7
This means that it's a handy, albeit slightly confusing way to keep something on the screen.

int locX; 
void setup() {
  size(300, 100);
}
void draw() {
  if(frameCount%60 == 0){ 
    background(random(255), random(255), random(255)); 
  }
  locX ++; 
  if(locX%width== 0){
    locX = 0; 
  }  
  fill(255); 
  ellipse(locX, 50, 30, 30); 
}
Modulo is often used in math for creating a cypher.
This is jumping ahead, but it's a cool trick. Here we use modulo to help make a grid without using nested for loops - more on this when we start messing with pixel arrays.
void setup() {
  size(400, 400); 
}
void draw() {
      int rectSize = 20; 
  for (int i = 0; i < 81; i ++) {
    int w = (i % 9) * rectSize;  
    int h = (i / 9) * rectSize; 
    rect(w, h, rectSize, rectSize);
  }
}

Getting the time

PFont font; 
int h, m, s; 
void setup() {
  font = createFont("Times", 20); 
  textFont(font); 
  size(400, 400);
  smooth();
}
void draw() {
  h = hour(); 
  m = minute(); 
  s = second(); 
  background(200); 
  fill(1); 
  text(h + ":" + m +":" + s, 20, 20);
}

Using modulo to make something happen evey 5 seconds.
boolean sFlag; 
void setup() {
  size(400, 400);
}
void draw() {
  background(200); 
  int s = second(); 
  if (s % 5 == 0 && sFlag == false) {
    sFlag = true; 
    println("joe is good: " + s);
  }
  if (s % 5 != 0) {
    sFlag = false;
  }
}

Rotation Part 1

float r2 = 0;

void setup() {
  size(600, 600); 
  smooth();
}

void draw() {
  r2 += .02;
  rotate(r2); 
  rect(width/2, height/2, 20, 20);
}
Why does this sketch not simply rotate the square? It is because the rotate command always wants to rotate around the point 0, 0. So to counteract that we need to temporarily set the point 0, 0 to the location where we want to draw the square. We do this with "translate".
float r2 = 0;

void setup() {
  size(600, 600); 
  smooth();
  rectMode(CENTER); 
}

void draw() {
  background(200); 
  r2 += .02;
  translate(width/2, height/2); 
  rotate(r2); 
  rect(0, 0, 20, 20);
}
This works great, but if we want to draw anything else on the screen now our coordinates are all messed up. We get around this with pushMatrix and popMatrix. pushMartix captures the current state of the coordinate, and popMatrix resets the coordinates when we are done.
translate
float r2 = 0;

void setup() {
  size(600, 600); 
  smooth();
  rectMode(CENTER); 
}

void draw() {
  background(200); 
  r2 += .02;
  pushMatrix(); // save the current state
  translate(width/2, height/2); 
  rotate(r2); 
  rect(0, 0, 20, 20);
  popMatrix(); // reset coordinates
  rect(60, 60, 50, 30); 
}
Notice in the sketch above that the x and y values for the rect are 0,0? This is because we translated to the new location and 0, 0 is now what the center of the stage used to be.
So what about the rotation being such a small number? Rotation works on radians instead of degrees.

A better question is why we settled on 360 for degrees in the first place? The ancient Sumerians had a Sexagesimal (base 60) number system, so it goes back about 4000 years. While we have 10 fingers including thumbs, we also have 12 finger segments on each hand (not including thumbs). 12 goes into 60 nicely, and 60 goes well into 360.
Radians, on the other hand, are directly linked to the geometry of the circle so while I love me some ancient Sumerians, most mathematicians prefer using raidans if possible. If PI is the ratio of a circle's circumference to it's diameter, TWO PI is the ratio of circle's circumference to it's RADIUS.

Rotation Part 2 - rotating something without translating
Having something rotate by pushing and poping is great, but it can get complicated when you have multiple push pops inside other push pops. What if you need the location of an object that is inide one of these transforms? That can get tricky, and fortunately there's another way to calculate rotation that you should know. Unfortunately it involves some trig, but please try not to freak out because it's actually not that hard.


Officially cosine is the "trigonometric function that is equal to the ratio of the side adjacent to an acute angle (in a right-angled triangle) to the hypotenuse".
What does this mean? If you ask the computer for the cos() of an angle in radians, it will give you an answer for how far over the x value would be if the radius of the circle was 1. Sin() does the same thing with the y value. (In programing, reducing a number to a value between -1 and 1 is called "normalizing".) So if we have an angle we can use sin() and cos() to get the value of what x and y would be if the radius was 1 and the center of the circle was at 0, 0.
Then we just multiply both these x and y values by the actual radius to get the x and y values scaled up.
The final step is to add these values to the x and y of the center of the circle.

A more in-depth but still simple explanation is availalbe at math is fun

Fortunately, if you must, you can easily convert degrees to radians using radians(angle). But it's an extra step

Usually, With Cartesain Coordinates, we define a point with X and Y, however, now we can use r and ∅ (Radiaus and Theta) to define a point. This is called a Polar Coordiante system.
NOTE- if you look around on the inter-webs, it will appear that our circle rotates in the opposite direction, however, in standard Cartesian coordinates used in math, the y value gets LOWER as it goes down so the values get flipped. Upshot - don't panic.
	float r = 0; 
	float radius = 60; 

	void setup() {
	  size (400, 400);
	  smooth();
	}

	void draw() {
	  background(100);
	  r += .1; 
	  float px = mouseX  + cos(r)* radius;
	  float py = mouseY  + sin(r)* radius;
	  ellipse(px, py, 5, 5);
	}
	

Okay, but what if you know the location of two points and need the rotation. Again, processing is your math buddy - you can use the atan2() function to get the radians between any two points.

HEY! - Notice that atan2() asks for the Y value then the x value. Usually it's the other way around so don't get messed up.

float blockX = 200; 
float blockY = 200;  
float speed = 4; 

void setup() {
    size (400, 400);
   rectMode(CENTER);
    smooth(); 
  }
  void draw() {
    background(200); 
    float rot = atan2(mouseY-blockY, mouseX-blockX);
    blockX +=  cos(rot)*(speed); // current location + the next "step"
    blockY +=  sin(rot)*(speed);
    pushMatrix();
    translate(blockX, blockY); 
    rotate(rot); 
    rect(0, 0, 40, 10); 
    popMatrix();   
  }

Lab Week 4
Make a clock with a second hand, minute hand, and hour hand that rotates accurately. Use an actual picture of a clock from the Internet as a background. This might be hard - that's okay. There are a few ways to do this assignment. Don't steal code - try it yourself.

Experimental Clock project introduction

This is NOT DUE next week. This is your first major assignment. I give it now to start the thinking process.
Make a sketch that tells time (and the date if you want), BUT is not a standard clock or calendar. The clock may be abstract or representational, just as long as it doesn't look like a clock.


Time Presentation