97

Temple Fay Mathematical Butterfly

Mathematical Lepidopteran flight combining Temple H. Fay's transcendental polar butterfly curve with iridescent Morpho blue wing scales, 3D flapping perspective kinematics, and feathery clubbed antennae.

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

Full Executable Algorithm Code

// 071 - Temple Fay Mathematical Butterfly (insects)
// 1:1 Original algorithm engine source
function createMathematicalButterfly() {
  return {
    setup() {
    },
    render(context, timeState, params) {
      const { ctx, width, height } = context;
      const flapSpeed = Number(params.flapSpeed ?? 1.2);
      const wingIridescence = Number(params.iridescence ?? 1);
      const venationDensity = Math.max(3, Math.min(8, Math.round(Number(params.venationDensity ?? 5))));
      const t = timeState.time * flapSpeed;
      ctx.fillStyle = "#040308";
      ctx.fillRect(0, 0, width, height);
      const cx = width * 0.5;
      const cy = height * 0.5;
      const maxR = Math.min(width, height) * 0.44;
      const flapAngle = Math.sin(t * 3.5);
      const flapScaleX = 0.35 + 0.65 * Math.cos(t * 3.5);
      const hoverY = Math.sin(t * 2) * 10;
      ctx.save();
      ctx.translate(cx, cy + hoverY);
      const baseHue = 195;
      for (let s = 0; s < 25; s++) {
        const seed = s * 89.3;
        const sa = Math.sin(seed + t * 0.5) * Math.PI * 2;
        const sr = maxR * (0.3 + 0.6 * Math.sin(seed * 3 + t * 0.4));
        const px = Math.cos(sa) * (sr * flapScaleX);
        const py = Math.sin(sa) * sr + Math.sin(t * 2 + s) * 12;
        const sAlpha = 0.2 + 0.4 * Math.sin(t * 3 + s);
        ctx.fillStyle = hsla(baseHue + s % 3 * 35, 95, 75, sAlpha * wingIridescence);
        ctx.beginPath();
        ctx.arc(px, py, 1.2 + s % 3 * 0.6, 0, Math.PI * 2);
        ctx.fill();
      }
      for (const side of [-1, 1]) {
        ctx.save();
        ctx.scale(side * flapScaleX, 1);
        ctx.beginPath();
        const fPoints = [];
        const fSteps = 70;
        for (let i = 0; i <= fSteps; i++) {
          const u = i / fSteps;
          const theta = u * Math.PI * 0.75 - Math.PI * 0.15;
          const r = maxR * (0.3 + 0.68 * Math.pow(Math.sin(u * Math.PI), 0.7));
          const fx = Math.sin(theta) * r * 1.2;
          const fy = -Math.cos(theta) * r * 0.95;
          fPoints.push({ x: fx, y: fy });
          if (i === 0) ctx.moveTo(fx, fy);
          else ctx.lineTo(fx, fy);
        }
        ctx.closePath();
        const fHue = baseHue + flapAngle * 15;
        ctx.fillStyle = hsla(fHue, 90, 52, 0.45 * wingIridescence);
        ctx.fill();
        ctx.strokeStyle = hsla(fHue + 25, 95, 80, 0.85);
        ctx.lineWidth = 1.4;
        ctx.stroke();
        for (let v = 1; v <= venationDensity; v++) {
          const vFrac = v / (venationDensity + 1);
          const targetPt = fPoints[Math.floor(vFrac * fSteps)];
          ctx.beginPath();
          ctx.moveTo(0, -maxR * 0.08);
          ctx.quadraticCurveTo(targetPt.x * 0.4, targetPt.y * 0.6, targetPt.x, targetPt.y);
          ctx.strokeStyle = hsla(fHue + 35, 90, 85, 0.35);
          ctx.lineWidth = 0.8;
          ctx.stroke();
          ctx.beginPath();
          ctx.moveTo(targetPt.x * 0.5, targetPt.y * 0.5);
          ctx.lineTo(targetPt.x * 0.85, targetPt.y * 0.75);
          ctx.strokeStyle = hsla(fHue + 15, 85, 78, 0.25);
          ctx.lineWidth = 0.6;
          ctx.stroke();
        }
        const eyeX = fPoints[Math.floor(fSteps * 0.55)].x * 0.65;
        const eyeY = fPoints[Math.floor(fSteps * 0.55)].y * 0.65;
        ctx.fillStyle = hsla(fHue + 70, 95, 85, 0.9);
        ctx.beginPath();
        ctx.arc(eyeX, eyeY, 4.5, 0, Math.PI * 2);
        ctx.fill();
        ctx.strokeStyle = "#05040a";
        ctx.lineWidth = 1.6;
        ctx.stroke();
        ctx.beginPath();
        const hSteps = 50;
        const hPoints = [];
        for (let j = 0; j <= hSteps; j++) {
          const v = j / hSteps;
          const phi = v * Math.PI * 0.8 + Math.PI * 0.4;
          const scallop = Math.sin(v * Math.PI * 4) * (maxR * 0.04);
          const hr = maxR * (0.25 + 0.48 * Math.sin(v * Math.PI)) + scallop;
          const hx = Math.sin(phi) * hr * 0.9;
          const hy = -Math.cos(phi) * hr * 0.9;
          hPoints.push({ x: hx, y: hy });
          if (j === 0) ctx.moveTo(hx, hy);
          else ctx.lineTo(hx, hy);
        }
        ctx.closePath();
        ctx.fillStyle = hsla(fHue - 20, 90, 48, 0.4 * wingIridescence);
        ctx.fill();
        ctx.strokeStyle = hsla(fHue + 15, 95, 76, 0.8);
        ctx.lineWidth = 1.3;
        ctx.stroke();
        for (let w = 1; w <= 3; w++) {
          const target = hPoints[Math.floor(w / 4 * hSteps)];
          ctx.beginPath();
          ctx.moveTo(0, maxR * 0.05);
          ctx.quadraticCurveTo(target.x * 0.45, target.y * 0.5, target.x, target.y);
          ctx.strokeStyle = hsla(fHue + 40, 85, 82, 0.3);
          ctx.lineWidth = 0.75;
          ctx.stroke();
        }
        ctx.restore();
      }
      const segCount = 8;
      for (let s = 0; s < segCount; s++) {
        const sNorm = s / segCount;
        const sy = sNorm * maxR * 0.42 - maxR * 0.05;
        const sw = maxR * 0.045 * (1 - sNorm * 0.6);
        const sh = maxR * 0.048;
        ctx.beginPath();
        ctx.ellipse(0, sy, sw, sh * 0.5, 0, 0, Math.PI * 2);
        ctx.fillStyle = hsla(220, 80, 20 + s * 3, 0.95);
        ctx.fill();
        ctx.strokeStyle = hsla(baseHue, 90, 65, 0.7);
        ctx.lineWidth = 1;
        ctx.stroke();
      }
      ctx.beginPath();
      ctx.ellipse(0, -maxR * 0.1, maxR * 0.052, maxR * 0.06, 0, 0, Math.PI * 2);
      ctx.fillStyle = "#0f172a";
      ctx.fill();
      ctx.strokeStyle = hsla(baseHue + 20, 95, 75, 0.9);
      ctx.lineWidth = 1.4;
      ctx.stroke();
      ctx.beginPath();
      ctx.arc(0, -maxR * 0.18, maxR * 0.038, 0, Math.PI * 2);
      ctx.fillStyle = "#020617";
      ctx.fill();
      ctx.strokeStyle = hsla(baseHue, 90, 75, 0.95);
      ctx.lineWidth = 1.2;
      ctx.stroke();
      for (const eyeSide of [-1, 1]) {
        ctx.fillStyle = hsla(baseHue + 45, 100, 85, 0.95);
        ctx.beginPath();
        ctx.arc(eyeSide * (maxR * 0.028), -maxR * 0.185, 2.2, 0, Math.PI * 2);
        ctx.fill();
      }
      for (const antSide of [-1, 1]) {
        const antSway = Math.sin(t * 3 + antSide) * 0.08;
        ctx.beginPath();
        ctx.moveTo(antSide * 2, -maxR * 0.2);
        const tipX = antSide * (maxR * 0.18) + antSway * 10;
        const tipY = -maxR * 0.38;
        ctx.quadraticCurveTo(antSide * (maxR * 0.06), -maxR * 0.32, tipX, tipY);
        ctx.strokeStyle = hsla(baseHue + 30, 95, 85, 0.85);
        ctx.lineWidth = 1.2;
        ctx.stroke();
        ctx.fillStyle = hsla(baseHue + 40, 100, 90, 0.95);
        ctx.beginPath();
        ctx.arc(tipX, tipY, 2.5, 0, Math.PI * 2);
        ctx.fill();
      }
      ctx.restore();
    }
  };
}

// Default parameters from content metadata
const defaultParams = [
  {
    "key": "flapSpeed",
    "label": "Flapping Rate",
    "type": "range",
    "min": 0.4,
    "max": 2.2,
    "step": 0.1,
    "defaultValue": 1.2,
    "description": "Wing flap oscillation cadence"
  },
  {
    "key": "iridescence",
    "label": "Wing Iridescence",
    "type": "range",
    "min": 0.4,
    "max": 1.6,
    "step": 0.1,
    "defaultValue": 1,
    "description": "Structural color reflection intensity"
  },
  {
    "key": "venationDensity",
    "label": "Venation Cells",
    "type": "range",
    "min": 3,
    "max": 8,
    "step": 1,
    "defaultValue": 5,
    "description": "Fractal wing vein branching density"
  }
];

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

const instance = window.__art_instances['mathematical-butterfly'];
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

high
Analytical Equation
r(θ)=esinθ2cos(4θ)+sin5(2θπ24),xflap(t)=x(0.35+0.65cos(ωt))r(\theta) = e^{\sin\theta} - 2\cos(4\theta) + \sin^5\left(\frac{2\theta - \pi}{24}\right), \quad x_\text{flap}(t) = x \cdot \left(0.35 + 0.65\cos(\omega t)\right)
Click to expand
Compact Formula
r = exp(sin θ) - 2*cos(4θ) + sin^5((2θ - π)/24), x = sin(θ)*r*flap_x

Mathematical Tags

#butterfly #insect #lepidoptera #temple-fay #creatures #wings #iridescent #morpho
Author: Math Art Core Target: 60 FPS

Export & Embed: Temple Fay Mathematical Butterfly

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/mathematical-butterfly" width="500" height="500" frameborder="0" loading="lazy"></iframe>
ESC
↑↓ Navigate Select
101 Mathematical Artworks

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! ✨