I'm getting strange results when calculating the physics between two objects.
My goal is to build a galaxy simulator that can simulate how galaxies consisting of 100s of stars might look when interacting. It's a fun little side project and I'm not even sure how it'll turn out (which is part of the fun). I have a really limited background in math and physics so this is a pretty big challenge for me atm. I'm starting with one star and a static object to attract it to nail down the basic physics.
The problem I'm facing is that, as star one approaches the static object it's is accelerating as expected and when it passes the object I expect the velocity to slowly bleed to zero and the star to fall back in. However, after passing the static object the star is behaving oddly. Depending on my delta time variable It position sometimes shoots off crazy fast in one direction or another. I'm too new to all of this and there are too many variables for me to follow where exactly the issue lies.
As an FYI this is a little web app written in javascript and not an actual video game. However, the concepts are similar to calculating video game physics and most web developer forums aren't helpful. Here is a link to the code in codepen. NOTE: If the “try me” button doesn't appear try shrinking your browser down in size or scrolling down to find the button.
Finally, the rendering engine (canvas) doesn't appear to be the problem as I can see the issue in the console as being related to the calculations and not he rendering.
let frameCount = 0;
let stars;
let dt;
let gravConst = 6.674 * Math.pow(10, -11);
// let solarMass = Math.pow(10, 30);
// let lightYear = 9.5 * Math.pow(10, 15);
let solarMass = 1;
let lightYear = 1;
let yearCounter;
stars = [
{ x: 250, y: 75, m: 1, v: 0 },
{ x: 275, y: 75, m: 1, v: 0 }
];
dt = 50000;
yearCounter = 0;
const render = () => {
let canvas = document.getElementById("canvasRef");
const context = canvas.getContext("2d");
let animationFrameId;
frameCount++;
animationFrameId = window.requestAnimationFrame(render);
draw(context, frameCount);
};
const draw = (ctx, frameCount) => {
// console.log(frameCount)
ctx.clearRect(0, 0, ctx.canvas.width, ctx.canvas.height);
ctx.fillStyle = "#ffffff";
calculateGravAccel(stars[0], stars);
drawStar(stars, ctx);
};
let calculateGravAccel = (star, stars) => {
// Force on current star by all other star sources (newtons)
let m1 = stars[0].m * solarMass;
let m2 = stars[1].m * solarMass;
let distance = (stars[0].x - stars[1].x) * lightYear;
let xDistance = stars[0].x - stars[1].x;
let f = gravConst * (m1 * m2) / Math.pow(distance, 2);
console.log(f);
// Convert velocity to account for the fact that the force is now coming from behind
// New velocity of current star
star.v = distance < 0 ? star.v + (f / m1) * dt : star.v - (f / m1) * dt;
// Position
star.x = star.x + star.v * dt;
// Ellapsed Time
yearCounter += dt;
};
const drawStar = (stars, ctx) => {
console.log(`x:${stars[0].x} y: ${stars[0].y} v: ${stars[0].v}`);
ctx.beginPath();
ctx.arc(stars[0].x, stars[0].y, 5, 0, 2 * Math.PI);
ctx.arc(stars[1].x, stars[1].y, 5, 0, 2 * Math.PI);
ctx.fill();
};