xxxxxxxxxx
147
const drag_force = 0.5;
const maxV = Math.PI/64;
const list = new List(5);
const canvas_size = 800;
var inscreen = false;
var origin;
function setup() {
can = createCanvas(canvas_size, canvas_size);
can.mouseOver( () => inscreen = true );
can.mouseOut( () => inscreen = false );
sl1 = createSlider(canvas_size/32, canvas_size/16, canvas_size/24, 0.25);
sl1.parent('div1')
sl2 = createSlider(4, 16, 8, 1);
sl2.parent('div1')
origin = createVector(canvas_size/2, canvas_size/2);
colorMode(HSB)
noCursor();
}
var frame = 1;
var accumulative = 0;
var radius = 0;
function mousePressed () {
if(!inscreen)
return;
frame = 1;
accumulative = 0;
radius = createVector(mouseX, mouseY).sub(origin).mag();
if(radius < canvas_size*0.05/2 + sl1.value()) radius = 0;
}
function mouseDragged() {
const last_frame = createVector(pmouseX, pmouseY).sub(origin).heading() + TWO_PI;
const current_frame = createVector(mouseX, mouseY).sub(origin).heading() + TWO_PI;
//console.log(accumulative/frame)
frame++;
if( abs(current_frame - last_frame) < TWO_PI-PI/8 )
accumulative += current_frame - last_frame;
}
function mouseReleased() {
ball = {
rad: radius,
angle: createVector(mouseX, mouseY).sub(origin).heading() + TWO_PI,
angleV: constrain(accumulative * drag_force / frame, -maxV, maxV),
size: sl1.value(),
hue: random(-PI,PI),
sat: random(-PI,PI)
}
if(ball.angleV == 0) ball.angleV = random(-maxV, maxV)*0.25;
if(inscreen || radius != 0) list.add(ball);
radius = 0;
}
function draw() {
colorMode(RGB)
background(0, 16);
fill('#007fff');
noStroke();
textSize(16)
textAlign(LEFT, CENTER)
if(frameCount % 30 == 0) list.resize(sl2.value());
text( list.current_size + ' / '+ sl2.value() + ' Orbits', 16, 25);
const pvec = createVector(mouseX, mouseY).sub(origin)
const vec = createVector(mouseX, mouseY).sub(origin);
colorMode(HSB)
fill(map(sin(vec.heading()), -1, 1, 0, 256), 256, 256, 4);
//push();stroke(0);fill(0, 256);circle(pmouseX, pmouseY, sl1.value());pop();
if(!mouseIsPressed)
circle(mouseX, mouseY, sl1.value())
vec.setMag(radius);
translate(origin)
circle(vec.x,vec.y, sl1.value())
circle(0,0,sl1.value())
list.iterate( (data) => {
fill(map(sin(data.angle+data.hue), -1, 1, 0, 256),
map(cos(data.angle+data.sat), -1, 1, 128, 256), 256, 256);
circle(cos(data.angle) * data.rad, sin(data.angle) * data.rad, data.size);
data.angle = (data.angle + data.angleV) % TWO_PI;
collision_detection(data);
});
}
function get_pos (ball) {
return p5.Vector.fromAngle(ball.angle).setMag(ball.rad);
}
function collision_detection (ball) {
const pos = get_pos(ball);
list.iterate( (ball2) => {
if(ball.id != ball2.id && pos.dist(get_pos(ball2)) < ball2.size/2 + ball.size/2)
handle_collision(ball, ball2);
})
}
function handle_collision(ball, ball2, pos, pos2) {
const mass1 = ball.rad*ball.rad*PI;
const mass2 = ball2.rad*ball2.rad*PI;
const impulse1 = mass1 * ball.angleV;
const impulse2 = mass2 * ball2.angleV;
ball.angleV = impulse2 / mass1;
ball2.angleV = impulse1 / mass2;
ball.angleV = constrain(ball.angleV, -maxV, maxV);
ball2.angleV = constrain(ball2.angleV, -maxV, maxV);
ball.hue = random(-PI, PI);
ball2.hue = random(-PI, PI);
ball.sat = random(-PI, PI);
ball2.sat = random(-PI, PI);
while(get_pos(ball).dist(get_pos(ball2)) < ball2.size/2 + ball.size/2) {
ball2.angle = (ball2.angle + ball2.angleV ) % TWO_PI;
ball.angle = (ball.angle + ball.angleV ) % TWO_PI;
}
}