438

Gerstner Ocean Waves

František Gerstner's exact nonlinear trochoidal ocean wave equation, exhibiting physically accurate sharpened wave crests and broad, flat troughs.

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';

// Trochoidal Gerstner Non-Linear Ocean Wave Superposition
export function createGerstnerOceanWaves(): ArtRenderer {
  const WAVE_LINES = 32;
  const POINTS_PER_LINE = 160;

  return {
    setup() {},

    render(context: RenderContext, timeState: TimeState, params: ParameterState) {
      const { ctx, width, height } = context;
      const speed = Number(params.waveSpeed || 1.2);
      const steepness = Number(params.steepness || 0.65);
      const t = timeState.time * speed;

      ctx.fillStyle = '#050a12';
      ctx.fillRect(0, 0, width, height);

      // 4 Directional Gerstner wave components (DirX, DirY, Wavelength, Amplitude, Speed)
      const waves = [
        { dx: 1.0, dy: 0.1, length: 140, amp: 26, s: 1.0 },
        { dx: 0.8, dy: 0.6, length: 85, amp: 14, s: 1.4 },
        { dx: 0.5, dy: -0.8, length: 50, amp: 8, s: 1.8 },
        { dx: -0.7, dy: 0.7, length: 30, amp: 4, s: 2.2 },
      ];

      for (let l = 0; l < WAVE_LINES; l++) {
        const normL = l / WAVE_LINES;
        const originY = height * 0.25 + normL * (height * 0.65);

        ctx.beginPath();
        for (let i = 0; i <= POINTS_PER_LINE; i++) {
          const normX = i / POINTS_PER_LINE;
          const x0 = normX * width;
          const y0 = originY;

          let displacedX = x0;
          let displacedY = y0;

          // Gerstner Displacement Sum
          for (let w = 0; w < waves.length; w++) {
            const wv = waves[w];
            const k = (2 * Math.PI) / wv.length;
            const wSpeed = Math.sqrt(9.8 * k) * wv.s;
            const phase = k * (wv.dx * x0 + wv.dy * y0) - wSpeed * t;

            // Trochoidal horizontal pinching & vertical crest peaking
            const q = steepness / (k * wv.amp * waves.length);
            displacedX -= (wv.dx / k) * (q * Math.sin(phase));
            displacedY -= wv.amp * Math.cos(phase);
          }

          if (i === 0) ctx.moveTo(displacedX, displacedY);
          else ctx.lineTo(displacedX, displacedY);
        }

        // Ocean depth color gradient: deep navy below, glowing turquoise crests
        const hue = (195 + normL * 35) % 360;
        const lightness = 40 + (1 - normL) * 35;
        ctx.strokeStyle = hsla(hue, 90, lightness, 0.75);
        ctx.lineWidth = 1.6 - normL * 0.6;
        ctx.stroke();
      }
    },
  };
}
Edit in Interactive Playground Zero Dependencies • Standalone Canvas 2D
ƒ

Mathematical Formulation

medium
Analytical Equation
x=x0−∑i=1NkikiQiAisin⁡(ki⋅x0−ωit),y=y0+∑i=1NAicos⁡(ki⋅x0−ωit)\mathbf{x} = \mathbf{x}_0 - \sum_{i=1}^{N} \frac{\mathbf{k}_i}{k_i} Q_i A_i \sin(\mathbf{k}_i \cdot \mathbf{x}_0 - \omega_i t), \quad y = y_0 + \sum_{i=1}^{N} A_i \cos(\mathbf{k}_i \cdot \mathbf{x}_0 - \omega_i t)
Click to expand
Compact Formula
x = x0 - (dx/k)*Q*sin(phase), y = y0 - A*cos(phase), phase = k*(dx*x0 + dy*y0) - ωt

Mathematical Tags

#ocean #gerstner #waves #hydrodynamics #nature #water #physics
Author: Math Art Core Target: 60 FPS

Export & Embed: Gerstner Ocean Waves

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/gerstner-ocean-waves" 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! ✨