Instructor: Marcele
This is a write up for Interaction Lab SP18 Recitation on Processing Animation on Apr 12, 2019.
What I learnt
I learnt how to work with the PVector class. It was really convenient for what I was trying to do.
Interesting thing
From line 64 to line 73 of InkLeak.pde, I used Linear Algebra to smartly orient the special effect. It was such an enjoyable moment when I pieced together my half-unsure Math knowledge from high school, and see my program correctly automated.
class Node {
// mode code omitted
public void orientWith(Node that) {
PVector perpendi = new PVector(this.y - that.y, that.x - this.x);
if (
PVector.fromAngle(this.angle).dot(perpendi)
* PVector.fromAngle(that.angle).dot(perpendi)
< 0
) {
this.angle += PI;
}
}
}
Yet another proof of the famous saying, “Math is power”.
Source Code
Homework
static final float SPEED = .05;
static final float WEIGHT = .06;
float progress = 0f;
void setup() {
size(600, 600);
colorMode(HSB, 100);
rectMode(CENTER);
}
void draw() {
strokeWeight(WEIGHT);
scale(width, height);
background(0, 0, 100);
progress += SPEED;
float _size = (sin(progress) + 1f) * .3 + .15;
stroke(int(progress * 30) % 100, 100, 100);
PVector position = new PVector(mouseX / float(width), mouseY / float(height));
float radius = _size / 2f + WEIGHT / 2f;
if (position.x < radius) {
position.x = radius;
}
if (position.x + radius > 1f) {
position.x = 1f - radius;
}
if (position.y < radius) {
position.y = radius;
}
if (position.y + radius > 1f) {
position.y = 1f - radius;
}
rect(position.x, position.y, _size, _size);
strokeWeight(.03);
line(position.x, position.y, mouseX / float(width), mouseY / float(height));
}
Recitation creation
I used two sketch files.
InkLeak.pde is a library I wrote for an eariler lecture, see my Github.
r7_interactive_animation.pde is the main code. The content is here:
final int RADIUS = 66;
final float NOISE_MAG = .1f;
final float NOISE_SPEED = .02f;
float rotation = 0f;
float V = 4;
PVector pos;
float orient;
float noise_i = 0;
int echo_i = 0;
String echo_mode = "high";
Timer t;
int counter = 5;
boolean legacy = true;
boolean legacy_phase = false;
void setup() {
size(713, 577);
background(#233333);
pos = new PVector(width/2, height/2);
orient = PI / 4f;
t = new Timer();
background(255);
}
void draw() {
strokeWeight(1);
float target_rotation = new PVector(mouseX - width/2, mouseY - height/2).heading();
if (target_rotation - rotation > PI) {
rotation += PI*2f;
} else if (rotation - target_rotation > PI) {
rotation -= PI*2f;
}
rotation = rotation * .99 + target_rotation * .01;
translate(width / 2, height / 2);
rotate(rotation);
scale(0.5);
noise_i += NOISE_SPEED;
orient += (noise(noise_i) - .5f) * NOISE_MAG;
PVector v = PVector.fromAngle(orient);
v.mult(V);
pos.add(v);
if (pos.x = width - RADIUS) {
orient = PI - orient;
pos.x = .95 * pos.x + .05 * (width/2);
acc();
}
if (pos.y = height - RADIUS) {
orient = - orient;
pos.y = .95 * pos.y + .05 * (width/2);
acc();
}
while (orient < 0) {
orient += 2 * PI;
}
while (orient > PI * 2) {
orient -= 2 * PI;
}
noStroke();
fill(255);
ellipse(pos.x, pos.y, RADIUS * 2, RADIUS * 2);
stroke(#233333);
if (legacy) {
clsWithEcho();
} else {
echoClear(echo_mode);
}
/*while (t.spin(1000)) {
counter --;
text(str(counter), width/2, height/2);
}*/
stroke(255);
strokeWeight(10);
noFill();
rect(0, 0, width, height);
}
void acc() {
counter --;
if (counter == 0) {
switch (echo_mode) {
case "low":
echo_mode = "high";
background(255);
V = 4;
counter = 5;
break;
case "high":
echo_mode = "low";
background(255);
V = 7;
counter = 9;
break;
}
if (legacy_phase) {
legacy = ! legacy;
legacy_phase = false;
} else {
legacy_phase = true;
}
}
if (counter % 2 == 0) {
fill(#3EFFB6);
} else {
fill(#FFC0CB);
}
textSize(1300 * pow(2.718, float(-counter) / 2.5f));
text(str(counter), width/2 - 128, height * .5);
}
final int ECHO = 20;
final int ECHO_MODE = 0;
int echoPhase = 0;
void clsWithEcho() {
if (ECHO_MODE == 0) {
int times = int(height / ECHO);
int r;
for (int i = 0; i < times; i ++) {
r = int(random(height));
line(0, r, width, r);
}
} else if (ECHO_MODE == 1) {
echoPhase ++;
if (echoPhase > ECHO) {
echoPhase = 0;
}
for (int i = echoPhase; i < height; i += ECHO) {
line(0, i, width, i);
}
} else if (ECHO_MODE == 2) {
int times = int(height / ECHO);
for (int i = 0; i < times; i ++) {
line(int(random(width)), int(random(height)), int(random(width)), int(random(height)));
}
}
}