A gravity simulation I made.
function setup() {
createCanvas(800, 800, $("#main"))
setInterval(draw2, 5);
noStroke()
}
let particles = [[0, 0, 0, 0, 50]];
let newParticles = [...particles];
const gravitational_constant = 2;
//Randomly spawns particles on the canvas
function addDust(num) {
for (let i = 0; i < num; i++) {
let x = [Math.random() * 400 - 200, Math.random() * 400 - 200, Math.random() * 2 - 1, Math.random() * 2 - 1, 0.1]
particles.push(x)
newParticles.push(x)
}
}
//Randomly spawns particles in a disk around the star, and gives them a random velocity that should make most of them orbit the same direction
function addAccretionDisk(num) {
for (let i = 0; i < num; i++) {
let a = Math.random() * 2 * Math.PI;
let x = [(Math.random() * 200 + 100) * Math.cos(a), (Math.random() * 200 + 100) * Math.sin(a), (Math.cos(a) - Math.cos(a + 0.1)) * Math.random() * 10, (Math.sin(a) - Math.sin(a + 0.1)) * Math.random() * 10, 0.05]
particles.push(x)
newParticles.push(x)
}
}
addAccretionDisk(600)
function draw2() {
console.log(particles.length);
background(0, 20)
push()
translate(400 - particles[0][0], 400 - particles[0][1])
let count1 = 0
for (p of particles) {
count1++;
if (p[4] > 30) {
//draw stars
colorMode(HSB, 100, 100, 100, 100)
fill(p[4] - 30, 100, 100)
ellipse(p[0], p[1], Math.sqrt(p[4] / Math.PI) * 10)
fill(p[4] - 30, 100, 100, 5)
ellipse(p[0], p[1], Math.sqrt(p[4] / Math.PI) * 11)
fill(p[4] - 30, 100, 100, 5)
ellipse(p[0], p[1], Math.sqrt(p[4] / Math.PI) * 12)
fill(p[4] - 30, 100, 100, 5)
ellipse(p[0], p[1], Math.sqrt(p[4] / Math.PI) * 13)
fill(p[4] - 30, 100, 100, 5)
ellipse(p[0], p[1], Math.sqrt(p[4] / Math.PI) * 14)
fill(p[4] - 30, 100, 100, 5)
ellipse(p[0], p[1], Math.sqrt(p[4] / Math.PI) * 15)
fill(p[4] - 30, 100, 100, 5)
ellipse(p[0], p[1], Math.sqrt(p[4] / Math.PI) * 16)
fill(p[4] - 30, 100, 100, 5)
ellipse(p[0], p[1], Math.sqrt(p[4] / Math.PI) * 17)
colorMode(RGB)
} else {
//draw planets
fill(255)
ellipse(p[0], p[1], Math.sqrt(p[4] / Math.PI) * 10)
}
let count2 = 0;
for (p2 of newParticles) {
count2++
if (count1 != count2) {
let dist2 = Math.pow(p[0] - p2[0], 2) + Math.pow(p[1] - p2[1], 2)
//gravity
let xgravity = p2[4] * gravitational_constant / dist2
if (p2[0] > p[0]) {
p[2] += xgravity
} else if (p2[0] < p[0]) {
p[2] -= xgravity
}
let ygravity = p2[4] * gravitational_constant / dist2
if (p2[1] > p[1]) {
p[3] += ygravity
} else if (p2[1] < p[1]) {
p[3] -= ygravity
}
//collsions
if (Math.sqrt(dist2) < Math.sqrt(p[4] / Math.PI) * 5.5) {
let x = particles.indexOf(p2)
p[2] = (p2[2] * p2[4] / (p[4] + p2[4])) + (p[2] * p[4] / (p[4] + p2[4]))
p[3] = (p2[3] * p2[4] / (p[4] + p2[4])) + (p[2] * p[4] / (p[4] + p2[4]))
p[4] += p2[4]
particles.splice(x, 1)
newParticles.splice(x, 1)
}
}
}
}
particles = [...newParticles]
for (p of particles) {
//update position based on velocity
p[0] += p[2]
p[1] += p[3]
//Removes particles if they get too far
if (dist(p[0], p[1], particles[0][0], particles[0][1]) > 100000) {
let x = particles.indexOf(p)
particles.splice(x, 1)
newParticles.splice(x, 1)
console.log(particles.length)
}
}
pop()
}
Collisions are kind of fixed, though some are still broken. I also have separate roche limit code, but that doesn't work well at all
I use p5.js for drawing stuff and jQuery to get the canvas on line 2
@SpiritOfWrath @Usseewa