独立渲染引擎就绪引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>微波光子学混频器 · 光域相干混频下变频原理</title>
<link href="https://fonts.googleapis.com/css2?family=Chakra+Petch:wght@400;600;700&family=Source+Code+Pro:wght@300;400;600&display=swap" rel="stylesheet">
<style>
*{margin:0;padding:0;box-sizing:border-box}
html,body{width:100%;height:100%;overflow:hidden;background:#050910}
body{display:flex;flex-direction:column;align-items:center;justify-content:center;font-family:'Source Code Pro',monospace;color:#b8cce0}
h1{font-family:'Chakra Petch',sans-serif;font-size:clamp(.9rem,1.8vw,1.35rem);font-weight:700;letter-spacing:3px;color:#d0e8ff;padding:10px 0 4px;text-shadow:0 0 24px rgba(0,160,255,.25)}
#wrap{flex:1;display:flex;align-items:center;justify-content:center;width:100%;padding:0 8px;min-height:0}
canvas{border-radius:10px}
#ctrl{display:flex;align-items:center;gap:clamp(12px,3vw,36px);padding:6px 0 10px;font-size:clamp(10px,1.2vw,12px);flex-wrap:wrap;justify-content:center}
#ctrl label{display:flex;align-items:center;gap:8px;white-space:nowrap}
input[type=range]{-webkit-appearance:none;width:clamp(110px,18vw,200px);height:3px;border-radius:2px;outline:none;background:linear-gradient(90deg,#ff6d00,#00e5ff)}
input[type=range]::-webkit-slider-thumb{-webkit-appearance:none;width:14px;height:14px;background:#fff;border-radius:50%;cursor:pointer;box-shadow:0 0 8px rgba(0,180,255,.45)}
.v{font-weight:600;min-width:52px}
.lo-c{color:#ff9100}.sig-c{color:#00e5ff}.if-c{color:#00e676}
</style>
</head>
<body>
<h1>微波光子学混频器 · 光域相干混频下变频原理</h1>
<div id="wrap"><canvas id="c"></canvas></div>
<div id="ctrl">
<label>振动频率 f<sub>sig</sub>:<input type="range" id="sigS" min="50" max="200" value="85" step="5"><span class="v sig-c" id="sigV">85 kHz</span></label>
<label>本振偏移 Δf = f<sub>IF</sub>:<input type="range" id="ifS" min="20" max="480" value="150" step="10"><span class="v if-c" id="ifV">150 Hz</span></label>
</div>
<script>
(function(){
/* ========== 画布与缩放 ========== */
const cv=document.getElementById('c'),cx=cv.getContext('2d');
const W=1440,H=760;
let dpr,sc;
function resize(){
dpr=devicePixelRatio||1;
const mw=innerWidth-16,mh=innerHeight-90;
sc=Math.min(mw/W,mh/H);
cv.style.width=W*sc+'px';cv.style.height=H*sc+'px';
cv.width=W*sc*dpr;cv.height=H*sc*dpr;
}
resize();addEventListener('resize',resize);
/* ========== 状态与控件 ========== */
let t=0,sigF=85,ifHz=150;
const sigS=document.getElementById('sigS'),ifS=document.getElementById('ifS');
const sigV=document.getElementById('sigV'),ifV=document.getElementById('ifV');
sigS.oninput=()=>{sigF=+sigS.value;sigV.textContent=sigF+' kHz';};
ifS.oninput=()=>{ifHz=+ifS.value;ifV.textContent=ifHz+' Hz';};
/* ========== 颜色 ========== */
const C={
bg:'#070b18',grid:'rgba(22,44,80,0.10)',
cyan:'#00e5ff',cyanD:'rgba(0,229,255,0.25)',
orange:'#ff9100',orangeD:'rgba(255,145,0,0.25)',
green:'#00e676',greenD:'rgba(0,230,118,0.25)',
purple:'#b388ff',purpleD:'rgba(140,100,255,0.18)',
white:'#d8e8f8',dim:'#4a6a8a',dimmer:'#28384e',
boxBg:'rgba(8,16,36,0.88)',boxBd:'rgba(50,100,180,0.22)',
mixBd:'rgba(150,110,255,0.50)',mixGlow:'rgba(120,70,255,0.10)',
};
/* ========== 粒子系统 ========== */
const pts=[];
function spawnP(x,y,c){
if(pts.length>100)return;
const a=Math.random()*Math.PI*2,sp=.4+Math.random()*1.4;
pts.push({x,y,vx:Math.cos(a)*sp,vy:Math.sin(a)*sp,life:1,c:c||C.purple,sz:1.2+Math.random()*2});
}
/* ========== 绘图工具 ========== */
function rrect(x,y,w,h,r){
cx.beginPath();cx.moveTo(x+r,y);cx.lineTo(x+w-r,y);cx.arcTo(x+w,y,x+w,y+r,r);
cx.lineTo(x+w,y+h-r);cx.arcTo(x+w,y+h,x+w-r,y+h,r);cx.lineTo(x+r,y+h);
cx.arcTo(x,y+h,x,y+h-r,r);cx.lineTo(x,y+r);cx.arcTo(x,y,x+r,y,r);cx.closePath();
}
// 发光正弦波
function glowWave(x1,y0,x2,cyc,amp,ph,col,lw,gl){
const len=x2-x1;if(len<=0)return;
cx.save();cx.shadowColor=col;cx.shadowBlur=gl||8;cx.strokeStyle=col;cx.lineWidth=lw||2;
cx.beginPath();
for(let i=0;i<=len;i+=1.5){
const px=x1+i,py=y0+amp*Math.sin(2*Math.PI*cyc*(i/len)+ph);
i===0?cx.moveTo(px,py):cx.lineTo(px,py);
}
cx.stroke();cx.restore();
}
// 组件盒
function compBox(x,y,w,h,lbl,sub,bdC,fillC){
cx.save();rrect(x,y,w,h,8);cx.fillStyle=fillC||C.boxBg;cx.fill();
cx.strokeStyle=bdC||C.boxBd;cx.lineWidth=1.5;cx.stroke();
cx.fillStyle=C.white;cx.font='600 12px "Source Code Pro",monospace';cx.textAlign='center';
if(sub){cx.fillText(lbl,x+w/2,y+22);cx.fillStyle=C.dim;cx.font='300 10px "Source Code Pro",monospace';cx.fillText(sub,x+w/2,y+37);}
else cx.fillText(lbl,x+w/2,y+h/2+5);
cx.restore();
}
// 箭头
function arrow(x1,y1,x2,y2,col,lw){
cx.save();cx.strokeStyle=col||C.dim;cx.lineWidth=lw||1.2;
cx.beginPath();cx.moveTo(x1,y1);cx.lineTo(x2,y2);cx.stroke();
const a=Math.atan2(y2-y1,x2-x1),hl=8;
cx.fillStyle=col||C.dim;cx.beginPath();cx.moveTo(x2,y2);
cx.lineTo(x2-hl*Math.cos(a-.38),y2-hl*Math.sin(a-.38));
cx.lineTo(x2-hl*Math.cos(a+.38),y2-hl*Math.sin(a+.38));cx.closePath();cx.fill();cx.restore();
}
// 流动光点
function flowDot(x1,y1,x2,y2,prog,col){
const px=x1+(x2-x1)*prog,py=y1+(y2-y1)*prog;
cx.save();cx.shadowColor=col;cx.shadowBlur=12;cx.fillStyle=col;
cx.beginPath();cx.arc(px,py,4,0,Math.PI*2);cx.fill();cx.restore();
}
// 标签
function label(txt,x,y,col,font){
cx.save();cx.fillStyle=col||C.dim;cx.font=font||'300 10px "Source Code Pro",monospace';
cx.textAlign='center';cx.fillText(txt,x,y);cx.restore();
}
/* ========== 主绘制 ========== */
function draw(){
const s=sc*dpr;cx.setTransform(s,0,0,s,0,0);
// 背景
cx.fillStyle=C.bg;cx.fillRect(0,0,W,H);
// 网格
cx.strokeStyle=C.grid;cx.lineWidth=.5;
for(let x=0;x<W;x+=40){cx.beginPath();cx.moveTo(x,0);cx.lineTo(x,H);cx.stroke();}
for(let y=0;y<H;y+=40){cx.beginPath();cx.moveTo(0,y);cx.lineTo(W,y);cx.stroke();}
// 视觉频率映射(夸张化以便观察)
const sigCyc=18; // 信号视觉周期数
const ifCyc=1+(ifHz/480)*4; // IF 视觉周期数:1~5
const loCyc=sigCyc-ifCyc; // LO 视觉周期数(略低于信号)
const loF_kHz=sigF-ifHz/1000; // LO 实际频率
const my=235; // 主信号流 Y 中心
/* ── 1. 光纤感知区 ── */
compBox(30,my-72,185,144,'光纤感知区','瑞利散射信号',C.boxBd);
// 光纤线
cx.save();cx.strokeStyle=C.cyan;cx.lineWidth=2.5;cx.shadowColor=C.cyan;cx.shadowBlur=6;
cx.beginPath();cx.moveTo(52,my);cx.lineTo(192,my);cx.stroke();cx.restore();
// 振动波纹
for(let i=0;i<5;i++){
const vx=62+i*28,vy=my-30;
cx.save();cx.strokeStyle='rgba(0,229,255,0.35)';cx.lineWidth=1;
cx.beginPath();for(let j=0;j<22;j++){
const px=vx-11+j,py=vy+7*Math.sin(j*.75+t*6+i*1.2);
j===0?cx.moveTo(px,py):cx.lineTo(px,py);}cx.stroke();cx.restore();
}
// 脉冲光点沿光纤行进
const pulseX=52+((t*40)%140);
cx.save();cx.shadowColor=C.cyan;cx.shadowBlur=14;cx.fillStyle=C.cyan;
cx.beginPath();cx.arc(pulseX,my,3.5,0,Math.PI*2);cx.fill();cx.restore();
label('高频振动调制',122,my+55,C.dim);
/* ── 2. 高频信号波 ── */
arrow(215,my,250,my,C.cyan);
cx.save();cx.fillStyle=C.cyan;cx.font='600 11px "Source Code Pro",monospace';cx.textAlign='center';
cx.fillText('高频信号边带',350,my-48);
cx.font='300 10px "Source Code Pro",monospace';cx.fillStyle=C.dim;
cx.fillText('f sig = '+sigF+'.0 kHz',350,my-34);cx.restore();
glowWave(255,my,445,sigCyc,30,-t*7,C.cyan,2.5,14);
/* ── 3. 微波光子学混频器(核心) ── */
const mx=468,mTop=my-100,mw=280,mh=200;
// 辉光背景
cx.save();const grd=cx.createRadialGradient(mx+mw/2,my,20,mx+mw/2,my,mw*.7);
grd.addColorStop(0,'rgba(120,70,255,0.10)');grd.addColorStop(1,'rgba(120,70,255,0)');
cx.fillStyle=grd;cx.fillRect(mx-60,mTop-60,mw+120,mh+120);cx.restore();
// 盒体(呼吸边框)
const pulse=.5+.5*Math.sin(t*2.2);
cx.save();rrect(mx,mTop,mw,mh,10);cx.fillStyle=C.boxBg;cx.fill();
cx.strokeStyle=C.mixBd;cx.lineWidth=2+pulse;cx.shadowColor=C.purple;cx.shadowBlur=18+pulse*12;cx.stroke();cx.restore();
// 标题
cx.save();cx.fillStyle=C.purple;cx.font='700 14px "Chakra Petch",sans-serif';cx.textAlign='center';
cx.fillText('微波光子学混频器',mx+mw/2,mTop+24);cx.restore();
cx.save();cx.fillStyle=C.dim;cx.font='300 10px "Source Code Pro",monospace';cx.textAlign='center';
cx.fillText('光域相干拍频 · 下变频',mx+mw/2,mTop+40);cx.restore();
// 拍频可视化
const bx1=mx+22,bx2=mx+mw-22,bw=bx2-bx1,by=my+8;
// 载波+包络(合成拍频信号)
cx.save();cx.strokeStyle='rgba(180,160,255,0.35)';cx.lineWidth=1;cx.beginPath();
for(let i=0;i<=bw;i+=1){
const fr=i/bw;
const carrier=Math.sin(2*Math.PI*12*fr+t*7);
const env=Math.cos(2*Math.PI*ifCyc/2*fr-t*1.2);
const py=by+22*env*carrier;
i===0?cx.moveTo(bx1+i,py):cx.lineTo(bx1+i,py);
}cx.stroke();cx.restore();
// 上包络(绿色高亮)
cx.save();cx.shadowColor=C.green;cx.shadowBlur=10;cx.strokeStyle=C.green;cx.lineWidth=2.2;
cx.setLineDash([7,4]);cx.beginPath();
for(let i=0;i<=bw;i++){const fr=i/bw;const e=Math.abs(Math.cos(2*Math.PI*ifCyc/2*fr-t*1.2));
const py=by-22*e;i===0?cx.moveTo(bx1+i,py):cx.lineTo(bx1+i,py);}cx.stroke();
// 下包络
cx.beginPath();for(let i=0;i<=bw;i++){const fr=i/bw;const e=Math.abs(Math.cos(2*Math.PI*ifCyc/2*fr-t*1.2));
const py=by+22*e;i===0?cx.moveTo(bx1+i,py):cx.lineTo(bx1+i,py);}cx.stroke();cx.restore();
// IF 标签
cx.save();cx.fillStyle=C.green;cx.font='600 10px "Source Code Pro",monospace';cx.textAlign='center';
cx.fillText('f IF = '+ifHz+' Hz',mx+mw/2,mTop+mh-14);cx.restore();
// IFR 注释——巧妙利用现有资源
cx.save();cx.fillStyle='rgba(180,160,255,0.55)';cx.font='300 9px "Source Code Pro",monospace';cx.textAlign='center';
cx.fillText('仅增加本振调制边带,复用相干接收架构',mx+mw/2,mTop+mh+16);cx.restore();
// 粒子
if(Math.random()<.35)spawnP(mx+mw/2,my,C.purple);
if(Math.random()<.2)spawnP(mx+mw/2,my,C.green);
/* ── 4. 可调谐本振源 ── */
const lx=510,ly=390,lw=190,lh=65;
compBox(lx,ly,lw,lh,'可调谐本振源','f LO = '+loF_kHz.toFixed(2)+' kHz',C.orange);
glowWave(lx+14,ly+lh/2+6,lx+lw-14,7,7,-t*5+1,C.orange,1.5,6);
arrow(lx+lw/2,ly,mx+mw/2,mTop+mh,C.orange);
/* ── 5. 中频信号波 ── */
arrow(mx+mw,my,755,my,C.green);
cx.save();cx.fillStyle=C.green;cx.font='600 11px "Source Code Pro",monospace';cx.textAlign='center';
cx.fillText('中频信号 (IF)',860,my-48);
cx.font='300 10px "Source Code Pro",monospace';cx.fillStyle=C.dim;
cx.fillText('f IF = '+ifHz+' Hz ≪ f Nyquist',860,my-34);cx.restore();
glowWave(760,my,960,Math.max(ifCyc,.6),30,-t*2,C.green,2.5,14);
/* ── 6. 低速 ADC ── */
compBox(980,my-65,135,130,'低速 ADC','采样率 ~1 kHz',C.boxBd);
// 采样点可视化
const adcX=992,adcW=112;
const nSamp=Math.max(Math.round(ifCyc*2.5),6);
cx.save();
for(let i=0;i<=nSamp;i++){
const fr=i/nSamp,px=adcX+fr*adcW;
const py=my+28*Math.sin(2*Math.PI*Math.max(ifCyc,.6)*fr-t*2);
cx.shadowColor=C.green;cx.shadowBlur=6;cx.fillStyle=C.green;
cx.beginPath();cx.arc(px,py,3.2,0,Math.PI*2);cx.fill();
cx.strokeStyle='rgba(0,230,118,0.25)';cx.lineWidth=.8;
cx.beginPath();cx.moveTo(px,py);cx.lineTo(px,my+44);cx.stroke();
}cx.restore();
label('无失真捕获',1047,my+55,C.green,'400 10px "Source Code Pro",monospace');
/* ── 7. 数字信号处理还原 ── */
arrow(1115,my,1145,my,C.dim);
compBox(1150,my-65,170,130,'数字信号处理','还原高频包络',C.boxBd);
// 还原的高频包络
cx.save();cx.strokeStyle='rgba(0,229,255,0.35)';cx.lineWidth=1;cx.beginPath();
for(let i=0;i<=145;i++){const fr=i/145;const px=1165+i;
const env=Math.cos(2*Math.PI*ifCyc/2*fr-t*1.2);
const carrier=Math.sin(2*Math.PI*12*fr+t*7);
const py=my+14*env*carrier;
i===0?cx.moveTo(px,py):cx.lineTo(px,py);}cx.stroke();cx.restore();
// 包络线
cx.save();cx.strokeStyle=C.cyan;cx.lineWidth=1.8;cx.shadowColor=C.cyan;cx.shadowBlur=6;
cx.beginPath();for(let i=0;i<=145;i++){const fr=i/145;const px=1165+i;
const e=Math.abs(Math.cos(2*Math.PI*ifCyc/2*fr-t*1.2));
const py=my-14*e;i===0?cx.moveTo(px,py):cx.lineTo(px,py);}cx.stroke();
cx.beginPath();for(let i=0;i<=145;i++){const fr=i/145;const px=1165+i;
const e=Math.abs(Math.cos(2*Math.PI*ifCyc/2*fr-t*1.2));
const py=my+14*e;i===0?cx.moveTo(px,py):cx.lineTo(px,py);}cx.stroke();cx.restore();
label('高频信息还原',1235,my+55,C.cyan,'400 10px "Source Code Pro",monospace');
/* ── 8. 流动光点 ── */
const dp=(t*.12)%1;
flowDot(255,my,445,my,dp,C.cyan);
flowDot(760,my,960,my,dp,C.green);
flowDot(530,390,608,my+100,(t*.15)%1,C.orange);
/* ── 9. 粒子渲染 ── */
for(let i=pts.length-1;i>=0;i--){
const p=pts[i];p.x+=p.vx;p.y+=p.vy;p.life-=.014;
if(p.life<=0){pts.splice(i,1);continue;}
cx.save();cx.globalAlpha=p.life*.55;cx.shadowColor=p.c;cx.shadowBlur=8;
cx.fillStyle=p.c;cx.beginPath();cx.arc(p.x,p.y,p.sz*p.life,0,Math.PI*2);cx.fill();cx.restore();
}
/* ══════ 频谱面板 ══════ */
drawSpectrum(sigF,loF_kHz,ifHz,ifCyc);
}
/* ========== 频谱面板 ========== */
function drawSpectrum(sigF,loF,ifHz,ifCyc){
const sx=55,sy=510,sw=W-110,sh=220;
cx.save();rrect(sx,sy,sw,sh,10);cx.fillStyle='rgba(6,10,22,0.92)';cx.fill();
cx.strokeStyle=C.boxBd;cx.lineWidth=1;cx.stroke();cx.restore();
// 标题
cx.save();cx.fillStyle=C.dim;cx.font='600 11px "Source Code Pro",monospace';cx.textAlign='left';
cx.fillText('频域示意:光域混频下变频',sx+18,sy+22);cx.restore();
const ax=sx+80,ay=sy+sh-38,aw=sw-140,ah=sh-75;
// 坐标轴
cx.save();cx.strokeStyle=C.dimmer;cx.lineWidth=1;
cx.beginPath();cx.moveTo(ax,ay);cx.lineTo(ax+aw,ay);cx.stroke();
cx.beginPath();cx.moveTo(ax,ay);cx.lineTo(ax,ay-ah);cx.stroke();cx.restore();
// X 轴刻度
cx.save();cx.fillStyle=C.dimmer;cx.font='300 9px "Source Code Pro",monospace';cx.textAlign='center';
cx.fillText('0',ax,ay+14);cx.fillText('频率 (kHz)',ax+aw/2,ay+14);
cx.fillText(sigF>120?'200':'100',ax+aw,ay+14);cx.restore();
const maxF=sigF>120?200:100;
// 奈奎斯特线(0.5 kHz,但在 kHz 轴上几乎在原点——放大表示)
const nyqVisX=ax+aw*(0.5/maxF)*12; // 放大 12 倍以便可见
cx.save();cx.strokeStyle='rgba(255,80,80,0.45)';cx.lineWidth=1.2;cx.setLineDash([5,4]);
cx.beginPath();cx.moveTo(nyqVisX,ay-ah);cx.lineTo(nyqVisX,ay);cx.stroke();cx.restore();
cx.save();cx.fillStyle='rgba(255,80,80,0.6)';cx.font='300 9px "Source Code Pro",monospace';cx.textAlign='center';
cx.fillText('f Nyquist = 500 Hz',nyqVisX,ay-ah-6);cx.restore();
// 高斯峰绘制函数
function peak(centerX,h,col,lbl,lblY){
const sigma=aw*0.022;
cx.save();cx.shadowColor=col;cx.shadowBlur=8;cx.strokeStyle=col;cx.lineWidth=2;
cx.beginPath();
for(let i=0;i<=aw;i++){
const px=ax+i;const d=px-centerX;
const py=ay-h*Math.exp(-d*d/(2*sigma*sigma));
i===0?cx.moveTo(px,py):cx.lineTo(px,py);
}cx.stroke();
// 填充
cx.lineTo(ax+aw,ay);cx.lineTo(ax,ay);cx.closePath();cx.globalAlpha=.12;cx.fillStyle=col;cx.fill();cx.restore();
// 标签
cx.save();cx.fillStyle=col;cx.font='600 10px "Source Code Pro",monospace';cx.textAlign='center';
cx.fillText(lbl,centerX,lblY);cx.restore();
}
// 信号峰
const sigX=ax+aw*(sigF/maxF);
peak(sigX,ah*.7,C.cyan,'f sig = '+sigF+' kHz',ay-ah*.7-10);
// LO 峰
const loX=ax+aw*(loF/maxF);
peak(loX,ah*.55,C.orange,'f LO = '+loF.toFixed(2)+' kHz',ay-ah*.55-10);
// IF 峰(在低频端,放大位置以便可见)
const ifVisX=ax+aw*(ifHz/500)*0.35+ax*0.08;
peak(ifVisX,ah*.45,C.green,'f IF = '+ifHz+' Hz',ay-ah*.45-10);
// 下变频箭头弧线:从信号峰到 IF 峰
const arcY=ay-ah*.35;
cx.save();cx.strokeStyle=C.purple;cx.lineWidth=1.8;cx.shadowColor=C.purple;cx.shadowBlur=6;
cx.beginPath();cx.moveTo(sigX,arcY);
cx.quadraticCurveTo((sigX+ifVisX)/2,arcY-50,ifVisX,arcY);cx.stroke();
// 箭头头部
const angle=Math.atan2(arcY-(arcY-50)*.5,ifVisX-(sigX+ifVisX)/2);
cx.fillStyle=C.purple;cx.beginPath();cx.moveTo(ifVisX,arcY);
cx.lineTo(ifVisX-9*Math.cos(angle-.4),arcY-9*Math.sin(angle-.4));
cx.lineTo(ifVisX-9*Math.cos(angle+.4),arcY-9*Math.sin(angle+.4));cx.closePath();cx.fill();cx.restore();
label('−f LO',ifVisX+(sigX-ifVisX)*.5,arcY-42,C.purple,'600 10px "Source Code Pro",monospace');
// IF 峰成功标记
cx.save();cx.fillStyle=C.green;cx.font='700 10px "Source Code Pro",monospace';cx.textAlign='center';
cx.fillText('✓ 可被低速 ADC 无失真捕获',ifVisX+60,ay+28);cx.restore();
}
/* ========== 动画循环 ========== */
function animate(){
t+=.025;draw();requestAnimationFrame(animate);
}
animate();
})();
</script>
</body>
</html>
实现说明:
IFR 理想态聚焦:动画直接展示微波光子学混频器工作时的理想状态——高频信号经光域拍频下变频后被低速 ADC 完美捕获,无需对比"有问题"的旧状态。
核心创新点高亮:混频器是视觉中心,采用紫色呼吸边框 + 径向辉光 + 粒子喷射三重强调;内部实时展示拍频现象——高频载波叠加低频包络(绿色虚线),直观呈现下变频物理本质。
资源利用暗示:混频器下方标注"仅增加本振调制边带,复用相干接收架构",突出 IFR 中"以极少新增资源化解矛盾"的思想。
交互控制:两个滑块——振动频率 f_sig(50–200 kHz)和本振偏移 Δf = f_IF(20–480 Hz)——可实时调节,观察 IF 频率变化如何影响拍频包络、中频波形和频谱峰位。
频谱面板:底部展示信号峰、LO 峰、IF 峰三者关系,紫色弧线箭头可视化"减去 f_LO"的下变频过程,奈奎斯特线标示 ADC 采样极限,IF 峰安全落在可捕获区间。
自动播放:页面加载即启动
requestAnimationFrame循环,信号波、脉冲光点、粒子、呼吸光效全部自动运行,刷新/重开即播。
积分规则:第一轮对话扣减8分,后续每轮扣6分
等待动画代码生成...
