CCF Light Cone

Simulator
id
2605135640435
title
CCF Light Cone
date
05/13/2026
text
Show source code
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, user-scalable=no">
<title>CCF Light Cone</title>
<style>
@import url('https://fonts.googleapis.com/css2?family=JetBrains+Mono:wght@200;300;400;600&display=swap');
*{margin:0;padding:0;box-sizing:border-box}
body{background:#06060b;font-family:'JetBrains Mono',monospace;overflow:hidden;touch-action:none;color:#c8a84e}

#topPanel{position:absolute;top:0;left:0;right:0;height:50vh;overflow:hidden}
#cv{display:block;width:100%;height:100%;cursor:crosshair;image-rendering:pixelated}
#hud{position:absolute;top:0;left:0;right:0;padding:5px 10px;background:linear-gradient(rgba(6,6,11,0.9),rgba(6,6,11,0));pointer-events:none;display:flex;justify-content:space-between}
.title{font-size:10px;font-weight:600;letter-spacing:1px;color:#c8a84e}
.eq{font-size:8px;color:#666}
.st{font-size:8px;color:#555;text-align:right}
.st b{color:#999}

#botPanel{position:absolute;top:50vh;left:0;right:0;bottom:0;overflow:hidden}
#cone3d{display:block;width:100%;height:100%;cursor:grab}
#cone3d:active{cursor:grabbing}
#coneHud{position:absolute;top:4px;left:0;right:0;text-align:center;pointer-events:none}
#coneHud .t{font-size:9px;font-weight:400;letter-spacing:2px;color:#c8a84e}
#coneHud .s{font-size:7px;color:#6a6040;margin-top:2px}

#divider{position:absolute;top:50vh;left:0;right:0;height:1px;background:#222;z-index:20}

#ctrl{position:absolute;top:calc(50vh - 52px);left:0;right:0;z-index:20;text-align:center;padding:4px 14px;background:linear-gradient(rgba(6,6,11,0),rgba(6,6,11,0.95))}
#ctrl .val{font-size:14px;color:#fff;font-weight:600;letter-spacing:1px;margin-bottom:2px}
#slider{width:80%;max-width:320px;height:5px;-webkit-appearance:none;appearance:none;background:#222;border-radius:3px;outline:none}
#slider::-webkit-slider-thumb{-webkit-appearance:none;width:18px;height:18px;border-radius:50%;background:#c8a84e;cursor:pointer}
#presets{margin-top:4px;display:flex;justify-content:center;gap:4px}
#presets button{background:rgba(200,168,78,0.04);color:#555;border:1px solid #222;font-family:inherit;font-size:7px;padding:3px 7px;cursor:pointer;border-radius:2px}
#presets button:hover{background:rgba(200,168,78,0.1);color:#c8a84e;border-color:#c8a84e}
.copy{position:absolute;bottom:2px;right:6px;font-size:6px;color:#1a1a10;z-index:20}
</style>
</head>
<body>

<div id="topPanel">
<canvas id="cv"></canvas>
<div id="hud">
<div><div class="title" id="mt">CCF Set</div><div class="eq" id="mf">Eₙ₊₁ = Eₙ² + Eₙ₋₁</div><div class="eq" id="mp">emission · full memory</div></div>
<div><div class="st">zoom <b id="zv">×1</b></div><div class="st">iter <b id="iv">80</b></div></div>
</div>
</div>

<div id="ctrl">
<div class="val" id="betaV">β = +1.000 (CCF Set)</div>
<input type="range" id="slider" min="-100" max="100" value="100" step="1">
<div id="presets">
<button onclick="setB(-100)">−1</button>
<button onclick="setB(-50)">−½</button>
<button onclick="setB(0)">0</button>
<button onclick="setB(50)">+½</button>
<button onclick="setB(100)">+1</button>
</div>
</div>

<div id="divider"></div>

<div id="botPanel">
<canvas id="cone3d"></canvas>
<div id="coneHud">
<div class="t">CCF LIGHT CONE — β = e in sig(3,2)</div>
<div class="s">J(β)ᵀGJ(β) = βG · E(n+1) = E(n)² + β·E(n-1)</div>
</div>
</div>

<div class="copy">© 2026 Captain Cookie Face Universe</div>

<script>
// ═══════════════════════════════════════
// SHARED DATA
// ═══════════════════════════════════════
var beta = 1.0;
var slider = document.getElementById('slider');

// Average radius data from original CCF Light Lifecycle simulator
var coneData = [
  [-1.00, 0.6658], [-0.90, 0.8635], [-0.80, 0.9062], [-0.70, 0.9380],
  [-0.60, 0.9497], [-0.50, 0.9631], [-0.40, 0.9724], [-0.30, 0.9832],
  [-0.20, 0.9908], [-0.10, 0.9941], [ 0.00, 0.9950], [ 0.10, 0.9925],
  [ 0.20, 0.9866], [ 0.30, 0.9757], [ 0.40, 0.9631], [ 0.50, 0.9355],
  [ 0.60, 0.8886], [ 0.70, 0.8342], [ 0.80, 0.7814], [ 0.90, 0.6692],
  [ 1.00, 0.2739]
];

function getRadAtBeta(b) {
  for (var i = 0; i < coneData.length - 1; i++) {
    if (b >= coneData[i][0] && b <= coneData[i + 1][0]) {
      var t = (b - coneData[i][0]) / (coneData[i + 1][0] - coneData[i][0]);
      return coneData[i][1] + (coneData[i + 1][1] - coneData[i][1]) * t;
    }
  }
  return coneData[0][1];
}

// ═══════════════════════════════════════
// FRACTAL (TOP)
// ═══════════════════════════════════════
var cv = document.getElementById('cv');
var cx = cv.getContext('2d', { alpha: false });
var fW, fH, img, sX, sY, zm, it;

var P = new Uint8Array(768);
for (var i = 0; i < 255; i++) {
  var r, g, b;
  if (i < 32) { r = i * 8; g = i * 8; b = 127 - i * 4; }
  else if (i < 128) { r = 255; g = 255 - (i - 32) * 2.67 | 0; b = (i - 32) * 1.33 | 0; }
  else if (i < 192) { r = 255 - (i - 128) * 4; g = (i - 128) * 3; b = 127 - (i - 128); }
  else { r = 0; g = 192 - (i - 192) * 3; b = 64 + (i - 192); }
  P[i * 3] = r < 0 ? 0 : r > 255 ? 255 : r;
  P[i * 3 + 1] = g < 0 ? 0 : g > 255 ? 255 : g;
  P[i * 3 + 2] = b < 0 ? 0 : b > 255 ? 255 : b;
}

function szFractal() {
  fW = cv.width = cv.clientWidth;
  fH = cv.height = cv.clientHeight;
  img = cx.createImageData(fW, fH);
}

function ivFractal() {
  sX = fW / 2 | 0; sY = fH / 2 | 0;
  zm = Math.min(fW, fH) / 3.75 | 0;
  it = 80;
}

function drawFractal() {
  var d = img.data, b = beta, esc = 10000;
  for (var py = 0; py < fH; py++) {
    var yn = (py - sY) / zm;
    for (var px = 0; px < fW; px++) {
      var xn = (px - sX) / zm;
      var n = 0, pr = 0, pi = 0, zr = xn, zi = yn, nr, ni;
      while (n < it) {
        if (zr * zr + zi * zi >= esc) break;
        nr = zr * zr - zi * zi + b * pr;
        ni = 2 * zr * zi + b * pi;
        pr = zr; pi = zi; zr = nr; zi = ni; n++;
      }
      var o = (py * fW + px) * 4;
      if (n >= it) { d[o] = 0; d[o + 1] = 0; d[o + 2] = 0; }
      else { var c = n % 255; d[o] = P[c * 3]; d[o + 1] = P[c * 3 + 1]; d[o + 2] = P[c * 3 + 2]; }
      d[o + 3] = 255;
    }
  }
  cx.putImageData(img, 0, 0);
  var baseZm = Math.min(fW, fH) / 3 | 0;
  document.getElementById('zv').textContent = '×' + (zm / baseZm).toFixed(1);
  document.getElementById('iv').textContent = it;
}

// Fractal interaction
var fDrag = 0, fdx, fdy, fPinch = 0, fpd0, fzm0, fRto = null;
function fSched() { if (fRto) clearTimeout(fRto); fRto = setTimeout(function () { drawFractal(); }, 30); }

cv.addEventListener('wheel', function (e) {
  e.preventDefault();
  var rect = cv.getBoundingClientRect();
  var mx = e.clientX - rect.left, my = e.clientY - rect.top;
  var xn = (mx - sX) / zm, yn = (my - sY) / zm;
  zm = Math.max(10, zm * (e.deltaY < 0 ? 1.3 : 0.77) | 0);
  sX = mx - xn * zm + 0.5 | 0; sY = my - yn * zm + 0.5 | 0;
  it = Math.max(50, Math.min(1500, 50 + Math.log(zm / 100 + 1) * 80 | 0));
  fSched();
}, { passive: false });

cv.addEventListener('mousedown', function (e) { fDrag = 1; fdx = e.clientX; fdy = e.clientY; });
cv.addEventListener('mousemove', function (e) { if (!fDrag) return; sX += e.clientX - fdx; sY += e.clientY - fdy; fdx = e.clientX; fdy = e.clientY; fSched(); });
cv.addEventListener('mouseup', function () { fDrag = 0; });

cv.addEventListener('touchstart', function (e) {
  e.preventDefault();
  if (e.touches.length === 2) { fPinch = 1; var a = e.touches[0], b = e.touches[1]; fpd0 = Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY); fzm0 = zm; }
  else if (e.touches.length === 1) { fDrag = 1; fdx = e.touches[0].clientX; fdy = e.touches[0].clientY; }
}, { passive: false });

cv.addEventListener('touchmove', function (e) {
  e.preventDefault();
  if (e.touches.length === 2 && fPinch) {
    var a = e.touches[0], b = e.touches[1];
    var dist = Math.hypot(a.clientX - b.clientX, a.clientY - b.clientY);
    var rect = cv.getBoundingClientRect();
    var cx2 = (a.clientX + b.clientX) / 2 - rect.left, cy2 = (a.clientY + b.clientY) / 2 - rect.top;
    var xn = (cx2 - sX) / zm, yn = (cy2 - sY) / zm;
    zm = Math.max(10, fzm0 * dist / fpd0 | 0);
    sX = cx2 - xn * zm + 0.5 | 0; sY = cy2 - yn * zm + 0.5 | 0;
    it = Math.max(50, Math.min(1500, 50 + Math.log(zm / 100 + 1) * 80 | 0));
    fSched();
  } else if (fDrag && e.touches.length === 1) {
    sX += e.touches[0].clientX - fdx; sY += e.touches[0].clientY - fdy;
    fdx = e.touches[0].clientX; fdy = e.touches[0].clientY; fSched();
  }
}, { passive: false });

cv.addEventListener('touchend', function (e) { if (e.touches.length < 2) fPinch = 0; if (e.touches.length < 1) fDrag = 0; });

// ═══════════════════════════════════════
// 3D CONE (BOTTOM)
// ═══════════════════════════════════════
var c3 = document.getElementById('cone3d');
var g3 = c3.getContext('2d');
var cW, cH, cCx, cCy, cSC;
var cRotX = -0.25, cRotY = 0.3, cTRX = -0.25, cTRY = 0.3;
var cDrag = false, clx, cly;

function szCone() {
  cW = c3.width = c3.clientWidth * 2;
  cH = c3.height = c3.clientHeight * 2;
  c3.style.width = c3.clientWidth + 'px';
  c3.style.height = c3.clientHeight + 'px';
  cCx = cW / 2; cCy = cH / 2;
  cSC = Math.min(cW, cH) * 0.2;
}

c3.addEventListener('mousedown', function (e) { cDrag = true; clx = e.clientX; cly = e.clientY; });
c3.addEventListener('mousemove', function (e) {
  if (!cDrag) return;
  cTRY += (e.clientX - clx) * 0.005; cTRX += (e.clientY - cly) * 0.005;
  cTRX = Math.max(-1.3, Math.min(0.4, cTRX));
  clx = e.clientX; cly = e.clientY;
});
c3.addEventListener('mouseup', function () { cDrag = false; });
c3.addEventListener('mouseleave', function () { cDrag = false; });
c3.addEventListener('touchstart', function (e) { cDrag = true; clx = e.touches[0].clientX; cly = e.touches[0].clientY; }, { passive: true });
c3.addEventListener('touchmove', function (e) {
  if (!cDrag) return;
  cTRY += (e.touches[0].clientX - clx) * 0.005; cTRX += (e.touches[0].clientY - cly) * 0.005;
  cTRX = Math.max(-1.3, Math.min(0.4, cTRX));
  clx = e.touches[0].clientX; cly = e.touches[0].clientY;
  e.preventDefault();
}, { passive: false });
c3.addEventListener('touchend', function () { cDrag = false; });

function cProj(x, y, z) {
  var x1 = x * Math.cos(cRotY) - z * Math.sin(cRotY);
  var z1 = x * Math.sin(cRotY) + z * Math.cos(cRotY);
  var y1 = y * Math.cos(cRotX) - z1 * Math.sin(cRotX);
  var z2 = y * Math.sin(cRotX) + z1 * Math.cos(cRotX);
  var p = 5.5 / (5.5 + z2);
  return { x: cCx + x1 * cSC * p, y: cCy - y1 * cSC * p, z: z2, s: p };
}

function cLn(a, b, col, al, w) {
  if (al < 0.005) return;
  g3.beginPath(); g3.moveTo(a.x, a.y); g3.lineTo(b.x, b.y);
  g3.strokeStyle = col; g3.globalAlpha = al; g3.lineWidth = w;
  g3.stroke(); g3.globalAlpha = 1;
}

function cPt(p, col, r, al) {
  if (al < 0.005) return;
  g3.beginPath(); g3.arc(p.x, p.y, r * p.s, 0, Math.PI * 2);
  g3.fillStyle = col; g3.globalAlpha = al; g3.fill(); g3.globalAlpha = 1;
}

function cLb(p, t, col, sz, ox, oy) {
  g3.font = (sz || 16) + 'px JetBrains Mono';
  g3.fillStyle = col || '#c8a84e'; g3.textAlign = 'center';
  g3.globalAlpha = 0.9;
  g3.fillText(t, p.x + (ox || 0), p.y + (oy || -16));
  g3.globalAlpha = 1;
}

function drawCone3D() {
  g3.clearRect(0, 0, cW, cH);

  // Smooth rotation
  cRotX += (cTRX - cRotX) * 0.07;
  cRotY += (cTRY - cRotY) * 0.07;

  var eLen = 2.0;
  var N = 36;

  // e-axis (β axis)
  var eNeg = cProj(0, 0, eLen);
  var ePos = cProj(0, 0, -eLen);
  var o = cProj(0, 0, 0);
  cLn(eNeg, ePos, '#dd44dd', 0.5, 2.5);
  cLb(ePos, 'β=+1', '#dd44dd', 12, 0, -12);
  cLb(ePos, 'emission', '#aa33aa', 9, 0, 2);
  cLb(eNeg, 'β=−1', '#dd44dd', 12, 0, -12);
  cLb(eNeg, 'absorption', '#aa33aa', 9, 0, 2);

  // Draw all rings
  for (var di = 0; di < coneData.length; di++) {
    var b = coneData[di][0];
    var r = coneData[di][1];
    var eCoord = -b * eLen;

    g3.beginPath();
    var first = true;
    for (var ai = 0; ai <= N; ai++) {
      var ang = ai / N * Math.PI * 2;
      var p = cProj(r * Math.cos(ang), r * Math.sin(ang), eCoord);
      if (first) { g3.moveTo(p.x, p.y); first = false; } else g3.lineTo(p.x, p.y);
    }
    g3.strokeStyle = '#dd44dd';
    g3.globalAlpha = 0.25 + 0.15 * Math.abs(b);
    g3.lineWidth = 2;
    g3.stroke(); g3.globalAlpha = 1;
  }

  // Meridian lines
  for (var mi = 0; mi < 8; mi++) {
    var ang = mi / 8 * Math.PI * 2;
    g3.beginPath();
    var first = true;
    for (var di = 0; di < coneData.length; di++) {
      var b = coneData[di][0], r = coneData[di][1];
      var eCoord = -b * eLen;
      var p = cProj(r * Math.cos(ang), r * Math.sin(ang), eCoord);
      if (first) { g3.moveTo(p.x, p.y); first = false; } else g3.lineTo(p.x, p.y);
    }
    g3.strokeStyle = '#dd44dd';
    g3.globalAlpha = 0.2;
    g3.lineWidth = 1.5;
    g3.stroke(); g3.globalAlpha = 1;
  }

  // Highlight β=0 ring
  var r0 = getRadAtBeta(0);
  g3.beginPath();
  for (var ai = 0; ai <= N; ai++) {
    var ang = ai / N * Math.PI * 2;
    var p = cProj(r0 * Math.cos(ang), r0 * Math.sin(ang), 0);
    ai === 0 ? g3.moveTo(p.x, p.y) : g3.lineTo(p.x, p.y);
  }
  g3.strokeStyle = '#888'; g3.globalAlpha = 0.5; g3.lineWidth = 2;
  g3.stroke(); g3.globalAlpha = 1;
  cLb(cProj(r0 + 0.1, 0, 0), 'β=0', '#888', 10, 15, 0);

  // Highlight β=+1 ring (emission)
  var r1 = coneData[coneData.length - 1][1];
  g3.beginPath();
  for (var ai = 0; ai <= N; ai++) {
    var ang = ai / N * Math.PI * 2;
    var p = cProj(r1 * Math.cos(ang), r1 * Math.sin(ang), -eLen);
    ai === 0 ? g3.moveTo(p.x, p.y) : g3.lineTo(p.x, p.y);
  }
  g3.strokeStyle = '#c8a84e'; g3.globalAlpha = 0.6; g3.lineWidth = 2.5;
  g3.stroke(); g3.globalAlpha = 1;

  // Highlight β=-1 ring (absorption)
  var rn = coneData[0][1];
  g3.beginPath();
  for (var ai = 0; ai <= N; ai++) {
    var ang = ai / N * Math.PI * 2;
    var p = cProj(rn * Math.cos(ang), rn * Math.sin(ang), eLen);
    ai === 0 ? g3.moveTo(p.x, p.y) : g3.lineTo(p.x, p.y);
  }
  g3.strokeStyle = '#4499ff'; g3.globalAlpha = 0.5; g3.lineWidth = 2.5;
  g3.stroke(); g3.globalAlpha = 1;

  // ═══ CURRENT SLICE — bright, animated ═══
  var curR = getRadAtBeta(beta);
  var curE = -beta * eLen;
  var sliceCol = beta > 0.01 ? '#c8a84e' : beta < -0.01 ? '#4499ff' : '#888';

  // Filled slice disk
  g3.beginPath();
  for (var ai = 0; ai <= N; ai++) {
    var ang = ai / N * Math.PI * 2;
    var p = cProj(curR * Math.cos(ang), curR * Math.sin(ang), curE);
    ai === 0 ? g3.moveTo(p.x, p.y) : g3.lineTo(p.x, p.y);
  }
  g3.closePath();
  g3.fillStyle = sliceCol; g3.globalAlpha = 0.12; g3.fill();
  g3.strokeStyle = sliceCol; g3.globalAlpha = 0.8; g3.lineWidth = 3;
  g3.stroke(); g3.globalAlpha = 1;

  // Center dot on slice
  var sliceCenter = cProj(0, 0, curE);
  cPt(sliceCenter, sliceCol, 6, 0.9);

  // Label
  var sign = beta >= 0 ? '+' : '';
  cLb(sliceCenter, 'β=' + sign + beta.toFixed(2), sliceCol, 12, 0, -14);

  requestAnimationFrame(drawCone3D);
}

// ═══════════════════════════════════════
// SLIDER & UPDATE
// ═══════════════════════════════════════
function setB(v) { slider.value = v; ivFractal(); upd(); }

function upd() {
  beta = slider.value / 100;
  var bv = document.getElementById('betaV');
  var mt = document.getElementById('mt');
  var mf = document.getElementById('mf');
  var mp = document.getElementById('mp');
  var sign = beta >= 0 ? '+' : '';

  if (Math.abs(beta - 1) < 0.005) {
    bv.textContent = 'β = +1.000 (CCF Set)'; mt.textContent = 'CCF Set'; mt.style.color = '#c8a84e';
    mf.textContent = 'Eₙ₊₁ = Eₙ² + Eₙ₋₁'; mp.textContent = 'emission · full memory';
  } else if (Math.abs(beta + 1) < 0.005) {
    bv.textContent = 'β = −1.000 (Null Cone)'; mt.textContent = 'CCF Null Cone Set'; mt.style.color = '#4499ff';
    mf.textContent = 'Eₙ₊₁ = Eₙ² − Eₙ₋₁'; mp.textContent = 'absorption · inverse memory';
  } else if (Math.abs(beta) < 0.005) {
    bv.textContent = 'β = 0 (free space)'; mt.textContent = 'E²'; mt.style.color = '#888';
    mf.textContent = 'Eₙ₊₁ = Eₙ²'; mp.textContent = 'free space · circle';
  } else {
    bv.textContent = 'β = ' + sign + beta.toFixed(3);
    mt.textContent = 'E² + β·E(n-1)'; mt.style.color = '#999';
    mf.textContent = 'Eₙ₊₁ = Eₙ² + ' + sign + beta.toFixed(3) + '·Eₙ₋₁';
    mp.textContent = beta > 0 ? 'partial memory' : 'partial inverse memory';
  }
  drawFractal();
}

slider.addEventListener('input', upd);

// ═══════════════════════════════════════
// INIT
// ═══════════════════════════════════════
function init() {
  szFractal(); ivFractal();
  szCone();
  upd();
  drawCone3D();
}

window.addEventListener('resize', function () { szFractal(); ivFractal(); szCone(); upd(); });
init();
</script>
</body>
</html>
tweet_url

    
SHA-256