三角函数 · 原理与代码
单位圆上旋转点投影出 sin/cos,波形随角度 θ 实时展开;可切换 tan、调相位/频率/振幅。
运行逻辑
访问 `/math/trig-waves` 时,DemoHost 按 registry 的 `mod: 'trig-waves'` 懒加载 `demos/trig-waves.js`,调用 `mountTrigWaves(host, { variant: 'trig-waves' })`。 模块自行创建 three.js 渲染器、场景、相机和 OrbitControls,并用 `createInfoPanel` 挂上信息面板。 每个 `requestAnimationFrame`:读取控件值,按速度缩放模拟时钟(dt 上限 50 ms),执行帧回调绘制;返回的读数写入信息面板。 改变参数:颜色/速度/大小等即时生效,需要重建的参数触发重新挂载;离开页面时取消 rAF、移除监听并释放资源。
运行环境
Canvas 2D: 2D 画布绘图; WebGL (three.js): three.js 通过 WebGLRenderer 使用 WebGL; requestAnimationFrame: 与屏幕刷新同步的动画循环; ResizeObserver: 画布随容器尺寸自适应; Pointer Events: 鼠标/触摸/触控笔统一事件; devicePixelRatio: HiDPI 清晰渲染(上限 2×) · react 18.3.1, react-router-dom 6.30.6, vite 5.4.21, three 0.170.0
引入的组件与依赖
three 0.170.0, three/addons/controls/OrbitControls.js 0.170.0, react 18.3.1
引入的组件函数
THREE — three.js 命名空间; OrbitControls — three.js 轨道相机控制:拖动旋转、滚轮/双指缩放; readLiveControls — 读取当前控件值(CSS 变量回退); colorToRgb — 颜色 → RGB 分量; maxDpr — 按设备限制像素比; preferLiteFx — 低端/移动设备时降低特效; tuneOrbitControls — 调校 OrbitControls(阻尼、触控); createInfoPanel — 右侧/底部信息面板:实时读数 + 公式/说明/参数/步骤; dockControls — 把控制面板停靠到画布旁; MATH_DOCS — 数学演示的公式/说明/参数文案表; THREE.BufferGeometry — 自定义顶点几何体; THREE.LineBasicMaterial — 线条材质; THREE.Line — 折线; THREE.Vector3 — 三维向量; THREE.LineDashedMaterial — 虚线材质; THREE.WebGLRenderer — WebGL 渲染器; THREE.Scene — 场景; THREE.OrthographicCamera — 正交相机; THREE.Group — 分组容器; THREE.LineSegments — 线段集合; THREE.Mesh — 网格物体(几何体 + 材质); THREE.CircleGeometry — 圆形几何体; THREE.MeshBasicMaterial — 不受光照的材质; THREE.BufferAttribute — 顶点属性数组(位置/颜色)
本 demo 代码
frontend/src/demos/trig-waves.js: trig-waves.js (L1-L522)
代码解释
L8-8: `TAU`(常量/表)。 L9-9: `COLORS`(常量/表)。 L11-35: `CSS`(常量/表)。 L37-41: `line`(函数);创建 three.js 对象 `BufferGeometry`, `LineBasicMaterial`, `Line`。 L42-48: `dashed`(函数);创建 three.js 对象 `BufferGeometry`, `Vector3`, `LineDashedMaterial`, `Line`。 L49-55: `setSeg`(函数)。 L57-522: `mountTrigWaves`(函数)。 L58-88: 定义 `ctrl`;创建 three.js 对象 `WebGLRenderer`;数学计算用到 `Math.max`, `Math.min`。 L89-100: 定义 `labelsEl`;创建 three.js 对象 `Scene`, `OrthographicCamera`。 L103-111: layout: circle centered at (CX,0); waves start at X0 and run to X1;创建 three.js 对象 `Group`。 L114-125: grid + axes;创建 three.js 对象 `LineBasicMaterial`, `Vector3`, `LineSegments`, `BufferGeometry`。 L128-134: unit circle;创建 three.js 对象 `Vector3`, `Mesh`, `CircleGeometry`, `MeshBasicMaterial`;数学计算用到 `Math.cos`, `Math.sin`。 L137-143: angle arc (θ);创建 three.js 对象 `BufferGeometry`, `BufferAttribute`, `Line`, `LineBasicMaterial`, `Mesh`, `MeshBasicMaterial` …。 L146-176: radius, projections, markers;用 Canvas 2D 的 `createRadialGradient`, `fillRect` 绘制;创建 three.js 对象 `Vector3`, `SphereGeometry`, `Mesh`, `MeshBasicMaterial`, `CanvasTexture`, `SRGBColorSpace` …。 L177-177: 调用 `glow()`。 L180-205: waves: index 0 = newest (at X0), flows right;创建 three.js 对象 `Color`, `BufferGeometry`, `BufferAttribute`, `DynamicDrawUsage`, `Line`, `LineBasicMaterial` …;返回读数 `line`, `pos`, `col`, `geo`, `fill`, `fpos`, `fg` … 给信息面板。
原理
y = A · sin(f·θ + φ) y = A · cos(f·θ + φ),tan = sin / cos 周期 T = 2π / f 左边单位圆上的点转一圈(θ 从 0 到 2π),它的纵坐标描出正弦波、横坐标描出余弦波。A 拉伸波高,f 让波更密,φ 让整条波左右平移。