this repo has no description
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

v2 (solid/dotted/dashed scheme)

+49 -39
+49 -39
tline_viz.html
··· 649 649 const xOfZ = (z) => xPlot0 + z * plotW; 650 650 651 651 const launched = [...dyn.launchedWaves].sort((a, b) => a.n - b.n); 652 - const shownWaves = launched; 652 + const shownWaves = launched.slice(0, 6); 653 653 654 654 function totalSegmentsForWaves(waves) { 655 655 const breakpoints = [0, 1]; ··· 684 684 ]; 685 685 } 686 686 687 - const panels = [{ 688 - label: "Sum (all waves)", 689 - color: theme.ok, 690 - segments: totalSegmentsForWaves(launched), 691 - markers: dyn.activeWaves.map(wf => wf.front) 692 - }]; 693 - for (const wf of shownWaves) { 694 - panels.push({ 695 - label: `V${wf.n} ${wf.dir > 0 ? "incident" : "reflected"}`, 696 - color: wf.dir > 0 ? theme.accent : theme.accent2, 697 - segments: segmentsForWave(wf), 698 - markers: (wf.u < 1) ? [wf.front] : [] 699 - }); 700 - } 701 - 702 - const nPanels = panels.length; 687 + const sumSegments = totalSegmentsForWaves(launched); 688 + const nPanels = 2; 703 689 const panelH = PLOT_PANEL_H; 704 690 705 691 // Fixed vertical scale for all panels/time for the current parameter set. 706 692 const maxAbsWave = Math.max(1e-6, ...shownWaves.map((wf) => Math.abs(wf.A))); 707 - const maxAbsSum = Math.max(1e-6, panels[0].segments.reduce((m, seg) => Math.max(m, Math.abs(seg.V)), 0)); 693 + const maxAbsSum = Math.max(1e-6, sumSegments.reduce((m, seg) => Math.max(m, Math.abs(seg.V)), 0)); 708 694 const vScale = Math.max(maxAbsWave, maxAbsSum); 709 695 const vLo = -1.15 * vScale; 710 696 const vHi = 1.15 * vScale; ··· 713 699 ctx.font = "12px ui-sans-serif, system-ui"; 714 700 ctx.fillText("Voltage along the T-line", 12, 14); 715 701 716 - for (let p = 0; p < nPanels; p++) { 717 - const top = padT + p * (panelH + panelGap); 718 - const bottom = top + panelH; 702 + function drawPanelFrame(top, bottom, yOfV, labelText) { 719 703 const midY = (top + bottom) / 2; 720 - 721 - const yOfV = (V) => top + 4 + (vHi - V) / (vHi - vLo) * (panelH - 8); 722 - 723 - // Panel frame and axes 724 704 ctx.strokeStyle = theme.grid; 725 705 ctx.lineWidth = 1; 726 706 line(ctx, xPlot0, top, xPlot1, top); ··· 732 712 ctx.lineWidth = 1.2; 733 713 line(ctx, xPlot0, yOfV(0), xPlot1, yOfV(0)); 734 714 735 - drawPiecewise(ctx, xOfZ, yOfV, panels[p].segments, panels[p].color, p === 0 ? 2.4 : 2.0); 736 - 737 - // Wavefront markers 738 - if (panels[p].markers.length) { 739 - ctx.strokeStyle = theme.warn; 740 - ctx.lineWidth = 1.2; 741 - ctx.setLineDash([4, 5]); 742 - for (const zf of panels[p].markers) line(ctx, xOfZ(zf), top, xOfZ(zf), bottom); 743 - ctx.setLineDash([]); 744 - } 745 - 746 - // Labels 747 715 ctx.fillStyle = theme.muted; 748 716 ctx.font = "12px ui-sans-serif, system-ui"; 749 - ctx.fillText(panels[p].label, xPlot0 + 8, top + 14); 717 + ctx.fillText(labelText, xPlot0 + 8, top + 14); 750 718 ctx.fillText("0", xPlot0 - 14, yOfV(0) + 4); 751 719 ctx.fillText("z", xPlot1 + 6, midY + 4); 752 720 } 753 721 722 + function drawMarkers(top, bottom, fronts) { 723 + if (!fronts.length) return; 724 + ctx.strokeStyle = theme.warn; 725 + ctx.lineWidth = 1.2; 726 + ctx.setLineDash([4, 5]); 727 + for (const zf of fronts) line(ctx, xOfZ(zf), top, xOfZ(zf), bottom); 728 + ctx.setLineDash([]); 729 + } 730 + 731 + // Panel 1: sum only. 732 + const top0 = padT; 733 + const bot0 = top0 + panelH; 734 + const y0 = (V) => top0 + 4 + (vHi - V) / (vHi - vLo) * (panelH - 8); 735 + drawPanelFrame(top0, bot0, y0, "Sum (all waves)"); 736 + drawPiecewise(ctx, xOfZ, y0, sumSegments, theme.ok, 2.4); 737 + drawMarkers(top0, bot0, dyn.activeWaves.map((wf) => wf.front)); 738 + 739 + // Panel 2: all component waves overlaid with style sequence. 740 + const top1 = padT + panelH + panelGap; 741 + const bot1 = top1 + panelH; 742 + const y1 = (V) => top1 + 4 + (vHi - V) / (vHi - vLo) * (panelH - 8); 743 + const truncated = launched.length > shownWaves.length; 744 + drawPanelFrame(top1, bot1, y1, truncated ? "Components (V1..V6 shown)" : "Components (all waves)"); 745 + 746 + const waveStyles = [ 747 + { color: theme.accent, dash: [] }, // solid blue 748 + { color: theme.accent2, dash: [] }, // solid pink 749 + { color: theme.accent, dash: [9, 6] }, // dashed blue 750 + { color: theme.accent2, dash: [9, 6] }, // dashed pink 751 + { color: theme.accent, dash: [2, 5] }, // dotted blue 752 + { color: theme.accent2, dash: [2, 5] }, // dotted pink 753 + ]; 754 + 755 + for (let i = 0; i < shownWaves.length; i++) { 756 + const wf = shownWaves[i]; 757 + const style = waveStyles[i]; 758 + ctx.setLineDash(style.dash); 759 + drawPiecewise(ctx, xOfZ, y1, segmentsForWave(wf), style.color, 2.0); 760 + ctx.setLineDash([]); 761 + } 762 + drawMarkers(top1, bot1, shownWaves.filter((wf) => wf.u < 1).map((wf) => wf.front)); 763 + 754 764 // Shared z-axis endpoint labels 755 765 ctx.fillStyle = theme.muted; 756 766 ctx.font = "12px ui-monospace, SFMono-Regular, Menlo, Consolas, monospace"; ··· 818 828 drawCircuit(c.ctx, c.w, c.h, tNorm, dyn); 819 829 820 830 // Plot 821 - ensurePlotCanvasHeight(1 + dyn.launchedWaves.length); 831 + ensurePlotCanvasHeight(2); 822 832 const p = resizeCanvasToCSS(el.plot); 823 833 drawPlot(p.ctx, p.w, p.h, tNorm, dyn); 824 834 if (!hasStarted) {