你肯定刷到过那个画面一个接一个的圆套着圆圆心之间互相牵着走最外圈的小笔尖拖出一条不断延伸的波形最后硬生生拼出一个棱角分明的方波。这几乎是“傅里叶级数”的官方代言图我第一次看到时第一反应是“这玩意儿到底是怎么算出来又是怎么画出来的”。后来我用 MATLAB 画过用 Python 重写过也帮别人用 PPT 手工仿过前前后后踩了不少坑。这篇文章就是完整讲清楚“旋转圆叠加方波”动画怎么做出来从方波的傅里叶级数原理到 Python 代码逐行讲解再到 Manim、Canvas、PPT 这些不同路线的取舍以及我实际操作中遇到的各类翻车现场和排查方法。无论你是正在学傅里叶变换的学生还是想给自己的视频或课件做一个数学可视化动画这篇文章都值得直接收藏照着做。1. 先搞清楚方波为什么能被旋转圆画出来1.1 一条方波等于一堆正弦波相加很多人第一次看到旋转圆动画时觉得圆和方波完全是两个世界的东西。其实关键在于傅里叶级数任何满足条件的周期函数都能拆成一系列不同频率、不同振幅的正弦波和余弦波。方波是最经典的例子它的分解公式长这样f(t) (4/π) × [sin(t) (1/3)sin(3t) (1/5)sin(5t) (1/7)sin(7t) ...]注意几个细节第一系数是 4/π第二括号里只出现奇数频率1、3、5、7、9...所有偶数次谐波都是零第三每个频率 n 的振幅是 1/n。这些细节直接决定你动画里每个圆的半径和转速所以务必记牢。为什么只有奇数次谐波因为标准方波在上下半个周期里是对称的奇函数偶数次谐波的正弦项会在拼起来时互相抵消。我当时第一次自己推这个公式算到第三项就发现规律了后面全是 4/(πn) 乘 sin(nt) 的样子。你如果只是想复现动画不用把积分推导背下来但至少要知道“圆的数量越多逼近方波越精确”。1.2 正弦波和旋转圆其实是一回事接下来是动画的核心桥梁为什么正弦波可以画成一个旋转的圆这要归功于欧拉公式e^(iθ) cos(θ) i·sin(θ)也就是说如果一个点在复平面里做半径为 r 的匀速圆周运动它的位置写成z(t) r·e^(i ω t) r·cos(ωt) i·(r·sin(ωt))其中实部是水平方向的投影虚部是竖直方向的投影。你看这个点的竖直坐标正好就是 r·sin(ωt)一条正弦波。换句话说一个旋转圆的竖直投影就是一条正弦曲线。所以每一级傅里叶级数里的 sin(nt) 项我都可以“翻译”成一个小圆圆半径就是这一项的振幅 4/(πn)圆转速就是频率 n。把多个旋转圆嵌套起来时大圆上带着小圆小圆上再带着更小的圆最后的末端点位置就是所有圆的向量叠加。末端点的竖直坐标恰好就是所有正弦项相加后的值。你保留的圆越多这个竖直坐标随时间的轨迹就越接近方波。这也是“旋转圆叠出方波”动画的全部秘密——它画的根本不是圆而是“圆周运动的竖直投影之和”。1.3 别误解圆链末端画出的不是整条方波这里有一个特别容易混淆的细节我在不少讨论贴里见过。如果你把所有圆看成复平面上的向量求和那么末端点 P(t) Σ r_n e^(i n t)它在复平面里拖出的轨迹并不就是方波的轮廓。准确说法是末端点的虚部竖直坐标随时间变化才是方波。所以动画通常有两种呈现形式一种是在圆链旁边还有一个“画波形”的区域时间轴往右展开末端点的竖直位置被同步投射到这个二维坐标里画出一条方波曲线。另一种是把末端点在复平面上的轨迹直接画出来那得到的其实是一个近似的什么图形呢取决于你用的是纯奇次正频率项还是加了负频率项。如果用的是前一种单侧圆链复平面轨迹会比较像“带圆弧的方波变形图”而不是教科书里那种横着的方波波形式。我建议刚上手时先用“圆链 右侧波形展开”这种布局因为它的视觉解释最清晰观众一眼就能看到圆在转、波在长。等理解了这一步再去玩复平面轨迹画矩形轮廓也不迟。2. 制作路线选型别一上来就上大引擎2.1 四条常用路线对比把原理搞明白之后就到了“怎么做出来”的问题。这个动画的实现路径非常多我帮你梳理一下当前最主流的四条路线以及它们的适用场景路线上手难度视觉效果适合场景Python Matplotlib低中等偏学术快速验证原理、教学演示、导出 GIF/MP4Python Manim中高极高丝滑运镜高质量数学动画视频接近 3Blue1Brown 风格JavaScript Canvas中高可交互网页展示、博客动态 banner、H5 交互动画PPT / GeoGebra 手工模拟低较低适合粗略示意一次性的课堂演示不追求精细这里提醒一句网络热词里经常出现 animation.css、PPT 动画、逐帧动画之类的关键词但很多预设动画库对傅里叶圆链其实帮不上忙因为这个动画的核心是“每一帧都要重新计算向量叠加位置”而不是位移循环。用 CSS 做出来的旋转圆最多是个外形像数学上并不准确。所以如果你追求的是真正的傅里叶级数效果至少需要一点代码能力或者是 GeoGebra 这种数学工具。2.2 为什么我推荐先用 Matplotlib 复刻首推 Matplotlib原因很简单Python 环境大多数人都有matplotlib 是标配而且它的 FuncAnimation 模块天生就是做这种“每帧更新图形”的动画。对比 ManimMatplotlib 的安装和排错成本低得多不会出现“渲染半天变成黑屏”这种劝退问题对比 CanvasMatplotlib 不需要考虑浏览器兼容也没有必须实时计算导致掉帧的压力。我之前帮一个朋友做教学视频对方要求“画面简洁、能看出圆的层级、波形要清晰”我用 Matplotlib 写了两个版本一个 3 分钟能跑出结果一个做了更多美化用了半小时。如果一上来就用 Manim光是安装依赖和配 LaTeX 字体可能就够折腾一晚上。所以实战建议是第一次复现用 Matplotlib跑通以后觉得不够炫再迁移到 Manim后者很多概念是相通的。3. 完整实操用 Matplotlib 从零搭出旋转圆叠加方波3.1 数学骨架先把系数和相位算对做动画前先把数据模型写对。标准方波单侧级数的第 n 项是r_n 4 / (π n)角度 θ_n n t因为我只取奇数次 n所以 n 可以写成 2k1k 从 0 开始。比如想叠加前 10 个谐波k 取 0 到 9对应 n 1, 3, 5, ..., 19。末端点位置计算公式是x_end Σ r_n cos(n t) y_end Σ r_n sin(n t)每个圆的圆心就是前一个向量的末端第 k 个圆的圆心坐标是前 k 个向量累加结果第 k 个圆的半径是 r_n。这里最容易出错的是某个圆自己的旋转角度起点相标准公式里是 θ n t也就是所有圆在 t0 时角度都是 0如果为了视觉效果想加初始相位必须所有圆统一加同一个值否则叠加出来的波形形状会变。3.2 可直接运行的 Python 代码下面这个脚本是我实际用过并精简后的版本它实现了左侧圆链 右侧方波同步生长的效果。代码可以直接保存为 .py 运行前提是你已经装好 numpy 和 matplotlib。import numpy as np import matplotlib.pyplot as plt from matplotlib.animation import FuncAnimation # ---------- 参数设置 ---------- N_HARMONICS 15 # 叠加 15 个谐波实际 n 为 1,3,5,...,29 FPS 30 # 每秒帧数 DURATION 12 # 动画总时长秒 WAVE_SCALE 6.0 # 右侧波形图的横向拉伸系数 CIRCLE_SCALE 1.0 # 左侧圆链整体缩放避免超出画布 # ---------- 计算每个圆的半径和角速度 ---------- n_values [2 * k 1 for k in range(N_HARMONICS)] radii [4.0 / (np.pi * n) for n in n_values] omegas [n for n in n_values] # ---------- 创建画布 ---------- fig, ax plt.subplots(figsize(14, 6)) ax.set_xlim(-1.5, 13.5) ax.set_ylim(-1.8, 1.8) ax.set_aspect(equal) ax.axis(on) ax.grid(True, alpha0.3) # ---------- 初始化绘图对象 ---------- circle_patches [] # 存储所有圆 line_segments [] # 存储圆心到圆周上点的连线 point_dot, ax.plot([], [], ro, markersize6) trace_line, ax.plot([], [], lw1.2, colorcrimson) # 预创建图形对象 for _ in range(N_HARMONICS): c plt.Circle((0, 0), 0.1, fillFalse, edgecolorsteelblue, lw0.8) ax.add_patch(c) circle_patches.append(c) seg, ax.plot([], [], lw1.0, colorgray, alpha0.8) line_segments.append(seg) # 右侧波形数据的存储 time_phases [] wave_values [] def update(frame): t frame / FPS # 计算当前所有圆的位置 positions [] # 每级圆心位置 x, y 0.0, 0.0 for idx, n in enumerate(n_values): circle_patches[idx].center (x, y) circle_patches[idx].set_radius(CIRCLE_SCALE * radii[idx]) angle omegas[idx] * t dx CIRCLE_SCALE * radii[idx] * np.cos(angle) dy CIRCLE_SCALE * radii[idx] * np.sin(angle) line_segments[idx].set_data([x, x dx], [y, y dy]) x dx y dy positions.append((x, y)) # 末端点位 point_dot.set_data([x], [y]) # 记录波形数据 time_phases.append(t) wave_values.append(y) # 只保留最近一段长度的曲线避免右侧图太长 max_len WAVE_SCALE * DURATION * FPS // 10 if len(time_phases) max_len: time_phases.pop(0) wave_values.pop(0) # 将末端点的纵向位置投影到右侧波形坐标系 trace_x [t * WAVE_SCALE for t in time_phases] trace_y wave_values trace_line.set_data(trace_x, trace_y) return circle_patches line_segments [point_dot, trace_line] anim FuncAnimation(fig, update, framesFPS * DURATION, interval1000 / FPS, blitTrue) # 保存 GIF需要 Pillow如果想保存 MP4可改用 ffmpeg 参数 anim.save(fourier_square_wave.gif, writerpillow, fpsFPS) plt.show()这个脚本把所有权重都算好了直接运行能出一个 12 秒的 GIF。我第一次跑通这个版本时看到右侧曲线慢慢变成方波内心还是很兴奋的。不过这个版本只画了右侧的“末端纵向轨迹”如果你想在右侧也画出完整的“随着时间展开的波形”并且让波形末端的点和左侧圆链末端用一条水平线连起来还需要再加一条水平连接线稍后我会说明。3.3 关键参数怎么调圈数、帧率、尾迹长度首先是谐波数量 N_HARMONICS。我实测下来N3 时右侧波形还是明显的波浪状N7 时已经能看到方波的大概轮廓但转折处有明显的过冲和振铃N15 到 N30 是视觉和性能的甜点区如果 N 超过 50画面左侧的圆会密密麻麻看似壮观但圆与圆之间的半径越来越接近视觉上已经很难分清层级而且计算量会明显上升。建议第一次直接设 15效果最好。其次是帧率 FPS。30 帧每秒对 GIF 来说已经够流畅。如果你要导出 MP4可以考虑 60 帧因为视频压缩后会有损失。注意 GIF 文件体积12 秒的 1440×720 GIF 很容易超过 20MB如果你只是发社交媒体可以把分辨率降到 800 宽或者在保存时用 optimizeTrue。最后是右侧波形线的横向拉伸系数 WAVE_SCALE。这个参数是我后加的因为如果不拉伸方波在右侧会非常“矮胖”不方便观察波形。一般取 5 到 8 合适太小波形挤在一起太大曲线来不及展开就退出屏幕。3.4 让动画更有“教学味”连接线、高亮当前点与坐标标签上面代码是基本版如果用来教学我建议再加三样东西一是左侧末端和右侧波形末端之间的水平连接线观众能直观看到“圆链末端的高度决定了波形当前位置的值”二是当前时刻波形上画一个大圆点醒目一点三是给每个圆的半径标上数值比如 r4/π、r4/(3π)这能让观众直接对应到傅里叶系数。连接线实现很简单在 update 里记录 x 和 y然后画一条从 (x, y) 到 (t*WAVE_SCALE, y) 的线即可。我加完这条线之后整个动画的“因果感”立刻强了很多。你会发现当末端点向上摆的时候右侧波形也在往上长两者是一一对应的。connect_line, ax.plot([], [], lw0.8, ls--, colororange) # 在 update 最后 connect_line.set_data([x, frame / FPS * WAVE_SCALE], [y, y])高亮当前波形点也简单在 trace_line 后面用同一个点坐标画一个浅色的大圆点作为光晕视觉效果会好很多。4. 常见问题排查与实操心得4.1 右侧波形转折处为什么总是“凸起”不是算错了这是被问得最多的问题。当你叠加的谐波数量有限时方波的边缘必定带过冲这在数学上叫 Gibbs 现象。我最初以为是代码把相位写错了后来把 N 加到 100 还是有过冲才意识到这是固有现象。具体表现是波形接近方波跳变时会有幅度约 8.95% 的过冲不管加多少谐波都不消失只是过冲振铃的宽度会越来越窄。很多教学动画会故意保留这个现象因为它恰恰说明“有限级数无法完美表示不连续点”。你在 PPT 课程里甚至可以把 N 做两个版本一个 N5 一个 N50对比给学生看效果远比空口讲 Gibbs 现象好。4.2 圆链整体越转越偏甚至跑出画面怎么办如果你把圆链末端位置直接累加会发现 P(t) 的实部会来回摆但整体中心可能偏到左边或者右边因为余弦项的加和并不以原点为中心。这个问题在动画里非常常见尤其当 N 比较小时末端点的水平坐标会有明显漂移。解决办法有两个一是加大左侧画布范围比如把 xlim 设为 [-2, 16]y 轴不变圆链会缩在小区域里转二是对所有圆的初始相位做一个调整让末端点在 t0 时停在某个理想位置。更简单的做法是给每个圆的位置累加前减去多出来均值偏置。不过我不建议随便做数学变换那会改变波形形状。我的经验是动画的左侧区域放宽到 1.5 倍圆链总直径基本不会跑出画面。4.3 动画卡顿、GIF 文件过大、颜色不够清晰卡顿一般出在两个地方一个是 N_HARMONICS 太大每一帧要更新几十个圆和线段另一个是波形数据越存越多导致绘图点数量爆炸。我上面的代码里已经做了 max_len 限制防止数据无限增长。如果还是卡可以把 blitTrue 打开它只重绘变化的区域能显著提速。GIF 过大则优先减小帧率和画布尺寸。如果你要的是高质量版本建议直接保存 MP4 而不是 GIF。Matplotlib 保存 MP4 需要电脑里有 ffmpeg命令改成anim.save(fourier_square_wave.mp4, writerffmpeg, fpsFPS, dpi120)颜色方面我有两个常用配色学术风用黑色背景 白色圆 青色波形比较接近 3Blue1Brown简洁风用白底 蓝色圆 红色波形。圆太多时可以把奇数项和偶数项画成两种颜色不过在方波场景里全是奇数项所以颜色相同没问题但可以用深浅区分内外层越外层的圆颜色越浅。4.4 经常有人问能不能让圆链末端直接在平面上画出方波轮廓我想单独讲一下这个问题因为它涉及对“旋转圆动画”的深层理解。如果你想让末端点在复平面上直接画出一个矩形轮廓不能只用单侧频率的实系数叠加因为标准方波的复数展开同时包含正频率和负频率。换句话说你需要把每个 sin(nt) 拆成两个旋转方向相反的圆每个圆半径减半一个顺时针转一个逆时针转这样它们的水平分量抵消竖直分量相加末端点在复平面上画出的轨迹才会是上下跳变的矩形轮廓而不是前面那种“圆链高度随时间变化”的展示。这种双圆版动画视觉上更接近“画图机”但代码复杂一些需要维护正负两套圆。如果你只是科普傅里叶级数我建议优先做“单侧圆链 右侧波形”版本如果是为了展示傅里叶变换的复数本质再去做双圆版本。5. 不写代码也能做的几种思路5.1 用 GeoGebra / Desmos 快速演示如果你完全不想安装 Python推荐用 GeoGebra 或者 Desmos。GeoGebra 可以这样操作定义 n 滑动条从 1 到 30步进 2定义 r 4/(π n)定义点 P (r cos(n t), r sin(n t))再用序列求和或向量累加生成一串点最后开启 trace 功能。GeoGebra 的 trace 可以让点留下轨迹配合时间变量 t 的动画按钮就能看到波形逐渐长出来。GeoGebra 的好处是零代码鼠标拖动滑动条改谐波数量还带实时交互特别适合课堂临时演示。我实际试过用 GeoGebra 复现前 15 次谐波效果非常不错。缺点是导出独立动画和自定义样式比较受限最终成品的“质感”不如 Python。5.2 PPT 手工模拟能行但只建议做概念版网络热词里有不少人搜“ppt动画”我猜也有一部分人想用 PPT 来做类似效果。坦率地说PPT 非常适合做“圆的旋转”基础动画但真正做到“末端点轨迹逐帧存储”非常吃力。你只能在 PPT 里预先画好几个不同半径的圆然后用“动画窗格”里的“陀螺旋”或“路径动画”设置转速比例让大圆转一圈、小圆转三圈并且把圆的中心点和下一级的圆心锁定在一起。实际操作上你需要用到“组合形状 动画刷”步骤大致是先画一个半径 4/π 的圆在里面画一个半径 4/(3π) 的小圆小圆的圆心放在大圆边缘然后对小圆添加“陀螺旋”动画设置持续时间为大圆的 1/3重复次数要相同。更麻烦的是末端轨迹PPT 无法自动记录你需要用“平滑路径”手动画一条近似方波再用动画“擦除”逐步显示效果会比较失真。所以我的结论是PPT 做这个只是“形式上像”真要体现数学还是用代码或 GeoGebra。5.3 网页端Canvas 是正路animation.css 只是玩具如果你想把动画放到个人博客或者产品页上JavaScript Canvas 是最合适的选择思路和 Matplotlib 完全一样每一帧清空画布循环绘制所有圆和线段末端点位置用欧拉公式累加然后画波形。Canvas 的好处是可以加鼠标交互比如点击某个圆高亮对应谐波这是静态教学资源做不到的。至于 CSS 动画库比如 animation.css它只能做预设位移、缩放、旋转循环无法做“多级圆周运动求和”的实时计算。你可以用 CSS 画出几个叠着的圆同时旋转但末端轨迹的精确绘制基本得靠 SVG path 或 Canvas 逐帧绘制。如果你对 Web 前端不熟我甚至建议不要硬啃 Canvas直接用前面说的 GeoGebra 或者 Python 导出 GIF 后嵌入网页省时又稳定。最后再说一点个人体会这动画我前前后后做了好几版从最早用 MATLAB 乱改参数到后来用 Python 写成带参数的脚本感受最深的一点是动画只是结果真正值钱的是你动手推导方波傅里叶系数那一步。你把 r_n 4/(πn) 这个式子写出来、再把 sin 拆成旋转圆投影的那一刻傅里叶级数就再也不是抽象公式了。一个很实用的建议不要一上来追求 50 个谐波先跑 N3认真看看三个圆是怎么把波形扭出一个雏形的再逐步加到 15。如果你之后想让动画更高级一点可以试试把右侧波形改成“可暂停 可回溯”或者加一个谐波数量滑块动态增减圆的数量那种“边调边看波形变化”的交互感比固定动画强得多。回来再重复一遍这个动画的难点不在画圆而在把数学公式翻译成逐帧的向量累加。只要过了这一关以后你想画锯齿波、三角波、甚至任意周期信号都是同一个套路。
企业数字化 ERP 产品动态
相关推荐
SMP平台函数功能实现与优化实践 1. 函数功能在SMP平台中的实现历程 作为一名长期从事企业信息化系统开发的工程师,我在使用SMP(软件制作平台)进行应用开发时遇到了一个关键瓶颈——平台原生缺乏函数功能。这导致我们在处理复杂业务逻辑时,不得不重复编写大量相似… · 2026/11/3 17:24:34
Redis Lua实现大模型API配额防透支的原子扣减方案 1. 项目概述:为什么“API配额防透支”不是锦上添花,而是生死线你刚上线一个面向中小企业的AI助手SaaS平台,后端调用的是OpenRouter或智谱千问这类大模型服务商的API。初期用户增长不错,某天凌晨三点,运维告警疯狂弹窗&… · 2026/11/3 17:24:34
游戏开发图集管理工具:MaxRects算法与性能优化实践 1. 工具定位与核心价值 在游戏开发流程中,图集(Texture Atlas)管理是个高频且耗时的环节。我们团队在开发2D横版游戏《星之轨迹》时,美术资源迭代过程中平均每天要处理37次图集调整。传统Photoshop手动拼合的方式,每次… · 2026/11/3 18:04:32
PyTorch推荐系统中的特征交互建模实践 1. 项目背景与核心定位Torch-RecHub作为基于PyTorch的推荐系统工具库,其任务2模块主要面向推荐算法中的特征交互建模场景。这个模块的设计初衷是为了解决传统推荐系统中特征交叉效率低下、表达能力有限的问题。在实际业务中,用户行为与物品特征之间的复杂… · 2026/11/3 18:04:32
JDBC连接MySQL原理与实践指南 1. JDBC连接MySQL的核心原理与价值 JDBC作为Java数据库连接的工业标准,本质上是一套面向关系型数据库的抽象接口层。它的设计哲学与Java平台"一次编写,到处运行"的理念一脉相承——通过定义统一的API规范,让开发者可以用相同的代码… · 2026/11/3 18:04:32
对比式目标感知融合技术解析与应用实践 1. 对比式目标感知融合技术概述在计算机视觉领域,如何有效融合多模态数据中的目标级信息一直是个核心挑战。Contrastive Object-Aware Fusion(对比式目标感知融合)正是为解决这一问题而生的创新方法。我首次接触这项技术是在处理跨摄像头行人… · 2026/11/3 18:04:32
汽车油耗计算原理与省油技巧全解析 1. 油耗计算的基本原理 作为一名开了十几年车的老司机,我经常被朋友问到"你的车油耗多少"这个问题。其实计算油耗并不复杂,但很多人对背后的原理和具体操作存在误解。今天我就来详细讲讲如何准确计算汽车油耗,以及影响油耗的各种因… · 2026/11/3 18:04:32
C++中struct与class的本质区别与工程实践 1. 结构体与类的本质探析在C的语法体系中,struct和class就像一对孪生兄弟,表面相似却各有性格。作为从C语言继承而来的语法结构,struct在C中被赋予了全新的内涵。记得我刚接触C时,曾天真地认为struct只是C语言中那个简单的数据打包… · 2026/11/3 18:03:32
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46
STM32F411RE与MAX14431实现SPI隔离:工业现场抗共模干扰实战 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
ESP32+大模型AI硬件开发:从Demo到产品的8个工程问题 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
基于MAX14431BAEE+与PIC18F85J10的SPI隔离方案设计与实践 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 1:01:59
双极步进电机控制实战:DRV8818PWPR与PIC18F86K22驱动调试 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/2 13:10:28
STM32F207ZG + DRV8818PWPR 步进电机驱动实战解析 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 6:04:24
DRV8818PWPR+dsPIC30F4013工业级双极步进电机控制方案 /* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views … · 2026/11/3 5:52:46