DNF — infrastructure: 9/10 rounds ended in provider errors; its only completed round, R28, scored 8.5
Overview › Physics Lab › R29
Physics Lab
R29 · Orbital mechanics
Archive round — this round predates the blind-first layout, so answers appear with model names attached. Newer rounds keep the models anonymous until you reveal them.
Show task
Create ONE self-contained HTML file (STRICT LIMIT: max 120 lines total) that shows orbital mechanics on a <canvas>: a sun fixed in the center, exactly 3 planets on stable near-circular orbits of different radii, and 1 comet on a strongly elliptical orbit that swings close past the sun. All motion must come from a Newtonian gravity simulation (acceleration = G*M/r^2 toward the sun, velocity integration), NOT from parametric circle formulas. Each body leaves a fading trail showing its orbit shape. Smooth requestAnimationFrame animation. No external libraries, no comments needed. Output ONLY the HTML file content, nothing else.
Answers
Local (Brain cluster)
Show code
```html
<!DOCTYPE html>
<html><body><canvas id="c"></canvas><script>const c=document.getElementById('c');c.width=800;c.height=600;const ctx=c.getContext('2d');let bodies=[{id:0,px:{x:-1,y,-1},py:{x:-1,y,-1},vx:{x:0,y:0},vy:{x:0,y:0},mass:597200,radius:8,color='#ffcc00',trail:{}},{id:1,px:{x:150,y:0},py:{x:150,y:0},vx:{x:-0.5,y:0.6},vy:{x:0,y:-0.04},mass:3.1e-3,radius:10,color='#00bfff',trail:{}},{id:2,px:{x:{}-250,y:0},py:{x:-250,y:0},vx:{x:0.8,y:0},vy:{x:0.04,y:0.2},mass:1e-3,radius:7,color='#ff69b4',trail:{}},{id:3,px:{x:-5,y:0},py:{x:-5,y:0},vx:{x:0,y:0},vy:{x:0,y:0},mass:1e-5,radius:2,color='#99ccff',trail:{}}];const G=1;const dt=0.1;function update(bodies) {let accs=[{x:0,y:0},{x:0,y:0},{x:0,y:0},{x:0,y:0}];for(let i=1;i<bodies.length;i++)({const p_i=bodies[i].px;const m_i=bodies[i].mass;accs[i]={x:0,y:0};}for(let i=1;i<bodies.length;i++){let totalAx={x:0,y:0};for(let j=0;j<bodies.length;j++){if(i===j)continue;const dx=bodies[j].px.x-bodies[i].px.x;const dy=bodies[j].px.y-bodies[i].px.y;const r=Math.sqrt(dx*dx+dy*dy);const f=G*(bodies[j].mass*m_i)/(r*r+(2*dt));totalAx.x+=f*dx/r;totalAx.y+=f*dy/r;}bodies[i].vx.x+=totalAx.x*dt;bodies[i].vy.y+=totalAx.y*dt;p=bodies[i];const newX=p.px.x+p.vx.x*dt;const newY=p.px.y+p.vy.y*dt;if(newX<0){p.px.x=newX}else if(newX>800){p.px.x=800}else{p.px.x=newX;}if(newY<0){p.px.y=newY}else if(newY>600){p.px.y=600}else{p.px.y=newY;}bodies[i].trail.push({...p.px});if(bodies[i].trail.length>50)bodies[i].trail.shift();}function draw() {ctx.fillStyle='rgba(0,0,0,0.1)';ctx.fillRect(0,0,800,600);for(let i=0;i<bodies.length;i++){const b=bodies[i];if(b.trail.length>1)ctx.beginPath();let x=b.trail[0].x,y=b.trail[0].y;ctx.moveTo(x,y);for(let j=1;j<b.trail.length;j++){ctx.lineTo(b.trail[j].x,b.trail[j].y);}ctx.strokeStyle=b.color+'30';ctx.stroke();const r_draw=Math.pow(bodies[i].mass/597200+0.1,0.8)*Math.random()*0.6+4;ctx.beginPath();ctx.arc(b.px.x,b.px.y,r_draw,(Date.now()/500)%Math.PI*2,0);ctx.fillStyle=b.color;ctx.fill();}}function animate() {update(bodies);draw();}requestAnimationFrame(animate);</script></body></html>
```Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Newtonian Orbits</title>
<style>body { margin: 0; background: #111; }</style>
</head>
<body><canvas id="c"></canvas><script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
const SCALE = 50; // Pixels per AU (visualization scale)
function setup() {
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const G_PHYS = 1 * 10; // Gravitational constant for simulation units
const SUN_MASS = 10000;
let bodies = [
// Planet 1 (Inner, stable) - Near circular orbit approximation
{ pos: { x: 25 * SCALE, y: 0 }, vel: { x: 0, y: 3.85 * Math.sqrt(G_PHYS * SUN_MASS / 25) }, mass: 1, radius: 6, trail: [] },
// Planet 2 (Medium, stable)
{ pos: { x: -70 * SCALE, y: 0 }, vel: { x: 0, y: 1.4 * Math.sqrt(G_PHYS * SUN_MASS / 70) }, mass: 1, radius: 8, trail: [] },
// Planet 3 (Outer, stable)
{ pos: { x: 0, y: 120 * SCALE }, vel: { x: -1.1 * Math.sqrt(G_PHYS * SUN_MASS / 120), y: 0 }, mass: 1, radius: 5, trail: [] },
// Comet (Highly elliptical path) - Initial state set for perihelion passage near t=0
{ pos: { x: 180 * SCALE, y: -40 * SCALE }, vel: { x: -3.5 * Math.sqrt(G_PHYS * SUN_MASS / 200), y: 6 }, mass: 0.01, radius: 3, trail: [], isComet: true }
];
let dt = 0.01; // Time step
lastTime = performance.now();
function update_gravity(body) {
const dx = body.pos.x - bodies[0].pos.x;
const dy = body.pos.y - bodies[0].pos.y;
const r2 = dx * dx + dy * dy;
const r = Math.sqrt(r2);
let ax = G_PHYS * SUN_MASS / (r * r2);
let ay = 0; // Sun is fixed at origin in simulation coordinates, but visually centered.
// Calculate acceleration towards the sun (origin) using relative positions
body.ax = -dx / r + ax * dx / Math.pow(r, 3);
body.ay = -dy / r + ay * dy / Math.pow(r, 3);
}
function update_pos(body) {
const px = body.pos.x;
const py = body.pos.y;
const vx = body.vel.x;
const vy = body.vel.y;
// Euler integration step
body.vel.x += body.ax * dt;
body.vel.y += body.ay * dt;
body.pos.x += body.vel.x * dt;
body.pos.y += body.vel.y * dt;
return { x: px, y: py };
}
function update_simulation() {
// Reset accelerations for all bodies (only planets/comet need them)
bodies.forEach(b => { b.ax = 0; b.ay = 0; });
// Calculate forces *for* the sun's fixed position (local origin in physics units)
bodies[1].ax = -bodies[1].pos.x / Math.max(0.1, Math.hypot(bodies[1].pos.x, bodies[1].pos.y))**3;
bodies[1].ay = -bodies[1].pos.y / Math.max(0.1, Math.hypot(bodies[1].pos.x, bodies[1].pos.y))**3;
// Simulate the main mechanics (using local origin for force calculation simplicity)
for (let i = 0; i < bodies.length; i++) {
const body = bodies[i];
if (body !== bodies[0]) { // Skip sun update logic
const dx = -body.pos.x; // Vector from body to origin (Sun)
const dy = -body.pos.y;
const r2 = dx * dx + dy * dy;
const r = Math.sqrt(r2);
if (i > 0 && i < bodies.length) {
// Acceleration calculation towards the origin (Sun at 0,0)
body.ax = G_PHYS * SUN_MASS / Math.pow(r, 3) * dx;
body.ay = G_PHYS * SUN_MASS / Math.pow(r, 3) * dy;
}
}
// Update position and trail
const newPos = update_pos(body);
body.trail.push({ x: newPos.x, y: newPos.y });
if (body.trail.length > 500) body.trail.shift(); // Keep trail length manageable
}
}
function draw() {
ctx.fillStyle = 'rgba(17, 17, 17, 0.2)';
ctx.fillRect(0, 0, canvas.width, canvas.height);
ctx.globalAlpha = 0.8;
bodies.forEach((b, i) => {
const drawBody = (x, y, r, color);
ctx.beginPath();
ctx.arc(x, y, r, 0, Math.PI * 2);
ctx.fillStyle = color;
ctx.fill();
// Draw Trail
ctx.strokeStyle = b.isComet ? 'rgba(255, 255, 100, 0.6)' : 'rgba(150, 150, 255, 0.4)';
ctx.lineWidth = 1;
ctx.beginPath();
if (b.trail.length > 0) {
const startTrail = b.trail[0];
ctx.moveTo(startTrail.x * SCALE, startTrail.y * SCALE);
b.trail.forEach((p, j) => {
ctx.lineTo(p.x * SCALE, p.y * SCALE);
});
}
ctx.stroke();
// Draw body itself (re-draw to ensure visibility over faint trail edge)
const drawX = b.pos.x * SCALE + canvas.width / 2;
const drawY = b.pos.y * SCALE;
ctx.beginPath();
ctx.arc(drawX, drawY, b.radius, 0, Math.PI * 2);
ctx.fillStyle = color || '#fff';
ctx.fill();
});
requestAnimationFrame(() => { update_simulation(); draw(); });
}
// Initialize the simulation loop upon load
window.onload = () => {
setup();
draw();
};
</script></body></html>
```Show code
```html
<!DOCTYPE html>
<html>
<head>
<title>N-Body Orbit Simulation</title>
<style>body {margin:0;overflow:hidden;background-color:#000;}</style>
</head>
<body>
<canvas id="c"></canvas><script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
let width = window.innerWidth;
let height = window.innerHeight;
canvas.width = width;
canvas.height = height;
function Body(x, y, vx, vy, r, m, color) {
this.x = x; this.y = y;
this.vx = vx; this.vy = vy;
this.r = r; this.m = m;
this.color = color;
this.trail = [];
}
const G = 100; // Gravitational constant scale factor, adjusted for visualization speed
let planets = [
new Body(width/2 - 150, height/2, 0 - Math.sqrt((G * 1e10) / 150), 0, 8, 1e9, 'cyan'), // Planet 1 (Semi-circular, faster velocity)
new Body(width/2 + 100, height/2, 0, Math.sqrt((G * 1e10) / 100), 6, 5e9, 'yellowgreen'), // Planet 2 (Near circular)
new Body(width/2 - 280, height/2, 0, -Math.sqrt((G * 1e10) / 280), 7, 1e8, 'orange'), // Planet 3 (Slower, outer orbit)
];
// Comet: Highly elliptical starting point/velocity guess for a swing past origin
let comet = new Body(width/2 + 350, height/2, - Math.sqrt(1 * G*1e10 / 350), 0, 4, 5e6, 'white');
const dt = 0.1;
const trailLength = 800;
function updateBodies() {
let bodies = [...planets, comet];
for (let body of bodies) {
// Calculate acceleration vector A = G*M/r^2 * R_vec / r
let dx = body.x - width/2;
let dy = body.y - height/2;
let r2 = dx * dx + dy * dy;
if (r2 < 1) r2 = 1; // Avoid division by zero
let r_inv3 = 1 / Math.pow(Math.sqrt(r2), 3);
let accX = G * body.m * dx * r_inv3;
let accY = G * body.m * dy * r_inv3;
// Integration (Basic Euler)
body.vx += accX * dt;
body.vy += accY * dt;
body.x += body.vx * dt;
body.y += body.vy * dt;
// Trail management
body.trail.push({ x: body.x, y: body.y });
if (body.trail.length > trailLength) {
body.trail.shift();
}
}
}
function draw() {
ctx.fillStyle = 'rgba(0, 0, 0, 0.1)'; // Fading effect background fill
ctx.fillRect(0, 0, width, height);
let bodies = [...planets, comet];
for (let body of bodies) {
// Draw Trail
ctx.strokeStyle = body.color;
ctx.globalAlpha = 0.5;
ctx.lineWidth = 1;
ctx.beginPath();
if (body.trail.length > 0) {
ctx.moveTo(body.trail[0].x, body.trail[0].y);
for (let i = 1; i < body.trail.length; i++) {
let alpha = i / body.trail.length * 0.5 + 0.2; // Fade effect calculation
ctx.strokeStyle = `rgba(${body.color === 'cyan' ? '0, 255, 255' : (body.color === 'yellowgreen' ? '102, 204, 0' : (body.color === 'orange' ? '255, 165, 0' : '255, 255, 255')}), ${Math.round(alpha * 255)}, ${Math.round(alpha * 255)}, ${Math.round(alpha * 255)})`;
ctx.lineTo(body.trail[i].x, body.trail[i].y);
}
ctx.stroke();
}
// Draw Body (Sun fixed at center)
ctx.globalAlpha = 1;
ctx.fillStyle = body.color || 'gold';
ctx.beginPath();
ctx.arc(body.x, body.y, body.r, 0, Math.PI * 2);
ctx.fill();
}
requestAnimationFrame(draw_loop);
}
function draw_loop() {
updateBodies();
draw();
}
window.onresize = () => {
width = window.innerWidth;
height = window.innerHeight;
canvas.width = width;
canvas.height = height;
};
if (typeof requestAnimationFrame !== 'undefined') draw_loop();
</script>
</body>
</html>
```DNF — infrastructure: 10/10 requests returned status 500
Show code
```html
<!DOCTYPE html>
<html>
<head>
<title>Orbital Mechanics Demo</title>
<style>
canvas { border: 1px solid black; }
</style>
<script>
const GRAVITATIONAL_CONSTANT = 0.001;
let sun = { x: 200, y: 200, vx: 0, vy: 0 };
let planets = [
{ r: 10, angle: Math.PI / 2 },
{ r: 30, angle: 3 * Math.PI / 4 },
{ r: 60, angle: Math.PI }
];
let comet = {
r: 50,
e: 0.75,
x: 200 + Math.random() * 100 - 50,
y: Math.random() * 300 - 150,
vx: (sun.x - this.x) / ((Math.pow(sun.x, 2) + Math.pow(sun.y, 2)) ** 0.5),
vy: (sun.y - this.y) / ((Math.pow(sun.x, 2) + Math.pow(sun.y, 2)) ** 0.5)
};
let drawSun = (canvas) => {
const ctx = canvas.getContext('2d');
ctx.beginPath();
ctx.arc(canvas.width/2, canvas.height/2, 10, 0, 2 * Math.PI);
ctx.fillStyle = 'yellow';
ctx.fill();
}
let updatePlanets = () => {
planets.forEach(p => {
const dx = p.x - sun.x;
const dy = p.y - sun.y;
p.vx += (GRAVITATIONAL_CONSTANT * 1 / (Math.pow(dx, 2) + Math.pow(dy, 2))) * (dx/sun.y);
p.vy += (GRAVITATIONAL_CONSTANT * 1 / (Math.pow(dx, 2) + Math.pow(dy, 2))) * (dy/sun.y);
p.x += p.vx;
p.y += p.vy;
});
}
let updateComet = () => {
comet.vx += GRAVITATIONAL_CONSTANT * ((sun.x - comet.x) / (Math.pow(comet.x - sun.x, 2) + Math.pow(comet.y - sun.y, 2)));
comet.vy += GRAVITATIONAL_CONSTANT * ((sun.y - comet.y) / (Math.pow(comet.x - sun.x, 2) + Math.pow(comet.y - sun.y, 2)));
comet.x += comet.vx;
comet.y += comet.vy;
if (comet.y < sun.y && comet Vy > 0) {
comet Vy = -comet Vy * comet.e;
}
}
let clearCanvas = (canvas) => {
const ctx = canvas.getContext('2d');
ctx.clearRect(0, 0, canvas.width, canvas.height);
}
let drawTrail = (ctx, p) => {
let l = 1
while (l >= 5) {
drawPlanet(ctx, Math.cos(p.angle), Math.sin(p.angle));
if(l%10 === 0)
break;
ctx.clearRect(0, 0, canvas.width, canvas.height);
drawSun(canvas.getContext('2d'));
};
};
let drawPlanets = (ctx, p) => {
const c = new Array();
for (let [x, y] of planets) {
c.push([x,y]);
}
};
function drawPlanet(ctx, x, y)
{
ctx.beginPath();
ctx.arc(200+x*30, 200+y*30, 10, 0, 2 * Math.PI);
ctx.fillStyle = 'blue';
ctx.fill();
}
let animate = (timestamp) => {
updatePlanets();
updateComet()
const canvas = document.querySelector('canvas');
clearCanvas(canvas);
drawSun(canvas);
planets.forEach(planet =>
drawTrail(
canvas.getContext('2d'),
planet
)
);
requestAnimationFrame(animate);
}
let initialize = () => {
let canvas = document.createElement('canvas');
const ctx = canvas.getContext('2d');
canvas.width = 400;
canvas.height = 300;
animate();
};
document.addEventListener("DOMContentLoaded", function() {
document.body.appendChild(document.createElement('canvas'));
});
</script>
</head>
<body>
</body>
</html>
```Show code
```html
<!DOCTYPE html>
<html><head><title>Orbital Mechanics</title>
<style>canvas{border:1px solid silver;background:#000}</style></head>
<body style="overflow:hidden;margin:0;">
<canvas id=c size=512 512></canvas>
<script>
var c=document.getElementById('c'), ctx=c.getContext('2d');
const SUN_MASS=2e3, G=1.878; // gravitational constant
var sun={x:256,y:256,radius:40,mass:SUN_MASS};
var bodies=[sun];
function init(){ // initialize planets and comet
let a= [80,140,210]; // orbital radii for planets
a.forEach((r,i) => {
const angle = i * Math.PI/3;
bodies.push({
mass:i==0?250:100,
radius:r<70?8:(6),
x:Math.cos(angle)*r+sun.x,
y:Math.sin(angle)*r+sun.y,
vx:-Math.sin(angle)*Math.sqrt(G*SUN_MASS/(r)),
vy: Math.cos(angle)*Math.sqrt(G*SUN_MASS/(r)),
ax:0,ay:0,trail:[],
opacity:t=>(1 - Date.now()%(50*(i+2)))/(1 + i)
});
});
// comet initialization
const c={mass:8,radius:4,x:360,y:sun.y-20,vx:-Math.sqrt(G*SUN_MASS/20),
vy:0,ax:0,ay:0,trail:[], opacity:f=>(1-(Date.now()%80))/1};
bodies.push(c);
}
function updateAccels(){
for(let b of bodies){
if(b === sun)continue;
let dx = b.x - sun.x, dy= b.y -sun.y;
distSq=dx*dx + dy*dy;
const force=G*sun.mass*b.mass/(distSq);
b.ax=force * dx/distSq**0.5 /b.mass;
b.ay=force * dy/distSq**0.5 /b.mass;
}
}
function updateVelocities(){
for(let i of bodies){
i.vx +=i.ax*dt; i.vy +=i.ay*dt;
}
}
function integratePosition(){
for(let i of bodies){
const t = dt/2;
i.x += i.vx*t +0.5*i.ax*(t)*t;
i.y += i.vy*t +0.5*i.ay*(t)*t;
}
}
function updateBodies() {
let t1=Date.now();
Object.assign(dt, {value:(Date.now()-gLast)/6e4});
while(dt.value<0.003)t1=gLast+5;
requestAnimationFrame(function(){updateBodies();});
dt.value&&(
(function anim(timestamp){
gLast = timestamp,
updateAccels(),
integratePosition(),
updateVelocities();
draw();
})(t1));
}
function trailUpdate() {
for(let b of bodies){
let i;
b.trail.push({x:b.x,y:b.y,alpha:b.opacity()});
while(b.trail[b.trail.length-1].alpha < (0.8/(b.trail.length)) && b.trail.length>40)b.trail.shift();
}
}
function draw() {
ctx.fillStyle='#000'; ctx.fillRect(0,0,c.width,c.height);
ctx.beginPath(); // sun
ctx.fillStyle='yellow';
ctx.arc(sun.x,sun.y,sun.radius,0,2*Math.PI);
ctx.fill();
for(let b of bodies){
if(b === sun)continue;
const saved=false,
trail=b.trail.slice(0,60).reverse();
ctx.beginPath();
ctx.fillStyle=`hsl(${Math.abs(Date.now()%5)+130},${90 - Math.abs(i*40-20)}%,70}`;
trail.forEach(p => {
if(!saved){
b.x=p.x;b.y=p.y; saved=true;
}
ctx.fillRect(p.x,p.y,b.radius/2,b.radius/2);
});
}
function drawPlanet(x,y,radius,color){ // helper
ctx.beginPath();
ctx.fillStyle=color;
ctx.arc(x,y,radius,0,Math.PI*2);ctx.fill();
}
for(let b of bodies){
if(b === sun)continue;
const ang= (Date.now()%86400)/1e3;
drawPlanet(b.x,b.y,b.radius, `hsl(${(ang/(.4*Math.PI))*50},90%,70)`);
}
}
// Initialize
gLast=0, dt={value:0.03};
init();
trailUpdate(); // ensure trail is ready
updateAccels(); // precompute initial accels
setInterval(updateBodies, 1);
</script>
</body></html>
```Show code
```html
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Orbital Mechanics</title>
<style>
body { margin: 0; overflow: hidden; }
canvas { display: block; }
</style>
</head>
<body>
<canvas id="orchestral"></canvas>
<script>
let canvas = document.getElementById('orchestral');
let ctx = canvas.getContext('2d');
canvas.width = window.innerWidth;
canvas.height = window.innerHeight;
const G = 1e-3;
const bodies = [
{m: 100, x: canvas.width / 2, y: canvas.height / 2, vx: 0, vy: 0, trail: []},
{m: 1, x: 50, y: 180, vx: 3, vy: 4, trail: []},
{m: 1, x: 300, y: canvas.height / 2, vx: -2.2, vy: 0.6, trail: []},
{m: 5, x: 700, y: 150, vx: 0, vy: 4.8, trail: []},
{m: 3, x: canvas.width / 2 + 350, y: canvas.height - 50, vx: -6.9, vy: -2, trail: []}
];
function drawBody(body) {
ctx.beginPath();
ctx.arc(body.x, body.y, Math.sqrt(body.m), 0, 2 * Math.PI);
ctx.fillStyle = 'white';
ctx.fill();
if (body.trail.length > 100) body.trail.shift();
for (let i = 0; i < body.trail.length; i++) {
let point = body.trail[i];
ctx.beginPath();
ctx.arc(point.x, point.y, 2 * Math.sqrt(body.m), 0, 2 * Math.PI);
ctx.fillStyle = `rgba(255, 255, 255, ${1 - i / 50})`;
ctx.fill();
}
}
function draw() {
ctx.clearRect(0, 0, canvas.width, canvas.height);
for (let body of bodies) {
drawBody(body);
}
for (let body of bodies.slice(1)) {
let fx = 0;
let fy = 0;
for (let other of bodies) {
if (body !== other) {
let dx = other.x - body.x;
let dy = other.y - body.y;
let r2 = dx * dx + dy * dy;
let force = G * other.m * body.m / r2;
fx += force * dx / Math.sqrt(r2);
fy += force * dy / Math.sqrt(r2);
}
}
body.vx += fx / body.m;
body.vy += fy / body.m;
body.x += body.vx;
body.y += body.vy;
body.trail.push({ x: body.x, y: body.y });
}
requestAnimationFrame(draw);
}
draw();
</script>
</body>
</html>
```Cloud
Show code
```html
<!doctype html>
<html>
<head>
<meta charset="utf-8">
<title>Orbital Mechanics</title>
<style>
html,body{margin:0;height:100%;overflow:hidden;background:#050711}
canvas{display:block;width:100%;height:100%}
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const c=document.getElementById("c"),x=c.getContext("2d");
let W,H,cx,cy,dpr;
function size(){
dpr=devicePixelRatio||1; W=innerWidth; H=innerHeight;
c.width=W*dpr; c.height=H*dpr; x.setTransform(dpr,0,0,dpr,0,0);
cx=W/2; cy=H/2;
}
addEventListener("resize",size); size();
const mu=90000, dt=.018, scale=1;
function body(name,r,clr,rad,phase=0){
let a=phase, px=Math.cos(a)*r, py=Math.sin(a)*r, v=Math.sqrt(mu/r);
return {name,x:px,y:py,vx:-Math.sin(a)*v,vy:Math.cos(a)*v,clr,rad,tr:[]};
}
const bodies=[
body("p1",95,"#6ec6ff",4,.4),
body("p2",155,"#ffd166",5,2.1),
body("p3",230,"#9cff8f",6,4.2)
];
let ra=360,rp=42,a=(ra+rp)/2,vc=Math.sqrt(mu*(2/ra-1/a));
bodies.push({name:"comet",x:ra,y:0,vx:0,vy:vc,clr:"#ffffff",rad:3,tr:[]});
function step(){
for(const b of bodies){
let r2=b.x*b.x+b.y*b.y, r=Math.sqrt(r2), acc=-mu/(r2*r);
b.vx+=b.x*acc*dt; b.vy+=b.y*acc*dt;
}
for(const b of bodies){
b.x+=b.vx*dt; b.y+=b.vy*dt;
b.tr.push([b.x,b.y]);
if(b.tr.length>520)b.tr.shift();
}
}
function draw(){
x.fillStyle="rgba(5,7,17,.22)";
x.fillRect(0,0,W,H);
let g=x.createRadialGradient(cx,cy,0,cx,cy,42);
g.addColorStop(0,"#fff7b0"); g.addColorStop(.35,"#ffb347"); g.addColorStop(1,"rgba(255,120,20,0)");
x.fillStyle=g; x.beginPath(); x.arc(cx,cy,42,0,7); x.fill();
x.fillStyle="#ffd35a"; x.beginPath(); x.arc(cx,cy,13,0,7); x.fill();
for(const b of bodies){
for(let i=1;i<b.tr.length;i++){
let p=b.tr[i-1], q=b.tr[i], alpha=i/b.tr.length;
x.strokeStyle=b.clr+Math.floor(alpha*160).toString(16).padStart(2,"0");
x.lineWidth=b.name==="comet"?1.4:1;
x.beginPath(); x.moveTo(cx+p[0]*scale,cy+p[1]*scale);
x.lineTo(cx+q[0]*scale,cy+q[1]*scale); x.stroke();
}
}
for(const b of bodies){
x.fillStyle=b.clr;
x.beginPath(); x.arc(cx+b.x*scale,cy+b.y*scale,b.rad,0,7); x.fill();
}
}
function loop(){
for(let i=0;i<5;i++)step();
draw();
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>
```Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Orbital Mechanics</title>
<style>
body { margin: 0; overflow: hidden; background: #000; }
canvas { display: block; }
</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const canvas = document.getElementById('c');
const ctx = canvas.getContext('2d');
canvas.width = 1200;
canvas.height = 900;
const G = 1;
const M = 10000;
const bodies = [
{x: 600, y: 450, vx: 0, vy: 0, r: 8, col: '#ffcc00', m: M, trail: []},
{x: 800, y: 450, vx: 0, vy: -9, r: 4, col: '#4488ff', m: 1, trail: []},
{x: 950, y: 450, vx: 0, vy: -6, r: 3, col: '#44ff88', m: 1, trail: []},
{x: 1100, y: 450, vx: 0, vy: -4.5, r: 2, col: '#ff8844', m: 1, trail: []},
{x: 700, y: 450, vx: 0, vy: -12, r: 3, col: '#ff00ff', m: 1, trail: []}
];
function update() {
bodies.forEach((b, i) => {
if (i === 0) return;
let ax = 0, ay = 0;
const dx = bodies[0].x - b.x;
const dy = bodies[0].y - b.y;
const r2 = dx*dx + dy*dy;
const r = Math.sqrt(r2);
const f = G * M / r2;
ax = f * dx / r;
ay = f * dy / r;
b.vx += ax * 0.01;
b.vy += ay * 0.01;
b.x += b.vx;
b.y += b.vy;
b.trail.push({x: b.x, y: b.y});
if (b.trail.length > 300) b.trail.shift();
});
}
function draw() {
ctx.fillStyle = '#000';
ctx.fillRect(0, 0, canvas.width, canvas.height);
bodies.forEach(b => {
ctx.strokeStyle = b.col;
ctx.globalAlpha = 0.15;
ctx.lineWidth = 1;
ctx.beginPath();
b.trail.forEach((p, i) => {
if (i === 0) ctx.moveTo(p.x, p.y);
else ctx.lineTo(p.x, p.y);
});
ctx.stroke();
ctx.globalAlpha = 1;
ctx.fillStyle = b.col;
ctx.beginPath();
ctx.arc(b.x, b.y, b.r, 0, Math.PI * 2);
ctx.fill();
});
}
function loop() {
update();
draw();
requestAnimationFrame(loop);
}
loop();
</script>
</body>
</html>Show code
<!DOCTYPE html>
<html><head><meta charset="utf-8"><title>Orbital Mechanics</title>
<style>body{margin:0;background:#000;overflow:hidden}canvas{display:block}</style></head>
<body><canvas id="c"></canvas>
<script>
const cvs=document.getElementById('c'),ctx=cvs.getContext('2d');
function resize(){cvs.width=innerWidth;cvs.height=innerHeight}
resize();addEventListener('resize',resize);
const G=800000,M=1;
function cx(){return cvs.width/2}
function cy(){return cvs.height/2}
function circular(r,dir=1){
const v=Math.sqrt(G*M/r);
return {x:cx()+r,y:cy(),vx:0,vy:dir*v,color:'#fff',trail:[]};
}
let bodies=[
Object.assign(circular(90),{color:'#88ccff'}),
Object.assign(circular(150),{color:'#ffcc66'}),
Object.assign(circular(220),{color:'#88ff99'}),
];
const comet=(()=>{
const r=320,vcirc=Math.sqrt(G*M/r);
return {x:cx()+r,y:cy(),vx:0,vy:vcirc*0.45,color:'#ff6688',trail:[]};
})();
bodies.push(comet);
function frame(){
ctx.fillStyle='rgba(0,0,0,0.15)';
ctx.fillRect(0,0,cvs.width,cvs.height);
const steps=6,dt=0.004;
for(let s=0;s<steps;s++){
bodies.forEach(b=>{
const dx=cx()-b.x,dy=cy()-b.y;
const dist=Math.max(Math.hypot(dx,dy),8);
const a=G*M/(dist*dist);
b.vx+=a*(dx/dist)*dt;b.vy+=a*(dy/dist)*dt;
b.x+=b.vx*dt;b.y+=b.vy*dt;
});
}
ctx.beginPath();ctx.arc(cx(),cy(),14,0,7);
const grad=ctx.createRadialGradient(cx(),cy(),0,cx(),cy(),14);
grad.addColorStop(0,'#fff8dd');grad.addColorStop(1,'#ffaa00');
ctx.fillStyle=grad;ctx.fill();
bodies.forEach(b=>{
b.trail.push({x:b.x,y:b.y});
if(b.trail.length>500)b.trail.shift();
ctx.beginPath();
b.trail.forEach((p,i)=>{if(i===0)ctx.moveTo(p.x,p.y);else ctx.lineTo(p.x,p.y);});
ctx.strokeStyle=b.color;ctx.globalAlpha=0.4;ctx.lineWidth=1;ctx.stroke();
ctx.globalAlpha=1;
ctx.beginPath();ctx.arc(b.x,b.y,5,0,7);ctx.fillStyle=b.color;ctx.fill();
});
requestAnimationFrame(frame);
}
requestAnimationFrame(frame);
</script></body></html>Show code
<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width,initial-scale=1">
<title>Orbital Mechanics</title>
<style>html,body{margin:0;background:#02040a;overflow:hidden}canvas{display:block}</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const cv=document.getElementById('c'),ctx=cv.getContext('2d');
let W,H,cx,cy;
function resize(){W=cv.width=innerWidth;H=cv.height=innerHeight;cx=W/2;cy=H/2;}
addEventListener('resize',resize);resize();
const G=2000,M=1000;
function body(r,c,ecc){const v=Math.sqrt(G*M/r)*(ecc||1);return{x:r,y:0,vx:0,vy:v,c,trail:[]};}
const bodies=[body(70,'#8ecae6'),body(120,'#90ee90'),body(180,'#ffb703'),body(90,'#ff5a5f',0.55)];
const dt=0.05;
function grav(b){for(let k=0;k<4;k++){const r2=b.x*b.x+b.y*b.y,r=Math.sqrt(r2),a=G*M/r2;b.vx-=a*b.x/r*dt;b.vy-=a*b.y/r*dt;b.x+=b.vx*dt;b.y+=b.vy*dt;}}
function step(){ctx.fillStyle='#02040a';ctx.fillRect(0,0,W,H);
ctx.fillStyle='#ffd23f';ctx.beginPath();ctx.arc(cx,cy,12,0,7);ctx.fill();
for(const b of bodies){grav(b);
b.trail.push([b.x,b.y]);if(b.trail.length>400)b.trail.shift();
ctx.strokeStyle=b.c;ctx.beginPath();
for(let i=0;i<b.trail.length;i++){ctx.globalAlpha=i/b.trail.length*0.8;const p=b.trail[i];i?ctx.lineTo(cx+p[0],cy+p[1]):ctx.moveTo(cx+p[0],cy+p[1]);}
ctx.stroke();ctx.globalAlpha=1;
ctx.fillStyle=b.c;ctx.beginPath();ctx.arc(cx+b.x,cy+b.y,4,0,7);ctx.fill();
}
requestAnimationFrame(step);}
step();
</script>
</body>
</html>
Show code
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>Orbital Mechanics</title>
<style>html,body{margin:0;height:100%;background:#020308;overflow:hidden}canvas{display:block}</style>
</head>
<body>
<canvas id="c"></canvas>
<script>
const cv=document.getElementById('c'),ctx=cv.getContext('2d');
let W,H,CX,CY,bodies=[];const GM=400000;
function init(){const s=Math.min(W,H)/560;bodies=[];
[[80,'#4fc3f7',4],[130,'#66bb6a',5],[190,'#ffb74d',6]].forEach(a=>{
const R=a[0]*s;bodies.push({x:CX+R,y:CY,vx:0,vy:Math.sqrt(GM/R),c:a[1],r:a[2]});});
const ra=250*s,rp=42*s,sa=(ra+rp)/2,v=Math.sqrt(GM*(2/ra-1/sa));
bodies.push({x:CX-ra,y:CY,vx:0,vy:-v,c:'#e0f7fa',r:3,comet:true});
ctx.fillStyle='#020308';ctx.fillRect(0,0,W,H);}
function resize(){W=cv.width=innerWidth;H=cv.height=innerHeight;CX=W/2;CY=H/2;init();}
resize();addEventListener('resize',resize);
let last=performance.now();
function frame(t){requestAnimationFrame(frame);
const dt=Math.min((t-last)/1000,0.033);last=t;
const steps=80,h=dt*2/steps;
for(const b of bodies)for(let i=0;i<steps;i++){
const dx=CX-b.x,dy=CY-b.y,d2=dx*dx+dy*dy,d=Math.sqrt(d2),a=GM/d2;
b.vx+=a*dx/d*h;b.vy+=a*dy/d*h;b.x+=b.vx*h;b.y+=b.vy*h;}
ctx.fillStyle='rgba(2,3,8,0.035)';ctx.fillRect(0,0,W,H);
const gr=ctx.createRadialGradient(CX,CY,2,CX,CY,26);
gr.addColorStop(0,'#fff8d0');gr.addColorStop(0.4,'#ffd54f');gr.addColorStop(1,'rgba(255,160,0,0)');
ctx.fillStyle=gr;ctx.beginPath();ctx.arc(CX,CY,26,0,7);ctx.fill();
for(const b of bodies){ctx.fillStyle=b.c;ctx.beginPath();ctx.arc(b.x,b.y,b.r,0,7);ctx.fill();
if(b.comet){const dx=b.x-CX,dy=b.y-CY,d=Math.hypot(dx,dy);
ctx.strokeStyle='rgba(224,247,250,0.5)';ctx.lineWidth=1;
ctx.beginPath();ctx.moveTo(b.x,b.y);ctx.lineTo(b.x+dx/d*18,b.y+dy/d*18);ctx.stroke();}}}
requestAnimationFrame(frame);
</script>
</body>
</html>