Гравитационная симуляция

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) {
 ...