xxxxxxxxxx
294
// constants of nature
deltaT = 0.01;
m = 2;
G = 200;
strutDist = 40;
k = 0.4;
core = 0*10;
coreSize = 10;
friction = 0;
damping = 0.01;
lastX = 0;
lastY = 0;
breakFactor = 0.8;
// center of masss of the whole thing
comX = 0;
comY = 0;
maxA = 2;
// initial angular velocity
omega = 0.1;
// coords for other objects
var xs = [];
var ys = [];
// velocities for the other objects
var vxs = [];
var vys = [];
// keeps track of whether the links are broken or not
var broken = [];
radObj = 5;
const STATE_INIT = 0;
const STATE_ANG = 1;
const STATE_RUNNING = 2;
running=false;
function setup() {
createCanvas(800, 800);
}
function draw() {
background(255);
// set the zero
translate(width/2,height/2);
fill(0);
// draw the other objects
for (var i = 0; i < xs.length; i++) {
circle(xs[i],ys[i],2*radObj);
if (!broken[i])
line(xs[i],ys[i],xs[next(i)],ys[next(i)]);
}
// print("Angular Momentum "+ computeL());
//noFill()
//circle(0,0,2*soundrad)
if (running) {
// do 10 steps in one drawing
for (var i = 0; i < 20; i++) {
timeEvolve();
}
}
text("Draw a closed loop",-50,height/2-40);
}
function timeEvolve() {
//
// evolve things forward in time
for (var i = 0; i < xs.length; i++) {
xs[i] += vxs[i]*deltaT;
ys[i] += vys[i]*deltaT;
for (var j=0; j < xs.length; j++) {
if (j != i) {
// now let's create the inverse square law attraction
r = distance(xs[i],ys[i],xs[j],ys[j]);
if (r > coreSize) {
deltaX = (xs[i] - xs[j])/r;
deltaY = (ys[i] - ys[j])/r;
// do the inverse square law thingie on the test particles
// need to construct a short distance repulsion but a long distance power law
vxs[i] += (G*deltaX*deltaT)*(-pow(r,-2)+core*pow(r,-4));
vys[i] += (G*deltaY*deltaT)*(-pow(r,-2)+core*pow(r,-4));
}
else {
// if they are inside the core, do a kind of damping motion relative to the
// average velocity of the two bodies
vxs[i] = vxs[i] - (vxs[i] - vxs[j])*damping;
vys[i] = vys[i] - (vys[i] - vys[j])*damping;
}
}
}
// now the force from the struts
indices = [next(i),prev(i)];
if (xs.length > 2) {
// loops over the one before and the one after
for (var k=0; k<2;k++) {
r = distance(xs[i],ys[i],xs[indices[k]],ys[indices[k]]);
if (abs(r-strutDist) > breakFactor*strutDist) {
// break the link
breakLink(indices[k],i);
}
// only apply the force if the strut is not broken
if (!isBroken(indices[k],i)) {
deltaX = (xs[i] - xs[indices[k]])/r;
deltaY = (ys[i] - ys[indices[k]])/r;
forceX = 0*(deltaX*deltaT)*(strutForce(r));
//print("The force is "+forceX+ "and r is "+r);
vxs[i] += (deltaX*deltaT)*(strutForce(r));
//print("Trying ",(deltaX*deltaT)*(strutForce(r)));
vys[i] += (deltaY*deltaT)*(strutForce(r));
}
}
}
// finally, a bit of friction.
vxs[i] -= friction*vxs[i];
vys[i] -= friction*vys[i];
//print(vxs[i]);
}
}
/*function mouseClicked() {
// deal with clicks by making a new object
//print("Here!",mouseX,mouseY);
// remember to offset by the origin
xs.push(mouseX-width/2);
ys.push(mouseY-height/2);
vxs.push(random(200)-100);
vys.push(random(200)-100);
}*/
function mouseReleased() {
/* should be the code to close the loop and start the simulation */
// close the loop by drawing a straight line
currX = xs[xs.length-1];
currY = ys[ys.length-1];
deltaX = (xs[0]-currX)/distance(currX,currY,xs[0],ys[0]);
deltaY = (ys[0]-currY)/distance(currX,currY,xs[0],ys[0]);
while(distance(currX,currY,xs[0],ys[0])>strutDist) {
currX += strutDist*deltaX;
currY += strutDist*deltaY;
addBit(currX,currY);
}
// need to give initial angular velocity.
for (var i = 0; i < xs.length; i++) {
comX += xs[i]/xs.length;
comY += ys[i]/xs.length;
}
// initialize the velocity vectors
for (var i=0; i < xs.length; i++) {
vxs[i] = -omega*(ys[i]-comY);
vys[i] = omega*(xs[i]-comX);
}
// now create the angular velocity about the center of mass of the thing.
running = true;
}
function distance(x1,y1,x2,y2) {
// just returns the distance
return(pow(pow(x1-x2,2)+pow(y1-y2,2),0.5));
}
function mousePressed() {
lastX = mouseX - width/2;
lastY = mouseY - height/2;
}
function mouseClicked() {
print(next(0));
print(prev(0));
}
function mouseDragged() {
currX = mouseX - width/2;
currY = mouseY - height/2;
if (distance(currX,currY,lastX,lastY)>strutDist) {
addBit(currX,currY);
lastX = currX;
lastY = currY;
}
}
function next(curr) {
if ((curr+1)>=xs.length)
return 0;
else
return curr+1;
}
function prev(curr) {
if (curr > 0)
return (curr-1);
else
return (xs.length-1);
}
function strutForce(r) {
// just make it a harmonic restoring force
//print("In the func ",r);
return (-k*(r-strutDist));
}
// add a new sphere.
function addBit(x,y) {
xs.push(x);
ys.push(y);
vxs.push(0);
vys.push(0);
broken.push(false);
}
function computeL() {
L = 0;
for (var i = 0; i < xs.length; i++) {
L += (xs[i]*vys[i] - ys[i]*vxs[i])
}
return(L);
}
// function to handle the links
function isBroken(i,j) {
link = min(i,j);
// possible issue if we are at the zeroth link
if (link == 0 && (i==(xs.length-1) || j==(xs.length-1)))
link = xs.length-1;
return(broken[link]);
}
function breakLink(i,j) {
link = min(i,j);
if (link == 0 && (i==(xs.length-1) || j==(xs.length-1)))
link = xs.length-1;
broken[link] = true;
}