/* built with Studio Sketchpad:
* https://sketchpad.cc
*
* observe the evolution of this sketch:
* https://p5js.sketchpad.cc/sp/pad/view/ro.SP7RhUmtC$$/rev.1096
*
* authors:
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* Kris Frajer
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
*
* f
*
* license (unless otherwise specified):
* creative commons attribution-share alike 3.0 license.
* https://creativecommons.org/licenses/by-sa/3.0/
*/
'use strict';
var astr;
// this is run once.
function setup() {
createCanvas(400, 600);
stroke(5);
astr = new VibrantString(20, width/3.0, 25.0);
astr.setOffset(0, -height/4);
astr.setAngle(90);
}
// this is run repeatedly.
function draw() {
translate(width/2.0, height/2.0);
astr.setOffset(0, mouseY-height/2);
noStroke();
fill('#00ffff');
rect(-width/2.0,-height/2.0,width/2.0,height);
fill('#F09494');
rect(0,-height/2.0,width/2.0,height);
//astr.drawPoints();
astr.drawVerteces();
astr.updatePoints();
}
function mouseReleased() {
astr.plokString();
}
function VibrantString(_n, _len, _amp) {
this.harmonic = 1;
this.n = _n; //Number of points
this.pts = [];
this.amp = _amp;
this.len = _len;
this.f = 0.5;
this.time = millis();
this.k=0;
this.deltak=0.04; //Damping constant
this.r=3; //Radius of points
this.theta=0;
this.xOffset=0;
this.yOffset=0;
this.c1=color('#00ffff');
this.c2=color('#F09494');
this.cc=this.c1;
for (let i=0; i<this.n; i++) {
this.pts[i]=createVector(0, 0);
}
this.setOffset = function(xoff, yoff) {
this.xOffset=xoff;
this.yOffset=yoff;
}
this.drawPoints=function() {
for (let i=0; i<this.n; i++) {
var v=this.pts[i];
ellipse(v.x, v.y, this.r, this.r);
}
}
this.setAngle = function(a) {
this.theta=a; //Value in degrees, positive clockwise
};
this.drawPoints = function() {
for (let i=0; i<this.n; i++) {
var v=this.pts[i];
ellipse(v.x, v.y, this.r, this.r);
}
};
this.drawVerteces=function() {
fill(this.cc);
beginShape();
for (let i=0; i<this.n; i++) {
var v=this.pts[i];
vertex(v.x, v.y);
}
var v=this.pts[0];
vertex(v.x, v.y); //Back to first point
endShape(CLOSE);
};
//Points are assumed to be draw from 0 to length in steps dictated by len/n
//Amplitude is measured wrt a zero baseline.
this.updatePoints = function() {
var px = -this.len/2.0;
var stepx=this.len/((this.n-1)*1.0);
this.time=millis();
for (let i=0; i<this.n; i++) {
var tx;
var ty;
tx=px;
//y(x,t)=Amp * sin(n*PI/L*x)cos(2*PI*freq*time)
var equationBody=this.amp*sin(this.harmonic*PI/this.len*(px+this.len/2.0))*cos(2*PI*this.f*this.time/1000.0);
ty=equationBody; //UPDATES position
if(equationBody>0)
this.cc=this.c2;
else
this.cc=this.c1;
ty-=this.k*equationBody; //DAMPING factor
//Rotation matrix about center follow by translation
var a=radians(this.theta);
this.pts[i].x= (tx*cos(a) - ty*sin(a) ) + this.xOffset;
this.pts[i].y= (ty*cos(a) + tx*sin(a) ) + this.yOffset;
px+=stepx;
}
if (this.k<1)
this.k+=this.deltak; //Damping factor rate
else
this.k=1.0;
};
this.plokString = function() {
this.f=random(0.5, 3);
this.k=0;
this.time=millis();
};
}