1 class L8onLife extends SCPattern {
2 // Controls the rate of life algorithm ticks, in milliseconds
3 private BasicParameter rateParameter = new BasicParameter("DELAY", 112.5, 0.0, 1000.0);
4 // Controls if the cubes should be randomized even if something changes. Set above 0.5 to randomize cube aliveness.
5 private BasicParameter randomParameter = new BasicParameter("RAND", 0.0);
6 // Controls the brightness of dead cubes.
7 private BasicParameter deadParameter = new BasicParameter("DEAD", 25.0, 0.0, 100.0);
8 // Controls the saturation.
9 private BasicParameter saturationParameter = new BasicParameter("SAT", 90.0, 0.0, 100.0);
11 public final double MIN_ALIVE_PROBABILITY = 0.2;
12 public final double MAX_ALIVE_PROBABILITY = 0.9;
14 private final SinLFO xPos = new SinLFO(0, model.xMax, 4500);
15 private final SinLFO zPos = new SinLFO(0, model.zMax, 2500);
18 // Index of cube in glucose.model.cubes
20 // Boolean which describes if cube is alive.
22 // List of this cubes neighbors
23 public List<Integer> neighbors;
25 public CubeState(Integer index, boolean alive, List<Integer> neighbors) {
28 this.neighbors = neighbors;
32 // Contains the state of all cubes by index.
33 private List<CubeState> cube_states;
34 // Contains the amount of time since the last cycle of life.
35 private int time_since_last_run;
36 // Boolean describing if life changes were made during the current run.
37 private boolean any_changes_this_run;
39 private List<Boolean> new_lives;
41 public L8onLife(GLucose glucose) {
44 //Print debug info about the cubes.
48 time_since_last_run = 0;
49 any_changes_this_run = false;
50 new_lives = new ArrayList<Boolean>();
52 addParameter(rateParameter);
53 addParameter(randomParameter);
54 addParameter(deadParameter);
55 addParameter(saturationParameter);
56 addModulator(xPos).trigger();
57 addModulator(zPos).trigger();
60 public void run(double deltaMs) {
64 any_changes_this_run = false;
66 time_since_last_run += deltaMs;
68 for (Cube cube : model.cubes) {
69 cube_state = this.cube_states.get(i);
71 if(shouldLightCube(cube_state)) {
80 boolean should_randomize_anyway = (randomParameter.getValuef() > 0.5);
81 if(should_randomize_anyway || !any_changes_this_run) {
82 randomizeCubeStates();
87 if(time_since_last_run >= rateParameter.getValuef()) {
88 time_since_last_run = 0;
92 public void lightLiveCube(Cube cube) {
93 for (LXPoint p : cube.points) {
94 float hv = max(0, lx.getBaseHuef() - abs(p.z - zPos.getValuef()));
95 colors[p.index] = lx.hsb(
97 saturationParameter.getValuef(),
103 public void lightDeadCube(Cube cube) {
104 for (LXPoint p : cube.points) {
105 float hv = max(0, lx.getBaseHuef() - abs(p.x - xPos.getValuef()));
106 double dead_bright = deadParameter.getValuef() * Math.random();
108 colors[p.index] = lx.hsb(
110 saturationParameter.getValuef(),
116 public void outputCubeInfo() {
118 for (Cube c : model.cubes) {
119 print("Cube " + i + ": " + c.x + "," + c.y + "," + c.z + "\n");
122 print("Edgeheight: " + Cube.EDGE_HEIGHT + "\n");
123 print("Edgewidth: " + Cube.EDGE_WIDTH + "\n");
124 print("Channelwidth: " + Cube.CHANNEL_WIDTH + "\n");
127 private void initCubeStates() {
128 List<Integer> neighbors;
129 boolean alive = false;
130 CubeState cube_state;
131 this.cube_states = new ArrayList<CubeState>();
134 for (Cube c : model.cubes) {
135 neighbors = findCubeNeighbors(c, i);
137 cube_state = new CubeState(i, alive, neighbors);
138 this.cube_states.add(cube_state);
143 private void randomizeCubeStates() {
144 double prob_range = (1.0 - MIN_ALIVE_PROBABILITY) - (1.0 - MAX_ALIVE_PROBABILITY);
145 double prob = MIN_ALIVE_PROBABILITY + (prob_range * Math.random());
147 //print("Randomizing cubes! p = " + prob + "\n");
149 for (CubeState cube_state: this.cube_states) {
150 cube_state.alive = (Math.random() <= prob);
154 public List<Integer> findCubeNeighbors(Cube cube, Integer index) {
155 List<Integer> neighbors = new LinkedList<Integer>();
158 for (Cube c : model.cubes) {
160 if(abs(c.x - cube.x) < (Cube.EDGE_WIDTH * 2) && abs(c.y - cube.y) < (Cube.EDGE_HEIGHT * 2)) {
161 //print("Cube " + i + " is a neighbor of " + index + "\n");
172 public boolean shouldLightCube(CubeState cube_state) {
173 // Respect rate parameter.
174 if(time_since_last_run < rateParameter.getValuef()) {
175 any_changes_this_run = true;
176 return cube_state.alive;
178 boolean new_life = cycleOfLife(cube_state);
179 new_lives.add(new_life);
184 public void applyNewLives() {
186 for(boolean liveliness: new_lives) {
187 CubeState cube_state = this.cube_states.get(index);
188 cube_state.alive = new_lives.get(index);
193 public boolean cycleOfLife(CubeState cube_state) {
194 Integer index = cube_state.index;
195 Integer alive_neighbor_count = countLiveNeighbors(cube_state);
196 boolean before_alive = cube_state.alive;
197 boolean after_alive = before_alive;
199 if(cube_state.alive) {
200 if(alive_neighbor_count < 2 || alive_neighbor_count > 3) {
207 if(alive_neighbor_count == 2) {
214 if(before_alive != after_alive) {
215 any_changes_this_run = true;
221 public Integer countLiveNeighbors(CubeState cube_state) {
223 CubeState neighbor_cube_state;
225 for(Integer neighbor_index: cube_state.neighbors) {
226 neighbor_cube_state = this.cube_states.get(neighbor_index);
227 if(neighbor_cube_state.alive) {
236 class L8onAutomata extends SCPattern {
237 // Controls if the points should be randomized even if something changes. Set above 0.5 to randomize cube aliveness.
238 private BasicParameter randomParameter = new BasicParameter("RAND", 0.0);
239 // Controls the rate of life algorithm ticks, in milliseconds
240 private BasicParameter rateParameter = new BasicParameter("DELAY", 75.0, 0.0, 1000.0);
242 private final SinLFO zPos = new SinLFO(0, model.zMax, 2500);
244 public final double MIN_ALIVE_PROBABILITY = 0.2;
245 public final double MAX_ALIVE_PROBABILITY = 0.9;
248 // Index of cube in glucose.model.cubes
249 public Integer index;
250 // Boolean which describes if cube is alive.
251 public boolean alive;
253 public PointState(Integer index, boolean alive) {
259 // Contains the state of all cubes by index.
260 private List<PointState> point_states;
261 // Contains the amount of time since the last cycle of life.
262 private int time_since_last_run;
263 // Boolean describing if life changes were made during the current run.
264 private boolean any_changes_this_run;
265 // Hold the new lives
266 private List<Boolean> new_states;
268 public L8onAutomata(GLucose glucose) {
271 //Print debug info about the cubes.
275 randomizePointStates();
276 time_since_last_run = 0;
277 any_changes_this_run = false;
278 new_states = new ArrayList<Boolean>();
280 addParameter(randomParameter);
281 addParameter(rateParameter);
282 addModulator(zPos).trigger();
285 private void initPointStates() {
286 boolean alive = false;
287 PointState point_state;
288 this.point_states = new ArrayList<PointState>();
291 for (LXPoint p : model.points) {
293 point_state = new PointState(i, alive);
294 this.point_states.add(point_state);
299 public void run(double deltaMs) {
301 PointState point_state;
303 any_changes_this_run = false;
305 time_since_last_run += deltaMs;
307 for (LXPoint p : model.points) {
308 point_state = this.point_states.get(i);
310 if(shouldLightPoint(point_state)) {
319 boolean should_randomize_anyway = (randomParameter.getValuef() > 0.5);
320 if(should_randomize_anyway || !any_changes_this_run) {
321 randomizePointStates();
326 if(time_since_last_run >= rateParameter.getValuef()) {
327 time_since_last_run = 0;
331 public void lightLivePoint(LXPoint p) {
332 float hv = max(0, lx.getBaseHuef() - abs(p.z - zPos.getValuef()));
333 colors[p.index] = lx.hsb(
340 public void lightDeadPoint(LXPoint p) {
341 colors[p.index] = lx.hsb(
348 public boolean shouldLightPoint(PointState point_state) {
349 // Respect rate parameter.
350 if(time_since_last_run < rateParameter.getValuef()) {
351 any_changes_this_run = true;
352 return point_state.alive;
354 boolean new_state = cycleOfAutomata(point_state);
355 new_states.add(new_state);
360 public boolean cycleOfAutomata(PointState point_state) {
361 Integer index = point_state.index;
362 Integer alive_neighbor_count = countLiveNeighbors(point_state);
363 boolean before_alive = point_state.alive;
364 boolean after_alive = before_alive;
366 if(point_state.alive) {
367 if(alive_neighbor_count == 1) {
374 if(alive_neighbor_count == 1) {
381 if(before_alive != after_alive) {
382 any_changes_this_run = true;
388 public int countLiveNeighbors(PointState point_state) {
389 Integer index = point_state.index;
390 PointState before_neighbor;
391 PointState after_neighbor;
395 before_neighbor = point_states.get(index - 1);
396 if(before_neighbor.alive) {
401 if (index < (point_states.size() - 1)) {
402 after_neighbor = point_states.get(index + 1);
403 if(after_neighbor.alive) {
411 private void applyNewStates() {
413 for(boolean new_state: new_states) {
414 PointState point_state = this.point_states.get(index);
415 point_state.alive = new_states.get(index);
420 private void randomizePointStates() {
421 double prob_range = (1.0 - MIN_ALIVE_PROBABILITY) - (1.0 - MAX_ALIVE_PROBABILITY);
422 double prob = MIN_ALIVE_PROBABILITY + (prob_range * Math.random());
424 print("Randomizing points! p = " + prob + "\n");
426 for (PointState point_state: this.point_states) {
427 point_state.alive = (Math.random() <= prob);
432 class L8onStrips extends SCPattern {
433 // Controls the rate of life algorithm ticks, in milliseconds
434 private BasicParameter rateParameter = new BasicParameter("DELAY", 112.5, 0.0, 1000.0);
435 // Controls if the cubes should be randomized even if something changes. Set above 0.5 to randomize cube aliveness.
436 private BasicParameter randomParameter = new BasicParameter("RAND", 0.0);
437 // Controls the brightness of dead cubes.
438 private BasicParameter deadParameter = new BasicParameter("DEAD", 25.0, 0.0, 100.0);
439 // Controls the saturation.
440 private BasicParameter saturationParameter = new BasicParameter("SAT", 90.0, 0.0, 100.0);
442 public final double MIN_ALIVE_PROBABILITY = 0.4;
443 public final double MAX_ALIVE_PROBABILITY = 0.9;
445 private final SinLFO xPos = new SinLFO(0, model.xMax, 4500);
446 private final SinLFO zPos = new SinLFO(0, model.zMax, 2500);
449 // Index of strip in glucose.model.strips
450 public Integer index;
451 // Boolean which describes if strip is alive.
452 public boolean alive;
453 // List of this cubes neighbors
454 public List<Integer> neighbors;
456 public StripState(Integer index, boolean alive, List<Integer> neighbors) {
459 this.neighbors = neighbors;
463 // Contains the state of all cubes by index.
464 private List<StripState> strip_states;
465 // Contains the amount of time since the last cycle of life.
466 private int time_since_last_run;
467 // Boolean describing if life changes were made during the current run.
468 private boolean any_changes_this_run;
469 // Hold the new lives
470 private List<Boolean> new_lives;
472 public L8onStrips(GLucose glucose) {
475 //Print debug info about the strips.
479 randomizeStripStates();
480 time_since_last_run = 0;
481 any_changes_this_run = false;
482 new_lives = new ArrayList<Boolean>();
484 addParameter(rateParameter);
485 addParameter(randomParameter);
486 addParameter(deadParameter);
487 addParameter(saturationParameter);
489 addModulator(xPos).trigger();
490 addModulator(zPos).trigger();
493 public void run(double deltaMs) {
495 StripState strip_state;
497 any_changes_this_run = false;
499 time_since_last_run += deltaMs;
501 for (Strip strip : model.strips) {
502 strip_state = this.strip_states.get(i);
504 if(shouldLightStrip(strip_state)) {
505 lightLiveStrip(strip);
507 lightDeadStrip(strip);
513 boolean should_randomize_anyway = (randomParameter.getValuef() > 0.5);
514 if(should_randomize_anyway || !any_changes_this_run) {
515 randomizeStripStates();
520 if(time_since_last_run >= rateParameter.getValuef()) {
521 time_since_last_run = 0;
525 public void lightLiveStrip(Strip strip) {
526 for (LXPoint p : strip.points) {
527 float hv = max(0, lx.getBaseHuef() - abs(p.z - zPos.getValuef()));
528 colors[p.index] = lx.hsb(
530 saturationParameter.getValuef(),
536 public void lightDeadStrip(Strip strip) {
537 for (LXPoint p : strip.points) {
538 float hv = max(0, lx.getBaseHuef() - abs(p.x - xPos.getValuef()));
539 double dead_bright = deadParameter.getValuef() * Math.random();
541 colors[p.index] = lx.hsb(
543 saturationParameter.getValuef(),
549 public void outputStripInfo() {
551 for (Strip strip : model.strips) {
552 print("Strip " + i + ": " + strip.cx + "," + strip.cy + "," + strip.cz + "\n");
557 private void initStripStates() {
558 List<Integer> neighbors;
559 boolean alive = false;
560 StripState strip_state;
561 this.strip_states = new ArrayList<StripState>();
564 int total_neighbors = 0;
566 for (Strip strip : model.strips) {
567 neighbors = findStripNeighbors(strip, i);
569 strip_state = new StripState(i, alive, neighbors);
570 this.strip_states.add(strip_state);
572 total_neighbors += neighbors.size();
576 float average_neighbor_count = (float) total_neighbors / (float) model.strips.size();
577 //print("Average neighbor count: " + average_neighbor_count + "\n");
580 private void randomizeStripStates() {
581 double prob_range = (1.0 - MIN_ALIVE_PROBABILITY) - (1.0 - MAX_ALIVE_PROBABILITY);
582 double prob = MIN_ALIVE_PROBABILITY + (prob_range * Math.random());
584 //print("Randomizing strips! p = " + prob + "\n");
586 for (StripState strip_state : this.strip_states) {
587 strip_state.alive = (Math.random() <= prob);
591 public List<Integer> findStripNeighbors(Strip strip, Integer index) {
592 List<Integer> neighbors = new LinkedList<Integer>();
594 int neighbor_count = 0;
595 double distance = 0.0;
597 for (Strip s : model.strips) {
598 if( (int)index != (int)i ) {
599 distance = Math.sqrt( Math.pow((s.cx - strip.cx), 2) + Math.pow((s.cy - strip.cy), 2) + Math.pow((s.cz - strip.cz), 2) );
601 if(distance < ( (double) Cube.EDGE_WIDTH) ) {
602 //print("Strip " + i + " is a neighbor of " + index + "\n");
612 public boolean shouldLightStrip(StripState strip_state) {
613 // Respect rate parameter.
614 if(time_since_last_run < rateParameter.getValuef()) {
615 any_changes_this_run = true;
616 return strip_state.alive;
618 boolean new_life = cycleOfStripperLife(strip_state);
619 new_lives.add(new_life);
624 public void applyNewLives() {
626 for(boolean liveliness: new_lives) {
627 StripState strip_state = this.strip_states.get(index);
628 strip_state.alive = new_lives.get(index);
633 public boolean cycleOfStripperLife(StripState strip_state) {
634 Integer index = strip_state.index;
635 Integer alive_neighbor_count = countLiveNeighbors(strip_state);
636 boolean before_alive = strip_state.alive;
637 boolean after_alive = before_alive;
639 if(strip_state.alive) {
640 if(alive_neighbor_count < 2 || alive_neighbor_count > 6) {
647 if(alive_neighbor_count == 5) {
654 if(before_alive != after_alive) {
655 any_changes_this_run = true;
661 public Integer countLiveNeighbors(StripState strip_state) {
663 StripState neighbor_strip_state;
665 for(Integer neighbor_index: strip_state.neighbors) {
666 neighbor_strip_state = this.strip_states.get(neighbor_index);
667 if(neighbor_strip_state.alive) {