/* 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;
}
}
}