438

DNA Double Helix

Watson-Crick B-DNA molecular structure modeled as dual out-of-phase intertwined 3D parametric helices connected by complementary hydrogen-bonded nucleotide rungs.

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

export function createDNADoubleHelix(): ArtRenderer {
  const BASE_PAIRS = 40;

  return {
    setup() {},

    render(context: RenderContext, timeState: TimeState, params: ParameterState) {
      const { ctx, width, height } = context;
      const speed = Number(params.rotationSpeed || 1.0);
      const helixRadius = Number(params.helixRadius || 85);
      const t = timeState.time * speed;

      ctx.fillStyle = '#05060a';
      ctx.fillRect(0, 0, width, height);

      const cx = width * 0.5;
      const cy = height * 0.5;
      const helixHeight = height * 0.85;
      const startY = cy - helixHeight * 0.5;

      // Base pair nodes array for depth sorting
      const nodes: {
        y: number;
        x1: number;
        z1: number;
        x2: number;
        z2: number;
        pairType: number;
      }[] = [];

      for (let i = 0; i < BASE_PAIRS; i++) {
        const normY = i / (BASE_PAIRS - 1);
        const y = startY + normY * helixHeight;
        // Two full helical turns (4*pi)
        const theta = normY * Math.PI * 4 + t * 2;

        const x1 = Math.cos(theta) * helixRadius;
        const z1 = Math.sin(theta) * helixRadius;

        const x2 = Math.cos(theta + Math.PI) * helixRadius;
        const z2 = Math.sin(theta + Math.PI) * helixRadius;

        nodes.push({ y, x1, z1, x2, z2, pairType: i % 4 });
      }

      // Sort base pairs by depth (average z)
      nodes.sort((a, b) => (a.z1 + a.z2) / 2 - (b.z1 + b.z2) / 2);

      for (let i = 0; i < nodes.length; i++) {
        const n = nodes[i];

        const px1 = cx + n.x1;
        const py1 = n.y;
        const depth1 = (n.z1 + helixRadius) / (helixRadius * 2); // 0 to 1

        const px2 = cx + n.x2;
        const py2 = n.y;
        const depth2 = (n.z2 + helixRadius) / (helixRadius * 2);

        // 1. Hydrogen Bond Horizontal Base Pair Rung
        ctx.beginPath();
        ctx.moveTo(px1, py1);
        ctx.lineTo(px2, py2);

        // Nucleotide color coding: A-T (Cyan/Indigo), G-C (Emerald/Rose)
        const baseHue = n.pairType < 2 ? 190 : 340;
        const avgDepth = (depth1 + depth2) * 0.5;
        ctx.strokeStyle = hsla(baseHue, 85, 60, 0.4 + avgDepth * 0.5);
        ctx.lineWidth = 1.8 + avgDepth * 1.5;
        ctx.stroke();

        // 2. Sugar-Phosphate Strand Nodes
        // Node 1
        ctx.fillStyle = hsla(185, 95, 70, 0.6 + depth1 * 0.4);
        ctx.beginPath();
        ctx.arc(px1, py1, 3.5 + depth1 * 3.5, 0, Math.PI * 2);
        ctx.fill();

        // Node 2
        ctx.fillStyle = hsla(280, 95, 75, 0.6 + depth2 * 0.4);
        ctx.beginPath();
        ctx.arc(px2, py2, 3.5 + depth2 * 3.5, 0, Math.PI * 2);
        ctx.fill();
      }
    },
  };
}
Edit in Interactive Playground Zero Dependencies • Standalone Canvas 2D
ƒ

Mathematical Formulation

medium
Analytical Equation
r1(z)=[Rcos⁡(ωz+t)Rsin⁡(ωz+t)z],r2(z)=[Rcos⁡(ωz+π+t)Rsin⁡(ωz+π+t)z]\mathbf{r}_1(z) = \begin{bmatrix} R \cos(\omega z + t) \\ R \sin(\omega z + t) \\ z \end{bmatrix}, \quad \mathbf{r}_2(z) = \begin{bmatrix} R \cos(\omega z + \pi + t) \\ R \sin(\omega z + \pi + t) \\ z \end{bmatrix}
Click to expand
Compact Formula
strand1 = [R cos(4πy + 2t), y], strand2 = [R cos(4πy + π + 2t), y], base_rung = line(s1, s2)

Mathematical Tags

#dna #genetics #helix #anatomy #biology #3d #molecular
Author: Math Art Core Target: 60 FPS

Export & Embed: DNA Double Helix

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/dna-double-helix" 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! ✨