# Beta decay
<!-- MICROSIMGEN:BEGIN v1.7 — generated by g08_place_microsims.py; three.js first (§15); do not hand-edit inside -->
## Microsims — p5.js
### Beta decay (p5.js)
<div class="microsim-player">
<iframe src="https://editor.p5js.org/sciencenibber/full/RnDl-UCo_" width="100%" height="480" frameborder="0" loading="lazy" sandbox="allow-scripts allow-same-origin" title="Beta decay — p5.js microsim"></iframe>
</div>
*Two hundred nuclei decay stochastically while a second panel renders the continuous Fermi beta spectrum — the shape that forced Pauli's neutrino.*
**Open in the editor:** [▶ fork this sketch](https://editor.p5js.org/sciencenibber/sketches/RnDl-UCo_) · library `p5js`
### Related microsims
Live sims on neighbouring articles — 4 of them inside this article's own Wikipedia link tree:
- [[Atomic_mass]] *(in tree)*
- [[Decay_chain]] *(in tree)*
- [[Half-life]] *(in tree)*
- [[Thorium]] *(in tree)*
- [[Plutonium]]
*Sim hosted off-article; the article owns the reference, not the runtime (WIKI_RULES §10.4). Placed by `g08_place_microsims.py`.*
<!-- g09-shelf-note -->
> **Also on this page:** 1 further p5.js sketch already published for this article live further down. Per WIKI_RULES §5 a collision promotes rather than forks — they are one shelf, not rivals; this block is the §10.4 *current best* reference.
<!-- MICROSIMGEN:END -->
## Microsim
### Live player
<div class="microsim-player">
<iframe src="https://editor.p5js.org/sciencenibber/full/6EKFi6NAU" width="100%" height="620" frameborder="0" sandbox="allow-scripts allow-same-origin"></iframe>
</div>
<div class="microsim-fallback">
<img src="Microsims/thumbs/Beta_decay.png" alt="Beta_decay microsim poster" style="width:100%;border:1px solid #4445;border-radius:6px;">
<p><em>Live microsim (desktop) · <a href="https://editor.p5js.org/sciencenibber/sketches/6EKFi6NAU">open sketch in the p5.js editor</a></em></p>
</div>
**Editor URL:** https://editor.p5js.org/sciencenibber/sketches/6EKFi6NAU
**Description (100 words):**
The left half of the canvas hosts a single nucleus of 24 mixed protons and neutrons; the right half is a live [[Histogram|histogram]] of emitted beta kinetic energies. A Poisson trial each frame fires a decay event: one nucleon flips identity, a bright yellow beta-particle track flies out, and a magenta antineutrino track shoots out roughly opposite. Sliders set the Q-value (endpoint energy) and decay constant lambda; a button toggles between beta-minus and beta-plus modes. The accumulated histogram fills in under the analytic Fermi-spectrum envelope, demonstrating why the continuous beta spectrum demanded a hidden neutrino.
```js
// =====================================================================
// Beta_decay.js -- Wikitube microsim
// Article: Beta_decay en.wikitube.io/wiki/Beta_decay
// Room: Helium Pattern: E (particle field
// with stochastic emission)
// ---------------------------------------------------------------------
// Idea: visualize the weak-interaction transmutation of a nucleon
// alongside the famous continuous beta spectrum. The left half of
// the canvas shows a single nucleus rendered as a cluster of nucleon
// dots (protons hot, neutrons cool). Every frame a Poisson trial
// decides whether the nucleus decays; when it does, one nucleon
// flips identity and two outgoing tracks fly out -- a beta particle
// (electron for beta-minus, positron for beta-plus) and a (anti-)
// neutrino partner. The right half accumulates the kinetic energy
// of each emitted beta into a histogram, building up the continuous
// beta spectrum bin by bin -- the very curve whose continuous shape
// forced Pauli to postulate the neutrino in 1930.
//
// Physics underneath the sketch
// -----------------------------
// Decay mode toggle:
// beta-minus: n -> p + e- + nu-bar (Z -> Z+1, A unchanged)
// beta-plus : p -> n + e+ + nu (Z -> Z-1, A unchanged)
// The number of un-decayed parents obeys the radioactive decay law
//
// dN/dt = -lambda N => N(t) = N0 * exp(-lambda * t)
//
// with half-life t_half = ln 2 / lambda. The sketch uses dimensionless
// units: lambda is set by the user (0.05 .. 3.0 per second), Q-value
// by the user (0.2 .. 2.5 MeV).
//
// The allowed-transition beta spectrum (Fermi 1933, ignoring the
// Coulomb-correction Fermi function F(Z, E) for simplicity) is
//
// N(E) dE ~ p * (E + m_e c^2) * (Q - E)^2 dE
//
// where p = sqrt(E * (E + 2 m_e c^2)) is the relativistic electron
// momentum, E is the kinetic energy of the emitted lepton, and Q is
// the endpoint energy. The (Q - E)^2 factor is the phase-space
// weighting of the unseen neutrino sharing the remaining energy.
// The sketch samples this distribution by rejection (a uniform
// proposal on [0, Q] vs. the analytic envelope, ~10 tries average).
//
// When the decay fires, the kinetic energies are split:
// E_beta = sample from N(E) above
// E_nu = Q - E_beta (neutrino carries the remainder)
// Both leptons launch from the decayed nucleon's screen position in
// randomly chosen but back-to-back-ish directions (a small angular
// spread reminds the reader the daughter nucleus recoils too).
//
// Visual layout (720 x 520 canvas)
// --------------------------------
// top-left: HUD title (22pt) + en.wikitube.io/wiki/Beta_decay
// left half: nucleus (protons orange, neutrons blue) with live
// beta and antineutrino tracks fading over ~120 frames
// right half: beta-spectrum histogram, 40 bins from 0 to Q_max,
// ASCII axes, count text top-right of plot
// bottom row: Q-value slider, lambda slider, mode toggle (beta-
// minus / beta-plus), reset button -- all docked at
// the same baseline with .position().size()
// bottom-right corner: canonical equations in ASCII
//
// Conventions (Wikitube Betterfire Standard v0)
// ---------------------------------------------
// * single ARTICLE constant at top, single quotes
// * p5.disableFriendlyErrors = true (no FES noise in editor)
// * createCanvas(720, 520), pixelDensity(2), textFont('system-ui')
// * every createSlider has .position(x, y).size(w)
// * non-ASCII characters (Greek lambda, mu, beta, neutrino) live in
// COMMENTS ONLY -- every text() string literal is plain ASCII
// * Energy-room palette from P5_JS_EDITOR section 4
// =====================================================================
const ARTICLE = 'Beta_decay';
const TITLE = ARTICLE.replace(/_/g, ' ');
p5.disableFriendlyErrors = true;
// ----- Energy-room palette (P5_JS_EDITOR section 4) ------------------
const BG = 18;
const FG = 240;
const DIM = [240, 240, 240, 150];
const HOT = [220, 110, 60]; // proton: warm
const COLD = [60, 130, 220]; // neutron: cool
const STRUCT = [120, 130, 150]; // axes, scratch, nucleon outlines
const TRAJ = [240, 220, 80]; // beta particle trail
const ACCENT = [200, 100, 220]; // (anti-)neutrino trail (magenta)
const BAR = [120, 220, 140]; // histogram bar fill (gauge green)
// ----- Physical and rendering constants ------------------------------
// All energies expressed in MeV. Electron rest-mass energy:
const M_E_C2 = 0.511; // m_e c^2 in MeV
const Q_MIN = 0.2;
const Q_MAX = 2.5;
const LAMBDA_MIN = 0.05;
const LAMBDA_MAX = 3.0;
const BINS = 40; // histogram resolution
const MAX_TRACKS = 80; // particle trails kept on screen
// Canvas regions: left half is the nucleus theatre, right half is the
// spectrum plot. Splitting at x = 360 leaves room for axis labels.
const NUC_CX = 175; // nucleus theatre center x
const NUC_CY = 235; // nucleus theatre center y
const NUC_R = 80; // nucleus visual radius
const PLOT_X0 = 380; // plot left edge
const PLOT_Y0 = 90; // plot top edge
const PLOT_W = 310;
const PLOT_H = 270;
// ----- UI control handles (created inside setup) ---------------------
let qSlider, lambdaSlider, modeButton, resetBtn;
// ----- Simulation state ----------------------------------------------
// nucleons[]: each is {x, y, kind} where kind is 'p' or 'n' and (x, y)
// is the screen position inside the nucleus (placed once in setup and
// re-balanced when a decay flips identity).
let nucleons = [];
const N_NUCLEONS = 24; // mass number A shown in the cluster
// tracks[]: outgoing lepton trails. Each is
// {x, y, vx, vy, life, kind} with kind in 'beta' or 'nu'.
let tracks = [];
// histogram bin counts of emitted beta kinetic energies (MeV).
let hist = new Array(BINS).fill(0);
let totalDecays = 0;
let runTime = 0; // accumulated sim time (seconds)
// mode: 0 = beta-minus (n -> p), 1 = beta-plus (p -> n)
let mode = 0;
// ===================================================================
// setup(): create the canvas, place initial nucleons, build UI.
// ===================================================================
function setup() {
createCanvas(720, 520);
pixelDensity(2);
textFont('system-ui');
textSize(13);
// Place A nucleons in a roughly close-packed disc inside NUC_R.
// The pattern: a central nucleon, then six on a ring, then twelve
// on an outer ring, etc. Truncate to N_NUCLEONS.
buildNucleus();
// Slider layout: three controls plus two buttons docked at y = 470 .. 500
// Spacing chosen so labels (drawn in drawControlsRow) don't overlap.
qSlider = createSlider(Q_MIN, Q_MAX, 1.0, 0.05).position(20, 470).size(160);
lambdaSlider = createSlider(LAMBDA_MIN, LAMBDA_MAX, 0.6, 0.01).position(210, 470).size(160);
modeButton = createButton('mode: beta-minus').position(20, 500);
modeButton.mousePressed(() => {
mode = 1 - mode;
modeButton.html(mode === 0 ? 'mode: beta-minus' : 'mode: beta-plus');
// Flipping mode keeps the running histogram (it is mode-agnostic
// in shape; the (e-) and (e+) spectra differ only in the Coulomb
// Fermi-function correction, which the sketch omits).
});
resetBtn = createButton('reset spectrum').position(210, 500);
resetBtn.mousePressed(() => {
hist = new Array(BINS).fill(0);
totalDecays = 0;
runTime = 0;
tracks = [];
buildNucleus();
});
}
// -------------------------------------------------------------------
// buildNucleus(): place A nucleons on a hex-ish disc and assign Z
// protons (the rest are neutrons). We pick Z roughly equal to N for
// a stable-looking nucleus drawing -- the exact Z is cosmetic, the
// physics in the sketch is per-decay and not nuclear-structural.
// -------------------------------------------------------------------
function buildNucleus() {
nucleons = [];
const Z = Math.floor(N_NUCLEONS / 2); // half protons, half neutrons
// Ring layout: ring k has 6k nucleons (for k >= 1), 1 at center.
let placed = 0;
// center nucleon
nucleons.push({ x: NUC_CX, y: NUC_CY, kind: 'p' }); placed++;
// outer rings
let ring = 1;
const RING_DR = 18;
while (placed < N_NUCLEONS) {
const count = 6 * ring;
const r = ring * RING_DR;
for (let i = 0; i < count && placed < N_NUCLEONS; i++) {
const theta = (i / count) * TWO_PI + ring * 0.4; // slight twist per ring
const x = NUC_CX + r * cos(theta);
const y = NUC_CY + r * sin(theta);
// alternate proton / neutron around the ring for a clean look,
// then fix the global count at the end.
nucleons.push({ x, y, kind: (i % 2 === 0) ? 'p' : 'n' });
placed++;
}
ring++;
}
// Re-assign kinds so the global Z is exactly the target.
for (let i = 0; i < nucleons.length; i++) {
nucleons[i].kind = (i < Z) ? 'p' : 'n';
}
// Shuffle the kind labels around the disc so protons and neutrons
// are visually mixed rather than half-on-one-side.
shuffleKinds();
}
function shuffleKinds() {
// Fisher-Yates on the 'kind' tags, leaving (x, y) put.
const kinds = nucleons.map(n => n.kind);
for (let i = kinds.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
const t = kinds[i]; kinds[i] = kinds[j]; kinds[j] = t;
}
for (let i = 0; i < nucleons.length; i++) nucleons[i].kind = kinds[i];
}
// ===================================================================
// draw(): each frame, advance the Poisson decay process, integrate
// the outgoing tracks, then render every region of the canvas.
// ===================================================================
function draw() {
background(BG);
const Q = qSlider.value(); // endpoint energy (MeV)
const lambda = lambdaSlider.value(); // decay rate (per second)
const dt = min(deltaTime / 1000, 0.05);
runTime += dt;
// ---- Step 1: Poisson decay trial -------------------------------
// For small lambda * dt the probability of a decay this frame is
// ~ lambda * dt. We sample one Bernoulli per frame; for higher
// lambda we could do a Poisson count, but visually one event per
// frame at max reads as a steady stream and stays uncluttered.
if (Math.random() < lambda * dt && countParents() > 0) {
fireDecay(Q);
}
// ---- Step 2: integrate outgoing tracks -------------------------
// Tracks travel at constant velocity (no field) and fade over
// ~120 frames. When life <= 0 they're removed.
for (let i = tracks.length - 1; i >= 0; i--) {
const t = tracks[i];
t.x += t.vx * dt * 60; // dt * 60 so vx is in px/frame
t.y += t.vy * dt * 60;
t.life -= 1;
if (t.life <= 0 || t.x < -20 || t.x > width + 20 ||
t.y < -20 || t.y > height + 20) {
tracks.splice(i, 1);
}
}
if (tracks.length > MAX_TRACKS) tracks.splice(0, tracks.length - MAX_TRACKS);
// ---- Step 3: render --------------------------------------------
drawNucleusTheatre(Q);
drawTracks();
drawSpectrumPlot(Q);
drawReadouts(Q, lambda);
drawControlsRow();
drawHUD();
drawEquationBox();
}
// -------------------------------------------------------------------
// countParents(): how many candidate nucleons are eligible for the
// current decay mode. For beta-minus the candidates are neutrons;
// for beta-plus, protons. If the population reaches zero the decay
// cannot fire and the slider just spins the clock.
// -------------------------------------------------------------------
function countParents() {
const target = (mode === 0) ? 'n' : 'p';
let c = 0;
for (const n of nucleons) if (n.kind === target) c++;
return c;
}
// -------------------------------------------------------------------
// fireDecay(Q): pick a parent nucleon, flip its kind, sample a beta
// kinetic energy from the spectrum N(E) ~ p (E + me) (Q - E)^2, then
// spawn one beta track and one (anti-)neutrino track. Energy is
// pushed into the histogram.
// -------------------------------------------------------------------
function fireDecay(Q) {
const target = (mode === 0) ? 'n' : 'p';
const flipped = (mode === 0) ? 'p' : 'n';
// Find a random parent of the correct kind.
const candidates = [];
for (let i = 0; i < nucleons.length; i++) {
if (nucleons[i].kind === target) candidates.push(i);
}
if (candidates.length === 0) return;
const idx = candidates[Math.floor(Math.random() * candidates.length)];
nucleons[idx].kind = flipped;
// Sample beta kinetic energy by rejection on N(E) over [0, Q].
const E = sampleBetaEnergy(Q);
const Enu = Q - E;
// Launch tracks from the decayed nucleon's position in two
// approximately back-to-back directions. The recoil of the daughter
// nucleus would in reality break exact back-to-back-ness; here we
// add a small randomized offset (about +/- 25 deg).
const baseAngle = Math.random() * TWO_PI;
const wobble = (Math.random() - 0.5) * 0.9; // ~ +/- 25 deg
const x0 = nucleons[idx].x;
const y0 = nucleons[idx].y;
// Beta velocity: speed grows with kinetic energy. Map E in
// [0, Q_MAX] linearly to pixel speed in [1, 3.2] px/frame.
const betaSpeed = map(E, 0, Q_MAX, 1.0, 3.2, true);
tracks.push({
x: x0, y: y0,
vx: betaSpeed * cos(baseAngle),
vy: betaSpeed * sin(baseAngle),
life: 130,
kind: 'beta',
energy: E,
});
// Neutrino: faster, fainter, opposite-ish direction. Neutrinos
// basically never interact, so the trail is rendered as a thin
// dashed line that fades quickly.
const nuSpeed = map(Enu, 0, Q_MAX, 1.5, 3.6, true);
const nuAngle = baseAngle + PI + wobble;
tracks.push({
x: x0, y: y0,
vx: nuSpeed * cos(nuAngle),
vy: nuSpeed * sin(nuAngle),
life: 130,
kind: 'nu',
energy: Enu,
});
// Histogram: bin by E in [0, Q_MAX] regardless of current Q so the
// global axis stays put while Q changes; samples outside [0, Q] are
// physically impossible and already excluded by the sampler.
const bin = Math.floor((E / Q_MAX) * BINS);
const safe = Math.max(0, Math.min(BINS - 1, bin));
hist[safe] += 1;
totalDecays += 1;
}
// -------------------------------------------------------------------
// sampleBetaEnergy(Q): rejection sampler on the allowed-transition
// spectrum N(E) ~ p (E + m_e c^2) (Q - E)^2 for E in [0, Q].
// The envelope max is bounded by sampling several E grid points;
// rejection success rate is typically 30-60%.
// -------------------------------------------------------------------
function sampleBetaEnergy(Q) {
// Precompute envelope max by scanning a 32-point grid.
let nmax = 0;
for (let k = 0; k <= 32; k++) {
const e = (k / 32) * Q;
const v = betaSpectrum(e, Q);
if (v > nmax) nmax = v;
}
if (nmax <= 0) return 0.5 * Q; // pathological; shouldn't happen
// Rejection sample (cap iterations to stay fast).
for (let tries = 0; tries < 200; tries++) {
const e = Math.random() * Q;
const u = Math.random() * nmax;
if (u <= betaSpectrum(e, Q)) return e;
}
return Math.random() * Q; // fallback uniform if RNG ran cold
}
// -------------------------------------------------------------------
// betaSpectrum(E, Q): allowed-transition Fermi spectrum, unnormalized.
// Returns 0 outside [0, Q] for cleanliness.
// -------------------------------------------------------------------
function betaSpectrum(E, Q) {
if (E < 0 || E > Q) return 0;
// p = sqrt(E (E + 2 m_e c^2)) (relativistic momentum)
const p = Math.sqrt(E * (E + 2 * M_E_C2));
const dE = Q - E;
return p * (E + M_E_C2) * dE * dE;
}
// ===================================================================
// Rendering: nucleus theatre, tracks, histogram, readouts, HUD.
// ===================================================================
// -------------------------------------------------------------------
// drawNucleusTheatre(Q): the left-half scene. A faint disc boundary
// + an outline ring keep the eye anchored when individual nucleons
// flip color.
// -------------------------------------------------------------------
function drawNucleusTheatre(Q) {
// Region header
noStroke(); fill(...DIM);
textSize(12);
text('Nucleus (A = ' + N_NUCLEONS + ')', 20, 90);
// Faint bounding disc.
noFill();
stroke(...STRUCT); strokeWeight(1);
drawingContext.setLineDash([4, 4]);
ellipse(NUC_CX, NUC_CY, 2 * NUC_R, 2 * NUC_R);
drawingContext.setLineDash([]);
// Nucleons
strokeWeight(1);
for (const nuc of nucleons) {
if (nuc.kind === 'p') {
fill(HOT[0], HOT[1], HOT[2]);
stroke(255, 200, 160);
} else {
fill(COLD[0], COLD[1], COLD[2]);
stroke(180, 200, 255);
}
ellipse(nuc.x, nuc.y, 12, 12);
}
// Mini-legend just below the disc.
textSize(11);
noStroke();
fill(HOT[0], HOT[1], HOT[2]); ellipse(NUC_CX - 50, NUC_CY + NUC_R + 22, 10, 10);
fill(...DIM); text('proton', NUC_CX - 40, NUC_CY + NUC_R + 26);
fill(COLD[0], COLD[1], COLD[2]); ellipse(NUC_CX + 5, NUC_CY + NUC_R + 22, 10, 10);
fill(...DIM); text('neutron', NUC_CX + 15, NUC_CY + NUC_R + 26);
}
// -------------------------------------------------------------------
// drawTracks(): outgoing lepton trails. The beta trail is bright
// yellow and thick; the neutrino trail is magenta and dashed to
// signal 'almost never interacts'.
// -------------------------------------------------------------------
function drawTracks() {
for (const t of tracks) {
const alpha = map(t.life, 0, 130, 0, 220, true);
if (t.kind === 'beta') {
stroke(TRAJ[0], TRAJ[1], TRAJ[2], alpha);
strokeWeight(2);
drawingContext.setLineDash([]);
} else {
stroke(ACCENT[0], ACCENT[1], ACCENT[2], alpha * 0.7);
strokeWeight(1.2);
drawingContext.setLineDash([3, 4]);
}
// Short tail behind the particle (10 px) for motion legibility.
const tailLen = (t.kind === 'beta') ? 12 : 14;
const sx = t.x - t.vx * tailLen;
const sy = t.y - t.vy * tailLen;
line(sx, sy, t.x, t.y);
}
drawingContext.setLineDash([]);
}
// -------------------------------------------------------------------
// drawSpectrumPlot(Q): the right half. Histogram of accumulated beta
// kinetic energies plus the analytic envelope curve overlaid for
// comparison.
// -------------------------------------------------------------------
function drawSpectrumPlot(Q) {
// Plot frame
noFill();
stroke(...STRUCT); strokeWeight(1);
rect(PLOT_X0, PLOT_Y0, PLOT_W, PLOT_H);
// Plot title
noStroke(); fill(...DIM);
textSize(12);
text('Beta kinetic-energy spectrum (E)', PLOT_X0, PLOT_Y0 - 8);
// Normalize histogram to its current peak for vertical scaling.
let hmax = 1;
for (let i = 0; i < BINS; i++) if (hist[i] > hmax) hmax = hist[i];
// Bars
const bw = PLOT_W / BINS;
noStroke();
fill(BAR[0], BAR[1], BAR[2], 200);
for (let i = 0; i < BINS; i++) {
const h = (hist[i] / hmax) * (PLOT_H - 20);
rect(PLOT_X0 + i * bw, PLOT_Y0 + PLOT_H - h, bw - 1, h);
}
// Analytic envelope: sample 100 points across [0, Q] and trace.
noFill();
stroke(TRAJ[0], TRAJ[1], TRAJ[2], 220);
strokeWeight(1.4);
beginShape();
const samples = 100;
// Find envelope max for normalization separately (its scale differs
// from histogram, but we overlay them on the same vertical extent).
let emax = 0;
for (let k = 0; k <= samples; k++) {
const e = (k / samples) * Q;
const v = betaSpectrum(e, Q);
if (v > emax) emax = v;
}
if (emax <= 0) emax = 1;
for (let k = 0; k <= samples; k++) {
const e = (k / samples) * Q;
const v = betaSpectrum(e, Q);
const px = PLOT_X0 + (e / Q_MAX) * PLOT_W;
const py = PLOT_Y0 + PLOT_H - 20 - (v / emax) * (PLOT_H - 30);
vertex(px, py);
}
endShape();
// X-axis tick marks at 0, 0.5, 1, 1.5, 2, 2.5 MeV (limited by Q_MAX)
stroke(...STRUCT); strokeWeight(1);
textSize(10); noStroke(); fill(...DIM);
for (let e = 0; e <= Q_MAX + 0.001; e += 0.5) {
const x = PLOT_X0 + (e / Q_MAX) * PLOT_W;
stroke(...STRUCT);
line(x, PLOT_Y0 + PLOT_H, x, PLOT_Y0 + PLOT_H + 4);
noStroke(); fill(...DIM);
text(e.toFixed(1), x - 6, PLOT_Y0 + PLOT_H + 16);
}
noStroke(); fill(...DIM); textSize(11);
text('E (MeV)', PLOT_X0 + PLOT_W - 50, PLOT_Y0 + PLOT_H + 30);
push();
translate(PLOT_X0 - 24, PLOT_Y0 + PLOT_H / 2 + 30);
rotate(-HALF_PI);
text('counts', 0, 0);
pop();
// Endpoint marker: vertical dashed line at E = Q.
stroke(TRAJ[0], TRAJ[1], TRAJ[2], 200);
strokeWeight(1);
drawingContext.setLineDash([4, 4]);
const xQ = PLOT_X0 + (Q / Q_MAX) * PLOT_W;
line(xQ, PLOT_Y0, xQ, PLOT_Y0 + PLOT_H);
drawingContext.setLineDash([]);
noStroke(); fill(TRAJ[0], TRAJ[1], TRAJ[2]); textSize(10);
text('Q', xQ + 3, PLOT_Y0 + 12);
}
// -------------------------------------------------------------------
// drawReadouts(Q, lambda): live numerical state in the top-right of
// the plot area: total decays, mean energy, current Q, current
// half-life ln 2 / lambda.
// -------------------------------------------------------------------
function drawReadouts(Q, lambda) {
let mean = 0;
let totalCounts = 0;
for (let i = 0; i < BINS; i++) {
const eMid = (i + 0.5) * (Q_MAX / BINS);
mean += eMid * hist[i];
totalCounts += hist[i];
}
if (totalCounts > 0) mean /= totalCounts;
const tHalf = Math.log(2) / Math.max(lambda, 1e-6);
noStroke();
fill(FG); textSize(12);
const x = PLOT_X0 + 10;
const y = PLOT_Y0 + 18;
text('decays: ' + totalDecays, x, y + 0);
text('mean E: ' + mean.toFixed(3) + ' MeV', x, y + 18);
text('Q: ' + Q.toFixed(2) + ' MeV', x, y + 36);
text('lambda: ' + lambda.toFixed(2) + ' /s', x, y + 54);
text('t_half: ' + tHalf.toFixed(2) + ' s', x, y + 72);
}
// -------------------------------------------------------------------
// drawControlsRow(): labels for the slider baseline. Keeps the row
// at y = 470 .. 510 self-describing without needing tooltips.
// -------------------------------------------------------------------
function drawControlsRow() {
noStroke(); fill(...DIM); textSize(11);
text('Q (MeV)', 20, 463);
text('lambda (1/s)', 210, 463);
}
// -------------------------------------------------------------------
// drawHUD(): title block at top-left of the canvas. Title is large
// bright, subtitle dim. This is the BF2/BF3 anchor for the Betterfire
// Standard.
// -------------------------------------------------------------------
function drawHUD() {
noStroke();
fill(FG); textSize(22);
text(TITLE, 14, 36);
fill(...DIM); textSize(12);
text('Wikitube microsim . en.wikitube.io/wiki/Beta_decay', 14, 56);
}
// -------------------------------------------------------------------
// drawEquationBox(): canonical relations in the bottom-right corner,
// pure ASCII so the Friendly Error System has nothing to complain
// about and the editor preview is faithful at any DPI.
// -------------------------------------------------------------------
function drawEquationBox() {
noStroke();
fill(...DIM); textSize(11);
const x = width - 320;
const y = height - 60;
text('dN/dt = -lambda * N t_half = ln 2 / lambda', x, y);
text('N(E) ~ p * (E + m_e c^2) * (Q - E)^2', x, y + 14);
text('p = sqrt( E * (E + 2 m_e c^2) )', x, y + 28);
}
```
## Links (Wikipedia order)
<!-- injected from _registry/childlinks/Beta_decay.json (2026-07-30T02:09:12Z) -->
`(n-p)_reaction` · `Aage_Bohr` · `Ab_initio_methods_(nuclear_physics)` · `Age_of_the_universe` · `Alexandru_Proca` · [[Alpha_decay]] · `Alpha_process` · `Angular_momentum_operator` · [[Atomic_mass]] · `Atomic_nucleus` · `Atomic_number` · `Beta-decay_stable_isobars` · `Beta_decay_transition` · `Beta_particle` · `Big_Bang_nucleosynthesis` · `Borromean_nucleus` · `Brookhaven_National_Laboratory` · `CNO_cycle` · `CRC_Press` · `Caesium-137` · `Cambridge_University_Press` · `Carbon-14` · `Carbon-burning_process` · `Carl_David_Anderson` · `Charles_Drummond_Ellis` · `Chien-Shiung_Wu` · `Chirality_(physics)` · `Clinton_Davisson` · `Cluster_decay` · `Clyde_Cowan` · `Cobalt-60` · `Common_beta_emitters` · `Conservation_of_energy` · `Copper-64` · `Cosmic_ray_spallation` · `Cosmogenic_nuclide` · `Cowan–Reines_neutrino_experiment` · [[Decay_chain]] · `Decay_energy` · [[Decay_product]] · `Deuterium_fusion` · `Discovery_of_the_neutron` · `Double_beta_decay` · `Double_electron_capture` · `Down_quark` · `Edward_Mills_Purcell` · `Edward_Teller` · `Electric_charge` · [[Electron]] · `Electron_capture` · `Electron_neutrino` · `Electron_shell` · `Electronvolt` · `Elementary_charge` · `Elsevier` · `Enrico_Fermi` · `Ernest_Lawrence` · `Ernest_Rutherford` · `Ernest_Walton` · `Eugene_Wigner` · `Even_and_odd_atomic_nuclei` · `Fermi's_interaction` · `Feynman_diagram` · `Fine-structure_constant` · `Flavour_(particle_physics)` · `Franz_N._D._Kurie` · `Frederick_Reines` · `Frederick_Soddy` · `Fritz_Strassmann` · `Frédéric_Joliot-Curie` · `GSI_Helmholtz_Centre_for_Heavy_Ion_Research` · `Gamma_function` · `Gamma_ray` · `Geiger_counter` · [[Half-life]] · `Halo_nucleus` · `Hans_Bethe` · `Hans_Geiger` · [[Helium-3]] · `Henri_Becquerel` · `Hideki_Yukawa` · `High-energy_nuclear_physics` · `Hydrogen_atom` · `HyperPhysics` · `Interacting_boson_model` · `Internal_conversion` · `Irène_Joliot-Curie` · `Island_of_stability` · `Isobar_(nuclide)` · `Isospin` · `Isotone` · `Isotope` · `Isotopes_of_dysprosium` · `Isotopes_of_holmium` · `Isotopes_of_lead` · `Isotopes_of_nickel` · `Isotopes_of_thallium` · `Isotopes_of_zinc` · `J._Hans_D._Jensen` · `J._J._Thomson` · `J._Robert_Oppenheimer` · `James_Chadwick` · `John_Cockcroft` · `Journal_of_Physics:_Conference_Series` · `Journal_of_Physics_G` · `KATRIN` · `Kazimierz_Fajans` · `Kinetic_energy` · `Ladder_operator` · `Large_Hadron_Collider` · `Le_Moyne_College` · `Lepton_number` · `Lise_Meitner` · `Lithium_burning` · `Luis_Walter_Alvarez` · `Magic_number_(physics)` · `Marie_Curie` · `Mark_Oliphant` · `Mass` · `Mass-to-charge_ratio` · `Mass_excess` · `Mass_number` · `Mass–energy_equivalence` · `Mirror_nuclei` · `Muon` · `National_Nuclear_Data_Center` · `Neon-burning_process` · `Neutrino` · `Neutrinoless_double_beta_decay` · [[Neutron]] · `Neutron_capture` · `Neutron_emission` · `Neutron_number` · `Nevill_Mott` · `Niels_Bohr` · `Nobel_Prize_in_Chemistry` · `Nuclear_Science_and_Engineering` · `Nuclear_astrophysics` · `Nuclear_binding_energy` · `Nuclear_drip_line` · `Nuclear_fission` · `Nuclear_fission_product` · `Nuclear_force` · [[Nuclear_fusion]] · `Nuclear_isomer` · `Nuclear_matter` · `Nuclear_physics` · `Nuclear_reaction` · `Nuclear_shell_model` · `Nuclear_structure` · `Nuclear_transmutation` · `Nucleon` · `Nucleon_pair_breaking_in_fission` · [[Nucleosynthesis]] · `Nuclide` · `Otto_Hahn` · `Oxygen-burning_process` · `P-process` · `Pandemonium_effect` · `Parity_(physics)` · `Particle_radiation` · `Patrick_Blackett` · `Pauli_matrices` · `Periodic_table` · `Perturbation_theory_(quantum_mechanics)` · `Photodisintegration` · `Photofission` · `Physical_Review` · `Physical_Review_Letters` · `Physics_Today` · `Pierre_Curie` · `Plutonium-241` · [[Polonium]] · `Positron` · [[Positron_emission]] · `Potassium-40` · `Primordial_nuclide` · [[Proton]] · `Proton_capture` · `Proton_emission` · `Proton–proton_chain` · `Q_value_(nuclear_science)` · `Quark` · `Quark–gluon_plasma` · `R-process` · [[Radioactive_decay]] · `Radioactive_displacement_law_of_Fajans_and_Soddy` · `Radiogenic_nuclide` · `Radionuclide` · [[Radium]] · `Raymond_Daudel` · `Relativistic_Heavy_Ion_Collider` · `Rp-process` · `S-process` · [[Science_(journal)]] · `Selection_rule` · `Semi-empirical_mass_formula` · `Silicon-burning_process` · `Spallation` · `Spectrometer` · `Speed_of_light` · [[Spin_(physics)]] · `Spin_polarization` · [[Spontaneous_fission]] · `Stable_nuclide` · `Stellar_nucleosynthesis` · `Supernova_nucleosynthesis` · `Synthetic_element` · `Tau_(particle)` · [[Thorium]] · `Total_absorption_spectroscopy` · `Triple-alpha_process` · `Tritium` · `Tsung-Dao_Lee` · `Ultrarelativistic_limit` · `University_of_Chicago_Press` · `Up_quark` · [[Uranium]] · `Valley_of_stability` · `Virtual_particle` · `W_and_Z_bosons` · [[Wayback_Machine]] · `Weak_interaction` · `Wilhelm_Orthmann` · `Wolfgang_Pauli` · `Wu_experiment` · `Władysław_Świątecki_(physicist)` · `Zeitschrift_für_Physik`
## From the Real GENERATIVE library (beauty pass)

*Beta decay — image hotlinked from Wikimedia Commons (via the Real G.E.N.E.R.A.T.I.V.E. course library, Nuclear room). [Details & license](https://commons.wikimedia.org/wiki/File:Beta-minus_Decay.svg).*
> In nuclear physics, beta decay (β-decay) is a type of radioactive decay in which an atomic nucleus emits a beta particle (fast energetic electron or positron), transforming into an isobar of that nuclide. For example, beta decay of a neutron transforms it into a proton by the emission of an electron accompanied by an antineutrino; or, conversely a proton is converted into a neutron by the emission of a positron with a neutrino in what is called positron emission. ([Wikipedia](https://en.wikipedia.org/wiki/Beta_decay))
<!-- BEAUTY-PASS-MEDIA:END -->
> **Room:** [[Helium]] · **Status:** ✅ shipped
## Overview
Beta decay is a form of [[Radioactive_decay|radioactive decay]] in which an atomic nucleus emits a beta particle — an [[Electron|electron]] or positron — accompanied by an antineutrino or neutrino. Mediated by the weak nuclear force, it transmutes one [[Chemical_element|chemical element]] into another by converting a [[Neutron|neutron]] into a [[Proton|proton]] (β⁻ decay) or a proton into a neutron (β⁺ decay), shifting the atomic number by one while leaving the mass number unchanged. A closely related process, electron capture, achieves the same nuclear transformation as β⁺ decay by absorbing an inner-shell electron.
Henri Becquerel first observed beta radiation in 1896, and James Chadwick demonstrated in 1914 that its [[Energy|energy]] spectrum is continuous rather than discrete. This puzzle led Wolfgang Pauli to postulate the neutrino in 1930, and Enrico Fermi formalized the theory in 1933 with a four-[[Fermion|fermion]] interaction that became the prototype for the modern electroweak description in terms of W [[Boson|boson]] exchange. The 1956 Wu experiment revealed that beta decay maximally violates parity symmetry.
The energy released in a beta transition, the Q value, is shared among the emitted lepton, antineutrino, and recoiling daughter nucleus, producing the characteristic continuous beta spectrum bounded by an endpoint energy. Decay rates obey N(t) = N0 exp(-lambda t), with [[Half-life|half-life]] t-half = ln 2 / lambda. Tritium (3H) undergoes β⁻ decay to 3He with a 12.3-year half-life, supplying nearly all terrestrial helium-3 used in [[Cryogenics|cryogenics]], neutron detection, and quantum research.
## See also
- Room hub: [[Helium]]
- p5.js Editor conventions: P5 JS EDITOR
- Wiki root: MAIN
---
*Scaffolded by `generative-microsim` from row 152 of the Helium sheet on 2026-05-14T19:48:29Z.*
<!-- BEAUTY-PASS-MEDIA:START -->
<!-- CRAFT-LINK:START g12 -->
*Built to the [[WT!P5_js_Microsim_Master_Class|p5.js Master Class]].*
<!-- CRAFT-LINK:END -->
## Wikipedia : Wikitube
**Strict pair:** [Wikipedia](https://en.wikipedia.org/wiki/Beta_decay) : [Wikitube](https://en.wikitube.io/wiki/Beta_decay)
## Previous hub tags
Tree parents: [[Helium]] · [[Helium-3]] · [[Hydrogen]] · [[Oxygen]].
Legacy hubs: `GENERATIVE`.
---
*Sources: 2 legacy notes. Minted wave 1, 2026-07-30 (v1.6 order).*