-
Notifications
You must be signed in to change notification settings - Fork 0
/
NFrostN.pde
242 lines (215 loc) · 5.88 KB
/
NFrostN.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
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
import java.io.IOException;
import java.util.Random;
public class NFrostN {
//declare variables
private float scale;
//holds width argument
private int gridWidth;
//holds height argument
private int gridHeight;
//holds density argument
private int particleDensity;
//holds seed argument
private int seed;
//holds value of the grid used only internally for algorithm
private boolean[][] grid;
//counter that holds filled amount
private int filled = 0;
//declare random
private Random ran;
private int frostColor = 255;
//declare diffusion variables
private int diffuseW;
private int diffuseH;
private boolean beginDiffuse = true;
private int remainingSteps = 0;
private int diffuseDir=0;
/**
this is the constructor it takes a width and height for grid. the density of particles to the full grid before the algorithm stops
a seed for the random number generator 0 picks random seed. the scale is how big the particle is drawn.
**/
public NFrostN(int gridWidth, int gridHeight, int particleDensity, int seed, float scale) {
//initialize everything!
this.gridWidth = (int)(gridWidth/scale);
this.gridHeight = (int)(gridHeight/scale);
this.particleDensity = particleDensity;
this.seed = seed;
this.scale = scale;
grid = new boolean[gridWidth][gridHeight];
//init grid to false for empty
for (int i = 0; i<this.gridWidth; i++) {
for (int j = 0; j<this.gridHeight; j++) {
grid[i][j] = false;
}
}
//init random
if (seed == 0) {
ran = new Random();
} else {
ran = new Random(seed);
}
}
//this will fully diffuse a new particle until it runs out
//of steps or finds another particle to stick to
public void diffuseParticle() {
//check if this is the beginning of new diffusion
if (beginDiffuse) {
beginDiffuse = false;
diffuseW = ran.nextInt(gridWidth);
diffuseH = ran.nextInt(gridHeight);
remainingSteps = (2*(gridWidth * gridHeight));
//the random startw and starth needs to be empty
while (!isEmpty(diffuseW, diffuseH)) {
diffuseW = ran.nextInt(gridWidth);
diffuseH = ran.nextInt(gridHeight);
}
}
while (remainingSteps > 0) {
//check if the particle can stick
if (checkNeighbors()) {
beginDiffuse = true;
grid[diffuseW][diffuseH] = true;
filled++;
//drawing this circle makes a sparkling affect when the particle sticks
fill(frostColor);
circle(diffuseW*scale, diffuseH*scale, scale+5);
return;
}
moveParticle();
//uncomment the following to the see the path the particle diffuses the
//transparancy makes it darker in the locations visited more than once. it looks awfully familiar... almost like land.
//could this be a way to procedurally generate some land?
//if(keyPressed){
//fill(frostColor,50);
//circle(diffuseW*scale, diffuseH*scale, scale);
//}
remainingSteps--;
}
//if we reached here it has diffused until it ran out of energy
beginDiffuse = true;
grid[diffuseW][diffuseH] = true;
filled++;
}
private void moveParticle() {
diffuseDir = ran.nextInt(4);
if (diffuseDir == 0) {
moveN();
}
if (diffuseDir == 1) {
moveE();
}
if (diffuseDir == 2) {
moveS();
}
if (diffuseDir == 3) {
moveW();
}
}
private void moveN() {
if (diffuseH == 0) {
diffuseH = (gridHeight - 1);
} else {
diffuseH--;
}
}
private void moveS() {
if (diffuseH == gridHeight - 1) {
diffuseH = 0;
} else {
diffuseH++;
}
}
private void moveE() {
if (diffuseW == gridWidth - 1) {
diffuseW = 0;
} else {
diffuseW++;
}
}
private void moveW() {
if (diffuseW == 0) {
diffuseW = (gridWidth - 1);
} else {
diffuseW--;
}
}
//this will check if a neighbor north west south or east are turned on.
private boolean checkNeighbors() {
if (checkNorth()) {
return true;
}
if (checkEast()) {
return true;
}
if (checkSouth()) {
return true;
}
if (checkWest()) {
return true;
}
return false;
}
/**
* @return returns true if pixel up is on
*/
private boolean checkNorth() {
//if at the top wrap to bottom
if (diffuseH == 0) {
return grid[diffuseW][(gridHeight-1)];
}
//else check pixel above
return grid[diffuseW][(diffuseH-1)];
}
/**
* @return returns true if pixel to the right is on
*/
private boolean checkEast() {
//if at the right edge wrap to left
if (diffuseW == (gridWidth-1)) {
return grid[0][(diffuseH)];
}
//else check pixel right
return grid[(diffuseW+1)][(diffuseH)];
}
/**
* @return True if pixel to the left is on
*/
private boolean checkWest() {
//if at the left wrap to the right
if (diffuseW == 0) {
return grid[gridWidth-1][(diffuseH)];
}
//else check pixel left
return grid[(diffuseW-1)][diffuseH];
}
/**
* @return Returns true if pixel south is on
*/
private boolean checkSouth() {
//if at the bottom wrap to top
if (diffuseH == (gridHeight-1)) {
return grid[diffuseW][(0)];
}
//else check pixel below
return grid[diffuseW][(diffuseH+1)];
}
//returns true if the cell at w, h is empty
private boolean isEmpty(int w, int h) {
return !grid[w][h];
}
//this will return true if the particle density has been met.
public boolean isParticleDensityMet() {
return (100*((double)filled/(gridWidth*gridHeight))>= particleDensity);
}
//This will iterate through the 2d array and draw each element that is on
public void renderGrid() {
fill(frostColor);
for (int i = 0; i<gridWidth; i++) {
for (int j = 0; j<gridHeight; j++) {
if (grid[i][j] == true) {
square(i*scale, j*scale, scale);
}
}
}
}
}