> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.3HAFqkWqzWo/rev.15
 * 
 * authors: 
 *   GoToLoop

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



/**
 * Necklace (v2.05)
 * by  scott_me (2014/Aug)
 * mod GoToLoop
 *
 * forum.processing.org/two/discussion/7294/
 * why-doesn039t-my-sketch-run-in-javascript-mode
 *
 * studio.processingtogether.com/sp/pad/export/ro.9NwgKBhS$Gxju/latest
 */

static final int NUM=120, HUES=120, DIAM=10, RAD=DIAM>>1;
static final float STEP=.01, LIMIT=20.0;

final PVector places[]=new PVector[NUM], vel=new PVector();

static final float[] lookup=new float[NUM];
static final color[] hues=new color[NUM];

void setup() {
  size(1000, 1000, JAVA2D);
  frameRate(60);
  smooth(4);
  noStroke();

  ellipseMode(CENTER);
  colorMode(HSB, HUES);

  for (int i=0; i!=NUM;) {
    places[i]=new PVector(random(width), random(height));
    lookup[i]=sin(TWO_PI/NUM * i)/10.0;
    hues[i]=color((float) HUES/NUM * i++, HUES, HUES);
  }
}

void draw() {
  background(0);
  PVector pos=places[0];

  for (int i=0; i!=NUM;) {
    display(hues[i], pos);
    move(lookup[i], pos, pos=places[++i%NUM], vel);
  }
}

void keyTyped() {
  for (PVector p: places)
    p.set(random(width), random(height), 0);
}

void mousePressed() {
  if (mouseButton != LEFT)  keyTyped();
}

void display(color wheel, PVector place) {
  fill(wheel);
  ellipse(place.x, place.y, DIAM, DIAM);
}

void move(float t, PVector p, PVector n, PVector v) {
  v.set(n);
  v.sub(p);

  float len=v.mag(), adjust=(len-LIMIT)/len;
  v.mult(adjust*STEP);
  p.add(v);

  v.normalize();
  p.add(v.y*t, -v.x*t, 0);

  p.x=constrain(p.x, RAD, width  - RAD-1);
  p.y=constrain(p.y, RAD, height - RAD-1);
}