Гравитационная симуляция
by jt3k
HTML
<canvas id="canvas"></canvas>
CSS
body {
margin: 0;
overflow: hidden;
background-color: #000;
}
canvas {
display: block;
}
JavaScript
const canvas = document.getElementById("canvas")
const ctx = canvas.getContext("2d")
canvas.width = window.innerWidth
canvas.height = window.innerHeight
const G = 6.67408e-11 // Реальная гравитационная постоянная
const SCALE_FACTOR = 1e5 // Масштабный коэффициент для лучшей визуализации
const MAX_STARS = 40
const MIN_MASS = -2e10
const MAX_MASS = 2e10
let stars = []
let lastTimestamp = 0
let animationId = null
function initRandomStars() {
stars = []
const count = MAX_STARS;
for (let i = 0; i < count; i++) {
stars.push({
x: Math.random() * canvas.width,
y: Math.random() * canvas.height,
vx: (Math.random() - 0.5) * 0.5,
vy: (Math.random() - 0.5) * 0.5,
mass: MIN_MASS + Math.random() * (MAX_MASS - MIN_MASS),
ax: (Math.random() - 0.5) * 0.5,
ay: (Math.random() - 0.5) * 0.5,
color: getColorByMass(MIN_MASS + Math.random() * (MAX_MASS - MIN_MASS)),
trail: [],
})
}
}
function getColorByMass(mass) {
return `rgb(255, ${Math.floor(255 * Math.max(0, Math.min(1, (mass - MIN_MASS) / (MAX_MASS - MIN_MASS))))}, 0)`
}
function calculateGravitationalForces() {
// Сброс ускорений
for (let star of stars) {
star.ax = 0
star.ay = 0
}
for (let i = 0; i < stars.length; i++) {
for (let j = i + 1; j < stars.length; j++) {
let star1 = stars[i]
let star2 = stars[j]
let dx = star2.x - star1.x
let dy = star2.y - star1.y
let rSquared = dx * dx + dy * dy
let r = Math.sqrt(rSquared)
if (r < 5) continue
// Закон всемирного тяготения с масштабным коэффициентом
let F = ((G * star1.mass * star2.mass) / rSquared) * SCALE_FACTOR
// Ускорение = Сила / масса
let ax = (F * dx) / (r * star1.mass)
let ay = (F * dy) / (r * star1.mass)
star1.ax += ax
star1.ay += ay
star2.ax -= ax
star2.ay -= ay
}
}
}
function updatePositions(dt) {
...