-
Notifications
You must be signed in to change notification settings - Fork 2
/
day_15.pde
141 lines (111 loc) · 2.96 KB
/
day_15.pde
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
import java.util.List;
float margin = 50;
// The buffer where we draw the letter
PGraphics letterCanvas;
// Text options
String text = "codecember";
int letterIndex = 0;
int changeFrame = 200;
List<Particle> particles;
/**
* Particle class, pretty simple
* stores a target destination and the previous one
*/
class Particle {
PVector location, velocity, acceleration;
PVector previousTarget, target;
float speed;
Particle(float x, float y, float speed) {
location = new PVector(x, y);
this.speed = speed;
this.velocity = new PVector(0, 0);
this.acceleration = new PVector(0, 0);
}
/**
* Set the target of the particle, switch the previous one
*/
void setTarget(PVector newTarget) {
this.previousTarget = this.target;
this.target = newTarget;
}
/**
* The farthest from the target the speedier (bad english here ;)
*/
void updateVelocity() {
PVector diff = PVector.sub(target, location);
float acc = map(diff.mag(), 0, 50, 0, 0.05);
acceleration = diff.mult(acc * speed);
}
void update() {
updateVelocity();
velocity.add(acceleration);
// Limit to not go too fast
velocity.limit(2);
location.add(velocity);
}
/**
* Display a line between two targets
*/
void display() {
stroke(0, 50);
strokeWeight(1);
line(location.x, location.y, target.x, target.y);
}
}
/**
* Change the letter and assign new random targets
*/
void changeLetter() {
char letter = text.charAt((letterIndex++) % text.length());
// Display the letter
letterCanvas.beginDraw();
letterCanvas.background(255, 0);
letterCanvas.textAlign(CENTER, CENTER);
letterCanvas.fill(0);
letterCanvas.textSize(400);
letterCanvas.text(letter, width / 2, height / 2 - 100);
letterCanvas.endDraw();
assignTargets();
}
/**
* Check for black pixels and assign new targets
*/
void assignTargets() {
List<PVector> targets = new ArrayList<PVector>();
letterCanvas.loadPixels();
for (int x = 0; x < letterCanvas.width; x++) {
for (int y = 0; y < letterCanvas.height; y++) {
if (letterCanvas.pixels[x + y * letterCanvas.width] == color(0)) {
targets.add(new PVector(x, y));
}
}
}
for (int i = 0; i < particles.size(); i++) {
if (targets.size() != 0) {
int randomTargetIndex = int(random(targets.size()));
particles.get(i).setTarget(targets.remove(randomTargetIndex).copy());
}
}
}
void setup() {
size(500, 500);
// Create the buffer
letterCanvas = createGraphics(width, height);
// Create random particles
particles = new ArrayList<Particle>();
for (int i = 0; i < 1500; i++) {
particles.add(new Particle(random(margin, width - margin), random(margin, height - margin), random(0.1, 1.5)));
}
// Initialize first letter
changeLetter();
}
void draw() {
background(255);
if (frameCount % changeFrame == 0) {
changeLetter();
}
for (Particle particle : particles) {
particle.display();
particle.update();
}
}