228

Nautilus Shell Spiral

Cephalopod chambered shell growth governed by the logarithmic equiangular spiral r = a*exp(b*theta), featuring internal curved septa walls and siphuncle canal.

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

Full Executable Algorithm Code

// 030 - Nautilus Shell Spiral (creatures)
// 1:1 Original algorithm engine source
function createNautilusSpiral() {
  const SPIRAL_STRANDS = 32;
  const CHAMBERS = 24;
  return {
    setup() {
    },
    render(context, timeState, params) {
      const { ctx, width, height } = context;
      const speed = Number(params.growthRate || 0.8);
      const chambersCount = Number(params.chamberCount || 20);
      const t = timeState.time * speed;
      ctx.fillStyle = "#020307";
      ctx.fillRect(0, 0, width, height);
      const cx = width * 0.5;
      const cy = height * 0.5;
      const scale = Math.min(width, height) * 0.38;
      const rotY = t * 0.4;
      const rotX = 0.45 + Math.sin(t * 0.3) * 0.25;
      const rotZ = Math.sin(t * 0.2) * 0.15;
      ctx.save();
      ctx.globalCompositeOperation = "screen";
      const baseHue = (25 + Math.sin(t * 0.5) * 20) % 360;
      const b = 0.175;
      const maxTheta = Math.PI * 4.4;
      for (let s = 0; s < SPIRAL_STRANDS; s++) {
        const normS = (s + 1) / SPIRAL_STRANDS;
        const a = scale * 0.035 * (0.4 + normS * 0.75);
        ctx.beginPath();
        const steps = 120;
        let avgDepth = 0;
        for (let i = 0; i <= steps; i++) {
          const theta = i / steps * maxTheta;
          const r = a * Math.exp(b * theta);
          const rawX = r * Math.cos(theta);
          const rawY = r * Math.sin(theta);
          const rawZ = (theta / maxTheta - 0.5) * (scale * 0.4) * (1 - normS * 0.3);
          const p = project3D(rawX, rawY, rawZ, rotX, rotY, rotZ, cx, cy, 450, 520);
          avgDepth += p.depth;
          if (i === 0) ctx.moveTo(p.x, p.y);
          else ctx.lineTo(p.x, p.y);
        }
        avgDepth /= steps + 1;
        const strandHue = (baseHue + normS * 35) % 360;
        const alpha = (0.05 + normS * 0.3) * avgDepth;
        ctx.strokeStyle = hsla(strandHue, 95, 72, alpha);
        ctx.lineWidth = Math.max(0.7, (normS > 0.88 ? 1.6 : 0.8) * avgDepth);
        ctx.stroke();
      }
      for (let c = 1; c <= CHAMBERS; c++) {
        if (c > chambersCount) break;
        const normC = c / CHAMBERS;
        const thetaC = normC * maxTheta;
        const rOuter = scale * 0.035 * 1.15 * Math.exp(b * thetaC);
        const rInner = scale * 0.035 * 1.15 * Math.exp(b * (thetaC - Math.PI * 2));
        const zOuter = (thetaC / maxTheta - 0.5) * (scale * 0.4);
        const zInner = ((thetaC - Math.PI * 2) / maxTheta - 0.5) * (scale * 0.4);
        const p1 = project3D(
          rOuter * Math.cos(thetaC),
          rOuter * Math.sin(thetaC),
          zOuter,
          rotX,
          rotY,
          rotZ,
          cx,
          cy,
          450,
          520
        );
        const p2 = project3D(
          Math.max(0, rInner) * Math.cos(thetaC - Math.PI * 2),
          Math.max(0, rInner) * Math.sin(thetaC - Math.PI * 2),
          zInner,
          rotX,
          rotY,
          rotZ,
          cx,
          cy,
          450,
          520
        );
        ctx.beginPath();
        ctx.moveTo(p2.x, p2.y);
        ctx.lineTo(p1.x, p1.y);
        ctx.strokeStyle = hsla(190, 100, 80, 0.4 * p1.depth);
        ctx.lineWidth = Math.max(0.8, 1.2 * p1.depth);
        ctx.stroke();
      }
      ctx.beginPath();
      for (let i = 0; i <= 80; i++) {
        const theta = i / 80 * maxTheta;
        const r = scale * 0.035 * 0.65 * Math.exp(b * theta);
        const rawX = r * Math.cos(theta);
        const rawY = r * Math.sin(theta);
        const rawZ = (theta / maxTheta - 0.5) * (scale * 0.4) * 0.8;
        const p = project3D(rawX, rawY, rawZ, rotX, rotY, rotZ, cx, cy, 450, 520);
        if (i === 0) ctx.moveTo(p.x, p.y);
        else ctx.lineTo(p.x, p.y);
      }
      ctx.strokeStyle = "#38bdf8";
      ctx.shadowColor = "#38bdf8";
      ctx.shadowBlur = 10;
      ctx.lineWidth = 1.6;
      ctx.stroke();
      ctx.shadowBlur = 0;
      ctx.restore();
    }
  };
}

// Default parameters from content metadata
const defaultParams = [
  {
    "key": "spinSpeed",
    "label": "Iridescent Rotation",
    "type": "range",
    "min": 0.1,
    "max": 1.5,
    "step": 0.05,
    "defaultValue": 0.4,
    "description": "Shell rotation speed"
  },
  {
    "key": "chamberCount",
    "label": "Septa Chambers",
    "type": "range",
    "min": 12,
    "max": 48,
    "step": 2,
    "defaultValue": 36,
    "description": "Number of internal camera walls"
  }
];

if (!window.__art_instances) window.__art_instances = {};
if (!window.__art_instances['nautilus-spiral']) {
  const inst = typeof createNautilusSpiral === 'function' ? createNautilusSpiral() : null;
  if (inst && inst.setup) {
    inst.setup({ ctx, width, height, dpr: 1, aspectRatio: width / height }, defaultParams);
  }
  window.__art_instances['nautilus-spiral'] = inst;
}

const instance = window.__art_instances['nautilus-spiral'];
if (instance && instance.render) {
  instance.render(
    { ctx, width, height, dpr: 1, aspectRatio: width / height },
    { time, deltaTime: dt, frameCount: Math.floor(time * 60), fps: 60 },
    defaultParams
  );
}
Edit in Interactive Playground Zero Dependencies • Standalone Canvas 2D
ƒ

Mathematical Formulation

medium
Analytical Equation
r(θ)=aebθ,b=ln(ϕ)2π0.1759,α=cot1(b)r(\theta) = a e^{b \theta}, \quad b = \frac{\ln(\phi)}{2\pi} \approx 0.1759, \quad \alpha = \cot^{-1}(b)
Click to expand
Compact Formula
r = a * exp(0.1759 * θ), septum_arch = quadCurve(inPoint, outPoint)

Mathematical Tags

#nautilus #spiral #logarithmic #creatures #golden-ratio #geometry
Author: Math Art Core Target: 60 FPS

Export & Embed: Nautilus Shell Spiral

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/nautilus-spiral" width="500" height="500" frameborder="0" loading="lazy"></iframe>
ESC
↑↓ Navigate Select
110 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! ✨