> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://cd3d.sketchpad.cc/sp/pad/view/ro.LF8$CjWJh4K/rev.1
 * 
 * authors: 
 *   Pascal Romon

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



/*
This sketch builds on a prior work, "rotating_polygon", created by Pascal Romon
http://cd3d.sketchpad.cc/sp/pad/view/ro.4lJDWzx$jTVZvDA/rev.20
*/
 
import java.util.List;
import java.util.ArrayList;
 
/*
This simple program evolves a centered regular polygon by the flow of 
the circular field
Pascal Romon 2016-09-30 
*/
 
 
int vertexSize = 10;  // circle size for drawing vertices
Curve C;
int n;
float tau = 0.1;
int pause = 0;  // control the mouse
 
 
boolean make_curve;
List<Curve> curves;
Curve building_curve;
List<Vector> building_vertices;
 
void setup() {
  frameRate(10);
  size(300, 300);
  background(100);
  n = 8;
 
  C = regularPolygon(n, 50, 50, 40);
 
 
  // To create new curves with the mouse.
  curves = new ArrayList<Curve>();
  building_curve = null;
  building_vertices = new ArrayList<Vector>();
  make_curve = false;
}
 
void draw() {
  translate(width/2, height/2);  // sets the origin of the coordinates in the center of the frame
  background(100);
  
  // Display the custom curves.
  if (building_curve != null) {
      building_curve.drawCurve();
  }
  
  for (Curve curve: curves) {
    curve.drawCurve();
  }
}
 
void mouseClicked() {
  if (make_curve) {
    building_vertices.add(new Vector(mouseX - width / 2, mouseY - height / 2));
    building_curve = new Curve();
    building_curve.loop = false;
    building_curve.vertices = building_vertices;
  }
}
 
void keyReleased() {
  if (key == 'c') {
    if (make_curve) {
      if (building_vertices.size() >= 3) {
        Curve builded_curve = new Curve();
        builded_curve.loop = true;
        builded_curve.vertices = new ArrayList<Vector>(building_vertices);
        curves.add(builded_curve);
      }
      
      building_curve = null;
      building_vertices.clear();
    }
    
    make_curve = !make_curve;
  }
}
 
Curve regularPolygon(int n, float xo, float yo, float radius) {
  Curve C = new Curve();
  C.loop = true;  // the curve is closed
  for (int i=0; i < n; i++) {
    Vector v = new Vector(xo + radius*cos(i*TWO_PI/n),yo + radius*sin(i*TWO_PI/n));
    C.vertices.add(v);
  }
  return(C);
}
 
 
class Vector {
  float x = 0.0;
  float y = 0.0;
  
  Vector() {
  }
  
  Vector(float xi,float yi) {
    x = xi;
    y = yi;
  }
 
  void add(Vector v) {
    x += v.x;
    y += v.y;
  }
  void sub(Vector v) {
    x-= v.x;
    y-= v.y;
  }
  
  void mult(float c) {
    x = x*c;
    y = y*c;
  }
 
  float det(Vector v) {
    return (x * v.y - y *v.x);
  }
 
  float scal(Vector v) {
    return (x * v.x + y *v.y);
  }
 
  float norm() {
    return(sqrt((x*x+y*y)));
  }
  float normsq() {
    return((x*x+y*y));
  }
  void normalize() {
    float mag = sqrt ((float)(x*x+y*y));
    x = x/mag;
    y= y/mag;
  }
  void rot() {
    float u, v;
    u=x;
    v=y;
    x= -v;
    y = u;
  }
}
 
class Curve {
  List<Vector> vertices = new ArrayList<Vector>();
  boolean loop;  // "yes" or "no"; if yes, indicate only n vertices
 
  void drawCurve() {
    int n = vertices.size();
    Vector current,next;
    //first: lines
    for(int i=0; i < n-1; i++) {
      current = vertices.get(i);
      next = vertices.get(i+1);
      line((float)current.x,(float)current.y,(float)next.x,(float)next.y);
    }
    current = vertices.get(n-1);  // last point
    if (loop) {
      next = vertices.get(0);
      line((float)current.x,(float)current.y,(float)next.x,(float)next.y);
    }
    // second: vertices
    for(int i=0; i < n-1; i++) {
      current = vertices.get(i);
      next = vertices.get(i+1);
      //println(i,current.x, current.y);
      ellipse((float)current.x,(float)current.y,vertexSize,vertexSize);
    }
    current = vertices.get(n-1);  // last point
    ellipse((float)current.x,(float)current.y,vertexSize,vertexSize);
  }
  
  void shift(ArrayList<Vector> shifts) {
    // one should check that the size of both list is the same ...
    //Vector v,s;
    for (int i = 0; i < vertices.size(); i++) {
      Vector v = vertices.get(i);
      Vector s = shifts.get(i);
      //vertices.get(i).add(s);
      v.x += s.x;
      v.y += s.y;
    }
  }
}