438

Spiral Galaxy Density

Chia-Chiao Lin and Frank Shu's stellar density wave model explaining long-lived spiral arm patterns through quasi-stationary compression waves.

Playground
60 FPS • Canvas 2D
Click + Drag to interact with field
</>

Full Executable Algorithm Code


import type { ArtRenderer, ParameterState, RenderContext, TimeState } from '../../types/engine';
import { hsla } from '../common/color';

// Lin-Shu Spiral Density Wave Galaxy Theory
export function createGalaxySpiralDensity(): ArtRenderer {
  const STARS = 2500;
  const starR = new Float32Array(STARS);
  const starTheta = new Float32Array(STARS);
  const starSpeed = new Float32Array(STARS);

  return {
    setup() {
      for (let i = 0; i < STARS; i++) {
        // Density exponential distribution
        starR[i] = Math.pow(Math.random(), 1.6) * 220 + 8;
        starTheta[i] = Math.random() * Math.PI * 2;
        // Flat rotation curve v ~ const for dark matter halo
        starSpeed[i] = 0.8 + 0.2 * (starR[i] / 220);
      }
    },

    render(context: RenderContext, timeState: TimeState, params: ParameterState) {
      const { ctx, width, height } = context;
      const t = timeState.time * Number(params.speed || 0.6);
      const arms = Number(params.armCount || 2);
      const pitch = Number(params.pitchAngle || 0.22);
      const scale = Math.min(width, height) / 500;

      ctx.fillStyle = 'rgba(8, 9, 13, 0.2)';
      ctx.fillRect(0, 0, width, height);

      const cx = width * 0.5;
      const cy = height * 0.5;

      // Galaxy core
      ctx.fillStyle = '#ffffff';
      ctx.shadowColor = '#38bdf8';
      ctx.shadowBlur = 24;
      ctx.beginPath();
      ctx.arc(cx, cy, 6 * scale, 0, Math.PI * 2);
      ctx.fill();
      ctx.shadowBlur = 0;

      for (let i = 0; i < STARS; i++) {
        starTheta[i] += (starSpeed[i] / (starR[i] * 0.4 + 10)) * 0.4;

        // Logarithmic spiral perturbation: theta_arm = (1/pitch) * ln(r/r0)
        const armPhase = (1 / pitch) * Math.log(starR[i] / 10) - t * 0.4;
        const distToArm = Math.sin(arms * (starTheta[i] - armPhase));

        // Density wave compression
        const effectiveR = starR[i] * (1 - 0.12 * distToArm);
        const px = cx + Math.cos(starTheta[i]) * effectiveR * scale;
        const py = cy + Math.sin(starTheta[i]) * effectiveR * scale;

        const isArm = distToArm > 0.3;
        const hue = isArm ? (200 + starR[i] * 0.3) % 360 : (270 + starR[i] * 0.4) % 360;
        const alpha = Math.min(1, Math.max(0.15, (1 - starR[i] / 240) * (isArm ? 1 : 0.4)));

        ctx.fillStyle = hsla(hue, 90, 70, alpha);
        ctx.fillRect(px, py, 1.5 * scale, 1.5 * scale);
      }
    },
  };
}
Edit in Interactive Playground Zero Dependencies • Standalone Canvas 2D
ƒ

Mathematical Formulation

high
Analytical Equation
Σ(r,θ,t)=Σ0(r)+Σ1(r)cos⁡[m(θ−Ωpt−f(r))],f(r)=ln⁡(r/r0)tan⁡i\Sigma(r, \theta, t) = \Sigma_0(r) + \Sigma_1(r) \cos\left[ m \left( \theta - \Omega_p t - f(r) \right) \right], \quad f(r) = \frac{\ln(r/r_0)}{\tan i}
Click to expand
Compact Formula
armPhase = (1/pitch) * ln(r/10) - 0.4t, r_eff = r * (1 - 0.12 * sin(m*(θ - armPhase)))

Mathematical Tags

#galaxy #density-wave #astrophysics #spiral #space #stars
Author: Math Art Core Target: 60 FPS

Export & Embed: Spiral Galaxy Density

4K PNG Snapshot

High-resolution single frame render

WebM Video (5s Loop)

60 FPS browser-captured stream

Standalone JS Script

Complete executable Canvas 2D algorithm

HTML Iframe Embed

<iframe src="https://art.fazleyrabbi.xyz/embed/galaxy-spiral-density" width="500" height="500" frameborder="0" loading="lazy"></iframe>
ESC
↑↓ Navigate ↵ Select
113 Mathematical Artworks
Made by Fazley Rabbi
☕

Support the Project

Keep mathematical creative coding alive & open source

Or via Direct Payoneer ($0 Fee)
Payoneer Customer ID: $0 Fee Direct
24076084

💡 Payoneer app: Go to Pay → Pay to recipient → Enter ID 24076084.

Thank you for supporting generative mathematical animations! ✨