xxxxxxxxxx
319
// this is going to be the art project.
let osc;
// constants of nature
deltaT = 0.1;
m_BH = 20000;
G = 100;
m_item = 200*0;
radforce = 5000000;
soundamp = 20000000;
soundfreq = 200000;
origParticles = 10;
hawkingVelocity = 40;
// black hole coords
x = 0;
y = 0;
vx = 0;
vy = 0;
rad = 25;
soundrad = 100;
deltarad = 1;
deltaM = 10;
defaultOmega = 50;
// coords for other objects
var xs = [100, 100];
var ys = [100, 200];
// velocities for the other objects
var vxs = [0,0];
var vys = [100,-100];
// the relative angle for each object
var thetas = [0,0];
var omegas = [defaultOmega,defaultOmega];
var objColors = [[0,0,0],[1,1,1]];
// the sound for each object
var oscs = [];
num_stars = 1000;
// the stuff for the stars
var starsX = [];
var starsY = [];
var starSize = [];
starMaxSize = 10;
// the colors
var star_color;
var bg_color;
var bh_color;
var thing_color;
var thing_colors = [];
var eaten_colors = [];
var eaten_number = origParticles;
// the numbers setting the size of the thing
radObj = 5;
strutObj = 5;
PHASE_CREATION = 0;
// in this phase you can make things.
PHASE_COLLAPSE = 1;
// in this phase I will artificially collapse everything into the BH;
PHASE_HAWKING = 2;
// in this phase the Hawking radiation comes out.
// time in the creation phase
creation_time = 2000;
hawking_time = 500;
var curr_time = 0;
var delta_hawking_quanta = 0;
// try at first without the collapse phase, see how it goes.
var curr_phase = PHASE_CREATION;
function setup() {
createCanvas(800, 800);
// initialize each oscillator
for (var i = 0; i < xs.length; i++) {
oscs.push(new p5.Oscillator('sine'));
oscs[i].start();
oscs[i].amp(0);
}
for (var i =0; i<num_stars; i++) {
starsX.push(random(-width,width));
starsY.push(random(-width, width));
starSize.push((random(0.5,1)*starMaxSize));
}
// set all the colors
bg_color = color(0,20,60);
bh_color = color(0,0,0);
thing_color = color(181,195,203);
thing_colors = [color(180,0,0), color(0,180,0), color(0,0,180)];
star_color = color(40,40,80);
// populate the eaten colors with a few random ones
for (var i = 0; i < origParticles; i++) {
for (var j = 0; j < 3; j++) {
eaten_colors.push(floor(random(3)));
}
}
}
function draw() {
//print(curr_time);
background(bg_color);
// set the zero
translate(width/2,height/2);
// draw the stars
for (var i =0; i< num_stars; i++) {
fill(star_color);
noStroke();
circle(starsX[i], starsY[i], starSize[i]);
}
// draw the bh
fill(bh_color);
circle(x,y,2*rad);
// draw the other objects
for (var i = 0; i < xs.length; i++) {
// note that now I draw three things!
//circle(xs[i],ys[i],2*radObj);
for (var j = 0; j < 3; j++) {
fill(thing_colors[objColors[i][j]])
circle(xs[i]+strutObj*cos(thetas[i]+j*2*PI/3),ys[i]+strutObj*sin(thetas[i]+j*2*PI/3),2*radObj);
}
}
//noFill()
//circle(0,0,2*soundrad)
timeEvolve();
if (curr_time >= creation_time && curr_phase == PHASE_CREATION) {
curr_phase = PHASE_HAWKING
// okay, we are switching phases now
// calculate how long between particle emission in the Hawking phase
delta_hawking_quanta = floor(hawking_time/eaten_number);
print("The Hawking quanta delta is ", delta_hawking_quanta);
// cheat: set the newton's constant to zero;
G = 0;
}
if (curr_phase == PHASE_CREATION) {
text("Click to drop a particle",-50,height/2-40);
// draw the progress bar
fill(thing_color);
progress_width = (width/4)*((creation_time-curr_time)/creation_time)
rect(-progress_width/2,height/2-40,progress_width,20);
}
}
function timeEvolve() {
curr_time++;
// evolve things forward in time
for (var i = 0; i < xs.length; i++) {
xs[i] += vxs[i]*deltaT;
ys[i] += vys[i]*deltaT;
thetas[i]+=omegas[i]*deltaT;
x += vx*deltaT;
y += vy*deltaT;
// now let's create the inverse square law attraction
deltaX = xs[i] - x;
deltaY = ys[i] - y;
r = sqrt(pow(deltaX,2) + pow(deltaY,2));
//print(r);
// do the inverse square law thingie on the test particles
vxs[i] -= (m_BH*G*deltaX*deltaT)/pow(r,3);
vys[i] -= (m_BH*G*deltaY*deltaT)/pow(r,3);
// now, the radiation reaction! this is complicated. first make a unit vector in the phi direction
nphiX = -deltaY/r;
nphiY = deltaX/r;
// next, figure out the sign from the for product of this with the actual velocity
prod = nphiX*vxs[i] + nphiY*vys[i];
sign = abs(prod)/prod;
//print((nphiX/pow(r,4))*radforce);
// now, do the radiation reaction thing (the power of r entering here was
// worked out by me before)
vxs[i] += (nphiX/pow(r,4))*radforce;
vys[i] += (nphiY/pow(r,4))*radforce;
freq = prod/r;
// now, do the *same* inverse square law on the BH itself
vx += (m_item*G*deltaX*deltaT)/pow(r,3);
vy += (m_item*G*deltaY*deltaT)/pow(r,3);
// adjust the amplitude (the real power here is 5, not 3)
oscs[i].amp(soundamp/pow(r,3),0.1);
//print(i, "Curr amplitude ", soundamp/pow(r,2));
oscs[i].freq(soundfreq/pow(r,1.5),0.2);
// now, delete the item if it gets eaten by the BH
if (r < rad) {
// store the color charges
for (var j = 0; j < 3; j++) {
eaten_colors.push(objColors[i][j]);
}
xs.splice(i,1);
ys.splice(i,1);
vxs.splice(i,1);
vys.splice(i,1);
thetas.splice(i,1);
omegas.splice(i,1);
objColors.splice(i,1);
// should work on this stuff
oscs[i].amp(0,0.3);
oscs.splice(i,1);
print("Ate one");
print(eaten_colors);
// increase the radius
rad += deltarad;
// increase the mass
m_BH += deltaM;
eaten_number += 1;
}
// now, to determine the orbital frequency; I compute the phi component of the velocity and divide by the radius.
// reflect if off the edge
/*if (abs(xs[i]) > width/2)
vxs[i] = -vxs[i];
if (abs(ys[i]) > height/2)
vys[i] = -vys[i];*/
// now, all of that is fine; we do it for all of them
// however, if we are doing the hawking radiation, we should now emit a hawking particle
}
if (curr_phase == PHASE_HAWKING) {
// throw out some particles with random frequency
// okay; now we need to figure out how many particles to spit out, and how long we want to take for it.
if ((curr_time % delta_hawking_quanta) == 0 && eaten_number >= 0) {
print("Hawking!", eaten_number, curr_time);
eaten_number--;
// create a particle
// choose an angle at random
angle = random(1)*2*PI;
xs.push((rad+10)*cos(angle));
ys.push((rad+10)*sin(angle));
vxs.push(hawkingVelocity*cos(angle));
vys.push(hawkingVelocity*sin(angle));
thetas.push(0);
omegas.push(defaultOmega);
objColors.push([floor(random(3)),floor(random(3)),floor(random(3))]);
oscs.push(new p5.Oscillator('sine'));
oscs[oscs.length-1].start()
rad -= deltarad;
m_BH -= deltaM;
//eaten_number--;
}
}
}
function mouseClicked() {
// deal with clicks by making a new object
//print("Here!",mouseX,mouseY);
if (curr_phase == PHASE_CREATION) {
// 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);
thetas.push(0);
omegas.push(defaultOmega);
newColor = floor(random(3));
print(newColor);
objColors.push([newColor,newColor,newColor]);
//objColors.push()
oscs.push(new p5.Oscillator('sine'));
oscs[oscs.length-1].start()
}
}