/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://cd3d.sketchpad.cc/sp/pad/view/ro.YYq22Ud-aH-/rev.23
*
* authors:
* Pascal Romon
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
/*
This simple program draws a curve by the flow of
the circular field
Pascal Romon 2016-09-30
with contribution of Celine Noel for building the curve with the mouse
*/
/*
Start drawing a curve by pressing 'c';
if a curve already eists, it is erased and a new one is created
Finish by 'c' for a closing the curve
Flow by 'f' (only if the curve exists)
*/
int vertexSize = 10; // circle size for drawing vertices
Curve C;
int n;
float tau = 0.1;
boolean pause = false; // control the mouse during the flow
boolean make_curve = false; // set to true to create the curve
boolean startFlow = false; // set to true to start the flow
void setup() {
frameRate(10);
size(300, 300);
background(100);
C = new Curve();
}
void draw() {
translate(width/2, height/2); // sets the origin of the coordinates in the center of the frame
if (C.vertices.size() > 0) {
C.drawCurve();
}
if (startFlow && !pause) {
background(100);
C.drawCurve();
ArrayList<Vector> flow = new ArrayList<Vector>();
flow = badRotationFlow(C);
C.shift(flow);
}
}
ArrayList<Vector> badRotationFlow(Curve Ctemp) {
ArrayList<Vector> ts = new ArrayList<Vector>();
for (int i = 0; i < Ctemp.vertices.size(); i++) {
Vector v = new Vector();
v.x = Ctemp.vertices.get(i).x;
v.y = Ctemp.vertices.get(i).y;
v.rot();
v.mult(tau);
ts.add(v);
}
for (int j = 0; j < ts.size(); j++) {
Vector v = ts.get(j);
}
return(ts);
}
void mouseClicked() {
if (make_curve) {
C.addVertex(mouseX - width / 2, mouseY - height / 2);
}
if (startFlow) {
pause = !pause; // during the flow, clicking pause and restarts the process
}
}
void keyReleased() {
if (key == 'c') {
startFlow = false; //interrupts flow
if (make_curve && C.vertices.size() >= 3) { // we close the loop
C.loop = true;
} else { // we start a new loop
background(100);
C.vertices.clear();
C.loop = false;
}
make_curve = !make_curve;
}
if (key == 'f' && make_curve == false) {
startFlow = true;
}
}
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 {
ArrayList<Vector> vertices = new ArrayList<Vector>();
boolean loop; // if true, 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 addVertex(float xnew, float ynew) { // adds a vertex
Vector v = new Vector(xnew,ynew);
vertices.add(v);
}
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;
}
}
}