独立渲染引擎就绪引擎就绪
<!DOCTYPE html>
<html lang="zh-CN">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>双频脉冲频分复用 — IFR原理动画</title>
<link href="https://fonts.googleapis.com/css2?family=Orbitron:wght@400;700;900&family=Share+Tech+Mono&display=swap" rel="stylesheet">
<style>
*{margin:0;padding:0;box-sizing:border-box}
:root{
--bg:#060a14;--fg:#b0c8e0;--muted:#3a5878;--accent:#00ff88;
--l1:#00ccff;--l2:#ff8800;--card:#0a1020;--border:#152040;
--danger:#ff3060;
}
body{
background:var(--bg);color:var(--fg);
font-family:'Share Tech Mono',monospace;
min-height:100vh;
background-image:
radial-gradient(ellipse at 15% 30%,rgba(0,204,255,.035) 0%,transparent 55%),
radial-gradient(ellipse at 85% 70%,rgba(255,136,0,.03) 0%,transparent 55%),
linear-gradient(rgba(0,180,255,.018) 1px,transparent 1px),
linear-gradient(90deg,rgba(0,180,255,.018) 1px,transparent 1px);
background-size:100% 100%,100% 100%,36px 36px,36px 36px;
}
.wrap{max-width:1240px;margin:0 auto;padding:14px 18px 24px}
header{text-align:center;margin-bottom:12px}
h1{
font-family:'Orbitron',sans-serif;font-weight:900;
font-size:clamp(1.1rem,2.6vw,1.65rem);letter-spacing:2px;
background:linear-gradient(90deg,var(--l1),var(--accent),var(--l2));
-webkit-background-clip:text;-webkit-text-fill-color:transparent;
background-clip:text;margin-bottom:5px;
}
.sub{color:var(--muted);font-size:.78rem;letter-spacing:.5px}
.fiber-box{
background:var(--card);border:1px solid var(--border);border-radius:12px;
padding:6px;margin-bottom:12px;position:relative;overflow:hidden;
}
.fiber-box::after{
content:'';position:absolute;inset:0;pointer-events:none;
background:repeating-linear-gradient(0deg,transparent,transparent 2px,rgba(0,204,255,.012) 2px,rgba(0,204,255,.012) 4px);
}
#fiberSvg{width:100%;height:auto;display:block;position:relative;z-index:1}
.waves{display:grid;grid-template-columns:1fr 1fr 1.35fr;gap:10px;margin-bottom:12px}
.wp{
background:var(--card);border:1px solid var(--border);border-radius:10px;
padding:10px 10px 6px;position:relative;
}
.wp.ifr{
border-color:rgba(0,255,136,.3);
box-shadow:0 0 24px rgba(0,255,136,.07),inset 0 0 18px rgba(0,255,136,.025);
}
.wp h3{
font-family:'Orbitron',sans-serif;font-size:.62rem;font-weight:700;
letter-spacing:.8px;margin-bottom:5px;color:var(--muted);
}
.wp.ifr h3{color:var(--accent)}
.wp canvas{width:100%;height:136px;display:block;border-radius:4px}
.badge{
position:absolute;top:7px;right:8px;
font-family:'Orbitron',sans-serif;font-size:.5rem;font-weight:700;
color:var(--accent);background:rgba(0,255,136,.1);
border:1px solid rgba(0,255,136,.3);border-radius:4px;padding:2px 6px;
animation:pulse 2s ease-in-out infinite;
}
@keyframes pulse{0%,100%{opacity:.65}50%{opacity:1}}
.ctrl{
background:var(--card);border:1px solid var(--border);border-radius:10px;
padding:12px 18px;display:flex;align-items:center;gap:14px;
margin-bottom:10px;flex-wrap:wrap;
}
.ctrl label{font-size:.78rem;color:var(--muted);white-space:nowrap}
.ctrl input[type=range]{
flex:1;min-width:180px;-webkit-appearance:none;appearance:none;
height:5px;background:var(--border);border-radius:3px;outline:none;
}
.ctrl input[type=range]::-webkit-slider-thumb{
-webkit-appearance:none;appearance:none;width:16px;height:16px;
background:var(--accent);border-radius:50%;cursor:pointer;
box-shadow:0 0 8px rgba(0,255,136,.4);
}
.fv{
font-family:'Orbitron',sans-serif;font-weight:700;font-size:.95rem;
color:var(--accent);min-width:68px;text-align:right;
}
.nw{
font-size:.7rem;color:var(--danger);margin-left:6px;
opacity:0;transition:opacity .3s;
}
.nw.on{opacity:1}
.params{
display:flex;justify-content:center;gap:20px;flex-wrap:wrap;
font-size:.72rem;color:var(--muted);
}
.params .v{color:var(--fg);font-weight:700}
.c1{color:var(--l1)}.c2{color:var(--l2)}.ca{color:var(--accent)}
@media(max-width:780px){.waves{grid-template-columns:1fr}.wrap{padding:8px}}
</style>
</head>
<body>
<div class="wrap">
<header>
<h1>双频脉冲频分复用 — 破解PRF矛盾</h1>
<p class="sub">利用波长维度折叠时间采样率 · 在无混叠前提下实现等效双倍PRF</p>
</header>
<div class="fiber-box">
<svg id="fiberSvg" viewBox="0 0 1200 330" xmlns="http://www.w3.org/2000/svg">
<defs>
<filter id="gC" x="-60%" y="-60%" width="220%" height="220%">
<feGaussianBlur stdDeviation="5" result="b"/><feComposite in="SourceGraphic" in2="b" operator="over"/>
</filter>
<filter id="gO" x="-60%" y="-60%" width="220%" height="220%">
<feGaussianBlur stdDeviation="5" result="b"/><feComposite in="SourceGraphic" in2="b" operator="over"/>
</filter>
<filter id="gG" x="-80%" y="-80%" width="260%" height="260%">
<feGaussianBlur stdDeviation="8" result="b"/><feComposite in="SourceGraphic" in2="b" operator="over"/>
</filter>
<linearGradient id="fG" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#142238"/><stop offset="50%" stop-color="#0b1525"/><stop offset="100%" stop-color="#142238"/>
</linearGradient>
<linearGradient id="srcG" x1="0" y1="0" x2="0" y2="1">
<stop offset="0%" stop-color="#0e1a2e"/><stop offset="100%" stop-color="#080e1c"/>
</linearGradient>
</defs>
<!-- Source / Receiver Unit -->
<rect x="16" y="55" width="140" height="220" rx="8" fill="url(#srcG)" stroke="#1a3050" stroke-width="1.5"/>
<text x="86" y="80" text-anchor="middle" fill="#4a7090" font-family="Orbitron,sans-serif" font-size="8.5" font-weight="700" letter-spacing="1">询问器单元</text>
<!-- Light source icon -->
<circle cx="86" cy="112" r="16" fill="none" stroke="#00ccff" stroke-width="1.2" opacity=".5"/>
<circle cx="86" cy="112" r="7" fill="#00ccff" opacity=".18"/>
<circle cx="86" cy="112" r="3" fill="#00ccff" opacity=".45"/>
<text x="86" y="142" text-anchor="middle" fill="#4a7090" font-size="7.5">脉冲光源</text>
<!-- Receiver -->
<rect x="46" y="158" width="80" height="22" rx="4" fill="none" stroke="#ff8800" stroke-width=".8" opacity=".4"/>
<text x="86" y="173" text-anchor="middle" fill="#4a7090" font-size="7">光电接收</text>
<!-- Demux prism -->
<polygon points="50,200 122,218 50,236" fill="none" stroke="#00ff88" stroke-width="1" opacity=".45"/>
<line x1="42" y1="212" x2="50" y2="212" stroke="#00ccff" stroke-width="1.5" opacity=".5"/>
<line x1="42" y1="226" x2="50" y2="226" stroke="#ff8800" stroke-width="1.5" opacity=".5"/>
<text x="86" y="252" text-anchor="middle" fill="#4a7090" font-size="7">波长解复用</text>
<!-- Output arrows -->
<line x1="30" y1="212" x2="18" y2="200" stroke="#00ccff" stroke-width="1" opacity=".3" marker-end="none"/>
<line x1="30" y1="226" x2="18" y2="238" stroke="#ff8800" stroke-width="1" opacity=".3"/>
<text x="12" y="198" fill="#00ccff" font-size="6" opacity=".5">λ₁</text>
<text x="12" y="246" fill="#ff8800" font-size="6" opacity=".5">λ₂</text>
<!-- Fiber cladding -->
<rect x="160" y="55" width="960" height="220" rx="10" fill="url(#fG)" stroke="#162540" stroke-width="1"/>
<!-- Lane labels -->
<text x="176" y="80" fill="#2a4a68" font-size="8.5" font-family="Share Tech Mono,monospace">→ 出射脉冲</text>
<text x="176" y="268" fill="#2a4a68" font-size="8.5" font-family="Share Tech Mono,monospace">← 后向散射回波</text>
<!-- Lane divider -->
<line x1="160" y1="165" x2="1120" y2="165" stroke="#162540" stroke-width="1" stroke-dasharray="6,5"/>
<!-- Core guides -->
<line x1="160" y1="118" x2="1120" y2="118" stroke="#12203a" stroke-width=".4" opacity=".6"/>
<line x1="160" y1="205" x2="1120" y2="205" stroke="#12203a" stroke-width=".4" opacity=".6"/>
<!-- Vibration zone -->
<rect id="vibZone" x="790" y="60" width="70" height="210" rx="5" fill="rgba(0,255,136,.04)" stroke="#00ff88" stroke-width="1" stroke-dasharray="4,3" opacity=".55"/>
<text x="825" y="52" text-anchor="middle" fill="#00ff88" font-size="8.5" font-family="Orbitron,sans-serif" font-weight="700" opacity=".75">振动传感区</text>
<!-- Vibration wave (animated) -->
<path id="vibW" d="" fill="none" stroke="#00ff88" stroke-width="1.6" opacity=".35"/>
<!-- Far end -->
<rect x="1120" y="65" width="28" height="200" rx="4" fill="#0b1525" stroke="#162540" stroke-width="1"/>
<text x="1134" y="170" text-anchor="middle" fill="#2a4a68" font-size="7.5" writing-mode="tb">远端</text>
<!-- Distance scale -->
<g fill="#22385a" font-size="7.5">
<text x="340" y="293">10 km</text><line x1="340" y1="278" x2="340" y2="285" stroke="#22385a" stroke-width=".5"/>
<text x="540" y="293">25 km</text><line x1="540" y1="278" x2="540" y2="285" stroke="#22385a" stroke-width=".5"/>
<text x="740" y="293">40 km</text><line x1="740" y1="278" x2="740" y2="285" stroke="#22385a" stroke-width=".5"/>
<text x="940" y="293">50 km</text><line x1="940" y1="278" x2="940" y2="285" stroke="#22385a" stroke-width=".5"/>
</g>
<!-- Insight annotation (appears later) -->
<g id="insight" opacity="0">
<rect x="310" y="300" width="500" height="26" rx="6" fill="rgba(0,255,136,.07)" stroke="rgba(0,255,136,.2)" stroke-width="1"/>
<text x="560" y="318" text-anchor="middle" fill="#00ff88" font-size="8.5" font-family="Orbitron,sans-serif" font-weight="700" letter-spacing=".5">
同波长间距大→无混叠 │ 异波长交错→双倍采样率
</text>
</g>
<!-- Dynamic pulse container -->
<g id="pG"></g>
<!-- Scatter flash container -->
<g id="flashG"></g>
</svg>
</div>
<div class="waves">
<div class="wp"><h3><span class="c1">●</span> λ₁ 通道 (1 kHz采样)</h3><canvas id="c1"></canvas></div>
<div class="wp"><h3><span class="c2">●</span> λ₂ 通道 (1 kHz采样)</h3><canvas id="c2"></canvas></div>
<div class="wp ifr"><h3><span class="ca">●</span> 交错重建 (等效2 kHz)</h3><div class="badge">IFR 理想解</div><canvas id="c3"></canvas></div>
</div>
<div class="ctrl">
<label>探测振动频率</label>
<input type="range" id="fSlider" min="100" max="2000" value="800" step="50">
<span class="fv" id="fVal">800 Hz</span>
<span class="nw" id="nWarn">⚠ 超过单通道奈奎斯特极限(500 Hz)</span>
</div>
<div class="params">
<span>双频间隔 <em class="v">0.8 nm</em></span>
<span>单频PRF <em class="v">1 kHz</em></span>
<span>等效PRF <em class="v ca">2 kHz</em></span>
<span>单通道奈奎斯特 <em class="v">500 Hz</em></span>
<span>等效奈奎斯特 <em class="v ca">1 kHz</em></span>
</div>
</div>
<script>
(function(){
'use strict';
/* ====== 配置常量 ====== */
const FL=168, FR=1110; // 光纤左右x边界
const OY=118, RY=205; // 出射/回波中心y
const VZX=825; // 振动区中心x
const PW=34, PH=14; // 脉冲宽高
const SPEED=3.2; // 脉冲移动速度 px/frame
const INTERVAL=55; // 每隔多少帧发一个脉冲
const NS='http://www.w3.org/2000/svg';
/* ====== 状态 ====== */
const S={frame:0,freq:800,pulses:[],nextPulse:25,nextWL:0,insightShown:false,wavePhase:0};
/* ====== DOM引用 ====== */
const svg=document.getElementById('fiberSvg');
const pG=document.getElementById('pG');
const flashG=document.getElementById('flashG');
const insightEl=document.getElementById('insight');
const vibW=document.getElementById('vibW');
const fSlider=document.getElementById('fSlider');
const fValEl=document.getElementById('fVal');
const nWarnEl=document.getElementById('nWarn');
/* ====== Canvas初始化 ====== */
function initCanvas(id){
const c=document.getElementById(id);
const dpr=Math.min(window.devicePixelRatio||1,2);
const r=c.getBoundingClientRect();
c.width=r.width*dpr;c.height=r.height*dpr;
const ctx=c.getContext('2d');ctx.scale(dpr,dpr);
return{c,ctx,w:r.width,h:r.height};
}
let W1,W2,W3;
/* ====== 脉冲SVG创建 ====== */
function mkPulseSVG(wl){
const g=document.createElementNS(NS,'g');
// 光晕
const glow=document.createElementNS(NS,'rect');
glow.setAttribute('width',PW+10);glow.setAttribute('height',PH+10);
glow.setAttribute('rx','6');glow.setAttribute('fill',wl===0?'#00ccff':'#ff8800');
glow.setAttribute('opacity','0.12');glow.setAttribute('filter',wl===0?'url(#gC)':'url(#gO)');
g.appendChild(glow);
// 主体
const rect=document.createElementNS(NS,'rect');
rect.setAttribute('width',PW);rect.setAttribute('height',PH);
rect.setAttribute('rx','4');
rect.setAttribute('fill',wl===0?'#00ccff':'#ff8800');rect.setAttribute('opacity','0.88');
g.appendChild(rect);
// 波长标签
const txt=document.createElementNS(NS,'text');
txt.setAttribute('x',PW/2);txt.setAttribute('y',PH/2+3);
txt.setAttribute('text-anchor','middle');
txt.setAttribute('fill',wl===0?'#001828':'#281000');
txt.setAttribute('font-size','7.5');txt.setAttribute('font-family','Orbitron,sans-serif');
txt.setAttribute('font-weight','700');
txt.textContent=wl===0?'λ₁':'λ₂';
g.appendChild(txt);
pG.appendChild(g);
return g;
}
/* ====== 散射闪光效果 ====== */
function spawnFlash(x,y,wl){
const c=document.createElementNS(NS,'circle');
c.setAttribute('cx',x);c.setAttribute('cy',y);c.setAttribute('r','3');
c.setAttribute('fill','none');c.setAttribute('stroke',wl===0?'#00ccff':'#ff8800');
c.setAttribute('stroke-width','2');c.setAttribute('opacity','0.8');
c.setAttribute('filter','url(#gG)');
flashG.appendChild(c);
let r=3,o=0.8;
function tick(){
r+=1.2;o-=0.04;
if(o<=0){if(c.parentNode)c.parentNode.removeChild(c);return}
c.setAttribute('r',String(r));c.setAttribute('opacity',String(o));
requestAnimationFrame(tick);
}
requestAnimationFrame(tick);
}
/* ====== 脉冲发射 ====== */
function emitPulse(){
const wl=S.nextWL; S.nextWL=1-S.nextWL;
S.pulses.push({
wl,el:mkPulseSVG(wl),x:FL,y:OY,
dir:1,lane:0,scattered:false,alive:true,op:1
});
}
/* ====== 脉冲更新 ====== */
function updatePulse(p){
p.x+=p.dir*SPEED;
// 出射脉冲经过振动区 → 产生回波
if(p.lane===0 && !p.scattered && p.x>=VZX){
p.scattered=true;
spawnFlash(p.x,OY,p.wl);
// 生成回波脉冲
const rp={
wl:p.wl,el:mkPulseSVG(p.wl),x:p.x,y:RY,
dir:-1,lane:1,scattered:true,alive:true,op:0.7
};
S.pulses.push(rp);
}
// 超出边界
if(p.lane===0 && p.x>FR+20) p.alive=false;
if(p.lane===1 && p.x<FL-10) p.alive=false;
// 更新SVG位置
const ox=-PW/2-5, oy=-PH/2-5;
p.el.setAttribute('transform','translate('+(p.x+ox)+','+(p.y+oy)+')');
p.el.setAttribute('opacity',String(p.op));
}
/* ====== 振动波形SVG更新 ====== */
function updateVibWave(t){
const cx=VZX,cy1=OY,amp=14;
const f=S.freq/180;
const phase=t*0.002*f*8;
let d='M '+(cx-32)+' '+cy1;
for(let i=-32;i<=32;i+=2){
const yy=cy1+Math.sin(i/32*Math.PI*4+phase)*amp*Math.cos(i/32*Math.PI/2.2);
d+=' L '+(cx+i)+' '+yy;
}
vibW.setAttribute('d',d);
// 振动区呼吸效果
const vibZone=document.getElementById('vibZone');
const glow=0.35+0.15*Math.sin(t*0.004);
vibZone.setAttribute('opacity',String(glow));
}
/* ====== 波形绘制 ====== */
function drawWave(info,channel){
const{ctx,w,h}=info;
ctx.clearRect(0,0,w,h);
const m={l:12,r:12,t:14,b:10};
const pw=w-m.l-m.r, ph=h-m.t-m.b;
const cy=m.t+ph/2;
const T=10; // 显示10ms
const freq=S.freq;
const phase=S.wavePhase;
const tX=t=>m.l+(t/T)*pw;
const vY=v=>cy-v*(ph/2)*0.78;
// 背景
ctx.fillStyle='#050912';ctx.fillRect(0,0,w,h);
// 网格
ctx.strokeStyle='rgba(20,36,62,.45)';ctx.lineWidth=.5;
for(let t=0;t<=T;t+=1){const x=tX(t);ctx.beginPath();ctx.moveTo(x,m.t);ctx.lineTo(x,h-m.b);ctx.stroke()}
for(let v=-1;v<=1;v+=.5){const y=vY(v);ctx.beginPath();ctx.moveTo(m.l,y);ctx.lineTo(w-m.r,y);ctx.stroke()}
// 零线
ctx.strokeStyle='rgba(80,120,160,.25)';ctx.lineWidth=1;
ctx.beginPath();ctx.moveTo(m.l,cy);ctx.lineTo(w-m.r,cy);ctx.stroke();
// 真实信号(淡)
ctx.strokeStyle='rgba(80,120,160,.18)';ctx.lineWidth=1.5;ctx.beginPath();
for(let px=0;px<=pw;px++){
const t=(px/pw)*T;
const v=Math.sin(2*Math.PI*freq*t/1000+phase);
const x=m.l+px, y=vY(v);
px===0?ctx.moveTo(x,y):ctx.lineTo(x,y);
}
ctx.stroke();
// 采样时刻
let pts=[];
if(channel==='l1'){
for(let t=0;t<=T;t+=1) pts.push({t,wl:0});
}else if(channel==='l2'){
for(let t=0.5;t<=T;t+=1) pts.push({t,wl:1});
}else{
for(let t=0;t<=T;t+=0.5){
const wl=(Math.round(t*2)%2===0)?0:1;
pts.push({t,wl});
}
}
// 计算采样点坐标
const dots=pts.map(p=>({
x:tX(p.t), y:vY(Math.sin(2*Math.PI*freq*p.t/1000+phase)), wl:p.wl, t:p.t
})).filter(d=>d.x>=m.l && d.x<=w-m.r);
// 重建线(连接采样点)
if(dots.length>1){
if(channel==='inter'){
ctx.strokeStyle='rgba(0,255,136,.55)';ctx.lineWidth=2.2;
}else{
ctx.strokeStyle=channel==='l1'?'rgba(0,204,255,.35)':'rgba(255,136,0,.35)';
ctx.lineWidth=1.6;
}
ctx.beginPath();ctx.moveTo(dots[0].x,dots[0].y);
for(let i=1;i<dots.length;i++) ctx.lineTo(dots[i].x,dots[i].y);
ctx.stroke();
}
// 采样点绘制
for(const d of dots){
const col=d.wl===0?'#00ccff':'#ff8800';
const a=channel==='inter'?0.55:0.85;
// 茎线
ctx.strokeStyle=col;ctx.globalAlpha=a*0.28;ctx.lineWidth=1;
ctx.beginPath();ctx.moveTo(d.x,cy);ctx.lineTo(d.x,d.y);ctx.stroke();
// 圆点
ctx.globalAlpha=a;ctx.fillStyle=col;
ctx.beginPath();ctx.arc(d.x,d.y,channel==='inter'?3.2:3.5,0,Math.PI*2);ctx.fill();
// 亮点
ctx.globalAlpha=a*0.5;ctx.fillStyle='#fff';
ctx.beginPath();ctx.arc(d.x,d.y-1,1.2,0,Math.PI*2);ctx.fill();
ctx.globalAlpha=1;
}
// 混叠指示
if(channel!=='inter' && freq>500){
ctx.fillStyle='rgba(255,48,96,.08)';ctx.fillRect(m.l,m.t,pw,ph);
ctx.font='bold 10px "Share Tech Mono",monospace';ctx.fillStyle='#ff3060';
ctx.textAlign='center';ctx.fillText('⚠ 混叠失真',w/2,m.t+14);ctx.textAlign='start';
}
if(channel==='inter' && freq>1000){
ctx.fillStyle='rgba(255,48,96,.08)';ctx.fillRect(m.l,m.t,pw,ph);
ctx.font='bold 10px "Share Tech Mono",monospace';ctx.fillStyle='#ff3060';
ctx.textAlign='center';ctx.fillText('⚠ 超过等效奈奎斯特',w/2,m.t+14);ctx.textAlign='start';
}
// IFR有效指示
if(channel==='inter' && freq<=1000){
ctx.font='bold 9px "Orbitron",sans-serif';ctx.fillStyle='rgba(0,255,136,.5)';
ctx.textAlign='center';ctx.fillText('✓ 无混叠 · 高保真',w/2,h-m.b+2);ctx.textAlign='start';
}
// 频率标签
ctx.font='9px "Share Tech Mono",monospace';ctx.fillStyle='#2a4a68';
ctx.textAlign='right';ctx.fillText('0',m.l-3,cy+3);
ctx.fillText('+1',m.l-3,m.t+10);ctx.fillText('−1',m.l-3,h-m.b);
ctx.textAlign='center';
ctx.fillText('0',tX(0),h-m.b+10);ctx.fillText('5 ms',tX(5),h-m.b+10);ctx.fillText('10 ms',tX(10),h-m.b+10);
}
/* ====== 主动画循环 ====== */
function loop(){
S.frame++;
S.wavePhase+=0.025; // 波形缓慢滚动
// 发射脉冲
if(S.frame>=S.nextPulse){
emitPulse();
S.nextPulse=S.frame+INTERVAL;
}
// 更新所有脉冲
for(const p of S.pulses) updatePulse(p);
// 移除死亡脉冲
const dead=S.pulses.filter(p=>!p.alive);
for(const p of dead){if(p.el.parentNode)p.el.parentNode.removeChild(p.el)}
S.pulses=S.pulses.filter(p=>p.alive);
// 限制同时存在的脉冲数(性能保护)
if(S.pulses.length>30){
const oldest=S.pulses.splice(0,S.pulses.length-30);
for(const p of oldest){if(p.el.parentNode)p.el.parentNode.removeChild(p.el)}
}
// 振动区动画
updateVibWave(S.frame*16.67);
// 洞察标注
if(S.frame>180 && !S.insightShown){
S.insightShown=true;
insightEl.setAttribute('opacity','1');
}
// 绘制波形
drawWave(W1,'l1');
drawWave(W2,'l2');
drawWave(W3,'inter');
requestAnimationFrame(loop);
}
/* ====== 滑块交互 ====== */
fSlider.addEventListener('input',function(){
S.freq=parseInt(this.value);
fValEl.textContent=S.freq+' Hz';
if(S.freq>500) nWarnEl.classList.add('on'); else nWarnEl.classList.remove('on');
});
/* ====== 初始化 ====== */
function init(){
W1=initCanvas('c1');W2=initCanvas('c2');W3=initCanvas('c3');
loop();
}
if(document.readyState==='loading') document.addEventListener('DOMContentLoaded',init);
else init();
window.addEventListener('load',function(){
// 重载保护:若未运行则启动
if(!W1) init();
});
})();
</script>
</body>
</html>
实现说明:
光纤系统图(SVG动画)
- 左侧询问器单元包含脉冲光源、光电接收和波长解复用器(棱镜符号)
- 光纤分为上下两条车道:出射脉冲(→)和后向散射回波(←)
- λ₁(青色)和 λ₂(橙色)脉冲交替发射,沿光纤传播
- 脉冲经过振动传感区时产生散射闪光效果,同时生成回波脉冲返回
- 振动区以正弦波形动态展示振动状态,并带有呼吸式发光
三路波形对比(Canvas绘制)
- λ₁通道:1 kHz采样率的采样点与重建线,超过500 Hz时出现混叠警告
- λ₂通道:同样1 kHz但时间偏移0.5 ms的采样点
- 交错重建(IFR面板):双波长交错后等效2 kHz采样率,重建线(绿色)精准跟踪真实信号,带有"IFR理想解"标识和脉冲呼吸动画
交互控制
- 频率滑块(100–2000 Hz)实时调整振动频率
- 当频率超过500 Hz时显示奈奎斯特警告
- 当频率超过1000 Hz时等效系统也出现混叠提示
- 500–1000 Hz区间正是本方案的价值区间:单通道混叠而交错重建无混叠
IFR核心思想体现
- 动画聚焦于"矛盾已解决"的理想运行状态
- 底部洞察标注:"同波长间距大→无混叠 │ 异波长交错→双倍采样率"
- 绿色高亮的IFR面板与两侧单通道面板形成鲜明对比,引导用户关注核心创新点
积分规则:第一轮对话扣减8分,后续每轮扣6分
等待动画代码生成...
