String
in
Share your Work
•
11 months ago
Simple string physics, click to grab/un-grab or leave it to move around.
final int NUMPOINTS=50; // number of points
final int SEGLENGTH=2; // distance between points
final int BORDER=10; // 'rebound' when this close to the edge
float fTargX, fTargY, fDeltaX, fDeltaY;
Boolean mouseControl;
class SPoint {
float fX, fY;
SPoint(float fTX, float fTY) {
fX=fTX;
fY=fTY;
}
}
SPoint[] points=new SPoint[NUMPOINTS];
SPoint[] buffer=new SPoint[NUMPOINTS];
void setup() {
size(800, 600);
//init points
for (int i=0;i<NUMPOINTS; i++) {
points[i]= new SPoint(width/2, 10 + SEGLENGTH*i);
buffer[i]= new SPoint(0, 0);
}
//set target & speed
fTargX=width/2;
fTargY=height/2;
fDeltaX=random(-1, 1);
fDeltaY=random(-1, 1);
fill(0);
stroke(0);
strokeWeight(4);
frameRate(40);
//under it's own control to begin with
mouseControl=false;
}
void draw() {
background(200);
showPoints();
updatePoints();
if (mouseControl) {
points[NUMPOINTS-1].fX=mouseX;
points[NUMPOINTS-1].fY=mouseY;
}
else {
//put target a 'head' end of string
points[NUMPOINTS-1].fX=fTargX;
points[NUMPOINTS-1].fY=fTargY;
//move head, body will follow :)
fTargX+=fDeltaX;
fTargY+=fDeltaY;
//rebound if necessary
if ((fTargX<BORDER) || (fTargX>width-BORDER)) {
fDeltaX=-fDeltaX;
fTargX+= 2*fDeltaX;
}
if ((fTargY<BORDER) || (fTargY>height-BORDER)) {
fDeltaY=-fDeltaY;
fTargY+= 2*fDeltaY;
}
//change direction occasionally
if (random(1)>0.98) {
fDeltaX=random(-1, 1);
fDeltaY=random(-1, 1);
}
}
}
void mousePressed(){
mouseControl=!mouseControl;
if(mouseControl) noCursor();
else{
fTargX=mouseX;
fTargY=mouseY;
cursor();
}
}
void showPoints() {
//connect points
for (int i=0;i<NUMPOINTS-1; i++)
line(points[i].fX, points[i].fY, points[i+1].fX, points[i+1].fY);
}
void updatePoints() {
PVector v1, v2;
float mag1, mag2;
float extension1, extension2;
float fX1, fY1, fX2, fY2, finalX, finalY;
for (int i=1; i<NUMPOINTS-1; i++) {
//preceeding node
fX1=points[i-1].fX - points[i].fX;
fY1=points[i-1].fY - points[i].fY;
v1=new PVector(fX1, fY1);
mag1=v1.mag();
extension1 = mag1 - SEGLENGTH;
//next node
fX2=points[i+1].fX - points[i].fX;
fY2=points[i+1].fY - points[i].fY;
v2=new PVector(fX2, fY2);
mag2=v2.mag();
extension2= mag2 - SEGLENGTH;
finalX=(fX1 / mag1 * extension1) + (fX2 / mag2 * extension2);
finalY=(fY1 / mag1 * extension1) + (fY2 / mag2 * extension2);
//apply 'damping'
buffer[i].fX = points[i].fX + (finalX * 0.99);
buffer[i].fY = points[i].fY + (finalY * 0.99);
}
//end node
fX2=points[1].fX - points[0].fX;
fY2=points[1].fY - points[0].fY;
v2=new PVector(fX2, fY2);
mag2=v2.mag();
extension2= mag2 - SEGLENGTH;
finalX=(fX2 / mag2 * extension2);
finalY=(fY2 / mag2 * extension2);
buffer[0].fX = points[0].fX + (finalX * 0.8);
buffer[0].fY = points[0].fY + (finalY * 0.8);
//copy buffer over
for (int i=0; i<NUMPOINTS-1; i++)
points[i]=buffer[i];
}