
简介本资源是一份面向物理专业本科生、研究生及MATLAB初学者的黑体辐射可视化教学实践包聚焦普朗克定律的数值实现与图像表达解决理论公式难直观理解、温度—波长—辐射强度关系难动态呈现的问题。压缩包共2个文件1个MATLAB源码文件plancklow.m 1个RGB像素数据文本文件总大小216KB其中m文件完整实现普朗克辐射谱计算、多温度曲线绘制、坐标标注与图例生成支持参数修改与结果复现txt文件提供实测/模拟光谱的RGB参考数据可用于理论曲线与实际光谱图像的定性比对验证。已有1702人学习下载资源代码结构清晰、注释友好附带可直接运行的完整计算逻辑涵盖普朗克公式编程实现、波长网格设定、指数项数值稳定性处理及多曲线可视化技巧是开展热辐射基础实验、量子物理课程设计或MATLAB科学绘图训练的实用入门材料。1. 用 MATLAB 直观呈现黑体辐射谱普朗克线不是一条“线”而是温度决定的连续能量分布曲线很多人第一次看到“普朗克线”这个词会下意识以为是某条固定位置的参考线——比如像玻尔轨道那样有确定波长。实际上它根本不是一条线而是一族由普朗克定律定义的、随温度变化的平滑辐射谱曲线。在 MATLAB 中绘制它核心不是调用某个现成函数而是亲手构建物理模型从波长或频率网格出发代入普朗克辐射公式再用plot或fplot渲染出峰值位置、形状和积分面积都严格符合热力学要求的曲线。这一步对物理仿真、红外测温标定、光学传感器响应建模甚至天文光谱拟合都构成底层支撑。如果你正在做热辐射建模、课程设计如《热学》《近代物理实验》、或需要验证某段红外探测器数据是否符合黑体假设那么这段代码不是演示而是可嵌入你 pipeline 的计算模块。它不依赖任何工具箱基础 MATLAB 即可运行但参数必须按 SI 单位制严格设置否则峰值波长会偏移近一个数量级。2. 从普朗克定律出发推导 MATLAB 可计算的辐射谱表达式并完成单位一致性校验普朗克定律描述黑体在温度 $T$ 下单位波长间隔内的光谱辐射出射度spectral radiance$$ B_\lambda(\lambda, T) \frac{2hc^2}{\lambda^5} \cdot \frac{1}{e^{\frac{hc}{\lambda k_B T}} - 1} $$其中$h 6.62607015 \times 10^{-34}~\text{J·s}$普朗克常数$c 2.99792458 \times 10^8~\text{m/s}$真空中光速$k_B 1.380649 \times 10^{-23}~\text{J/K}$玻尔兹曼常数注意MATLAB 中所有物理量必须统一为国际单位制SI。若输入波长单位为纳米nm必须先除以 $10^9$ 转为米若温度用摄氏度必须加 273.15 转为开尔文。单位错一位整个曲线峰值偏移超 10 倍——这是新手最常踩的坑。2.1 构建波长向量覆盖可见光到远红外兼顾分辨率与计算效率我们不使用linspace(0.2, 20, 1000)这类粗略范围因为普朗克谱在短波端发散$\lambda^{-5}$直接线性采样会导致数值溢出在长波端又趋近于零浪费计算资源。更合理的方式是采用对数间距logspace并在峰值附近加密采样% 定义温度开尔文 T 5800; % 太阳表面有效温度用于基准参考 % 计算维恩位移定律预测的峰值波长单位米 lambda_peak_theory 2.897771955e-3 / T; % 单位m % 构建波长向量以 lambda_peak_theory 为中心前后各扩展 2 个数量级 lambda_min lambda_peak_theory * 1e-2; % 0.01 × peak lambda_max lambda_peak_theory * 1e2; % 100 × peak % 使用 logspace 生成 2000 个点避免短波端数值爆炸 lambda logspace(log10(lambda_min), log10(lambda_max), 2000); % 单位m % 若需输出常用单位如微米可额外定义 lambda_um lambda * 1e6; % 转为 μm仅用于横轴标注这段代码的关键在于logspace保证了短波紫外区域有足够密度防止插值失真长波远红外区域不会因过密采样拖慢速度lambda_min/max动态绑定T使不同温度下的绘图范围自动适配——比如画 300 K室温物体时峰值在 9.7 μm范围自动设为 0.1–1000 μm画 1000 K 物体时峰值在 2.9 μm范围缩至 0.03–300 μm。2.2 实现普朗克公式用向量化运算避免 for 循环显式处理数值稳定性直接套用公式会出现两个典型问题① $\lambda \to 0$ 时$\exp(hc/\lambda k_B T)$ 溢出为Inf导致整项为NaN② $\lambda$ 很大时指数项趋近于 0分母 $e^x - 1 \approx x$但直接计算仍可能因浮点精度丢失导致除零错误。MATLAB 的稳健写法是引入expm1函数计算 $e^x - 1$ 的高精度版本并用条件分支截断极端值% 物理常数SI 单位 h 6.62607015e-34; c 2.99792458e8; kB 1.380649e-23; % 计算指数项 x hc / (lambda * kB * T) x (h * c) ./ (lambda * kB * T); % 使用 expm1 避免 e^x - 1 在 x 较小时的精度损失 % 同时对 x 700 的情况设为 Inf此时 e^x 已远超 double 表示上限 x(x 700) Inf; denominator expm1(x); % 等价于 exp(x) - 1但 x 接近 0 时更准 % 主公式B_lambda (2*h*c^2 / lambda^5) / (exp(hc/(lambda*kB*T)) - 1) B_lambda (2 * h * c^2) ./ (lambda.^5) ./ denominator; % 将结果单位转为常用 W·sr⁻¹·m⁻³即每米波长、每球面度、每平方米面积的功率 % 注意此即标准光谱辐亮度单位可直接与仪器标定值比对提示expm1(x)是 MATLAB 内置函数专为 $e^x - 1$ 设计。当 $x 10^{-5}$ 时exp(x)-1会产生相对误差达 $10^{-12}$ 量级而expm1(x)保持机器精度。此处x在长波端很小例如 $\lambda100~\mu m$ 时 $x \approx 0.001$必须使用。2.3 验证单位一致性用维恩位移定律和斯特藩-玻尔兹曼定律交叉校验绘图前必须验证计算结果是否自洽。我们用两个经典定律进行双重检验维恩位移定律理论峰值波长 $\lambda_{\max} b / T$其中 $b 2.897771955 \times 10^{-3}~\text{m·K}$斯特藩-玻尔兹曼定律总辐射出射度 $M \sigma T^4$其中 $\sigma 5.670374419 \times 10^{-8}~\text{W·m}^{-2}\text{·K}^{-4}$且 $M \int_0^\infty B_\lambda(\lambda,T),d\lambda$% 查找数值峰值位置注意lambda 是向量B_lambda 是对应值 [~, idx_peak] max(B_lambda); lambda_peak_numeric lambda(idx_peak); % 单位m lambda_peak_theory 2.897771955e-3 / T; fprintf(数值峰值波长: %.4g μm\n, lambda_peak_numeric * 1e6); fprintf(理论峰值波长: %.4g μm\n, lambda_peak_theory * 1e6); fprintf(相对误差: %.2e\n, abs(lambda_peak_numeric - lambda_peak_theory)/lambda_peak_theory); % 数值积分验证总辐射使用 trapz注意 dλ 步长 dlambda diff(lambda); % lambda 是 logspace步长不等故用 diff M_numeric trapz(lambda, B_lambda); % 单位W·sr⁻¹·m⁻² sigma 5.670374419e-8; M_theory sigma * T^4; fprintf(数值积分总辐射: %.4g W·sr⁻¹·m⁻²\n, M_numeric); fprintf(理论总辐射: %.4g W·sr⁻¹·m⁻²\n, M_theory); fprintf(相对误差: %.2e\n, abs(M_numeric - M_theory)/M_theory);运行后应看到两组误差均小于 $10^{-3}$。若超过 $10^{-2}$说明波长范围过窄、采样点不足或单位转换有误例如忘了把 nm 转 m。3. 绘制多温度普朗克线族叠加标注、动态范围压缩与视觉可读性优化单条曲线意义有限实际应用中需对比不同温度下的谱形变化如 LED 封装热分析、燃烧火焰温度反演。MATLAB 绘图需解决三个关键问题① 多曲线重叠导致低温度曲线被高温度曲线完全遮盖② 纵坐标跨度达 $10^{10}$ 以上线性坐标无法同时显示峰值与长波尾部③ 缺乏物理标注如维恩线、可见光区间使图像失去解释力。3.1 用semilogy实现纵轴对数刻度并手动设置YLim避免自动裁剪figure(Position, [100, 100, 900, 600]); hold on; T_list [300, 1000, 3000, 5800, 10000]; % 开尔文 colors lines(length(T_list)); % 自动配色 for i 1:length(T_list) T T_list(i); % 重用前述计算逻辑此处省略重复代码实际需封装为函数 lambda logspace(log10(2.897771955e-3/T*1e-2), ... log10(2.897771955e-3/T*1e2), 2000); x (h*c) ./ (lambda * kB * T); x(x 700) Inf; denominator expm1(x); B_lambda (2*h*c^2) ./ (lambda.^5) ./ denominator; % 绘制横轴用微米纵轴用对数 plot(lambda*1e6, B_lambda, Color, colors(i,:), LineWidth, 1.4); end xlabel(波长 \lambda (\mum), FontSize, 12); ylabel(光谱辐亮度 B_\lambda (W·sr^{-1}·m^{-3}), FontSize, 12); title(黑体辐射谱不同温度下的普朗克线族, FontSize, 14, FontWeight, bold); % 设置 y 轴为对数并限定显示范围避免极小值淹没 set(gca, YScale, log); ylim([1e4, 1e14]); % 根据 T_list 动态调整此处覆盖全部曲线 % 添加图例温度值带单位 legend_str arrayfun((t) sprintf(%d K, t), T_list, UniformOutput, false); legend(legend_str, Location, southwest, FontSize, 10);3.2 标注物理参考线可见光区间0.38–0.78 μm与维恩位移线单纯曲线不够必须嵌入物理语境% 标注可见光波段灰色半透明矩形 fill([0.38, 0.38, 0.78, 0.78], ylim, [0.9, 0.9, 0.9], FaceAlpha, 0.2, EdgeColor, none); text(0.5, ylim(2)*0.8, 可见光, HorizontalAlignment, center, FontSize, 10); % 绘制维恩位移线λ_max b/T用虚线连接各温度峰值 lambda_ve 2.897771955e-3 ./ T_list; % 单位m → μm plot(lambda_ve*1e6, zeros(size(lambda_ve)) ylim(1)*1.5, k--o, MarkerSize, 4, LineWidth, 1); text(lambda_ve(1)*1e6, ylim(1)*1.8, \leftarrow 维恩位移线, FontSize, 9); % 添加网格提升可读性 grid on; box on;3.3 解决长波端噪声用smoothdata抑制数值积分残留振荡由于logspace在长波端采样稀疏且expm1在 $x \ll 1$ 时仍有微小波动B_lambda末尾可能出现高频抖动。这不是物理现象而是数值误差% 对每条曲线末尾 30% 数据做移动平均平滑仅视觉优化不影响峰值 n_smooth floor(0.3 * length(lambda)); B_lambda_smooth smoothdata(B_lambda, movmean, n_smooth); plot(lambda*1e6, B_lambda_smooth, Color, colors(i,:), LineWidth, 1.4);注意平滑仅用于绘图不可用于后续数值积分或拟合。若需高精度积分应改用quadgk或增加采样密度。4. 导出高保真矢量图与批量处理EPS/PDF 兼容性设置及多温度数据导出技巧科研论文、技术报告对图像质量要求严苛字体必须嵌入、线条不能锯齿、坐标轴标签需 LaTeX 渲染。MATLAB 默认print命令导出的 EPS 常出现字体缺失或符号错位根源在于未指定Renderer和FontEmbedding。4.1 导出无损 EPS/PDF绕过 OpenGL 渲染器强制使用 Painters% 关键设置禁用硬件加速启用矢量渲染 set(gcf, Renderer, painters); % 必须否则 EPS 文字变方块 set(gcf, PaperPositionMode, auto); % 导出 EPS兼容 LaTeX \includegraphics print(-depsc2, -r600, planck_spectrum.eps); % 导出 PDF现代期刊首选 print(-dpdf, -r600, planck_spectrum.pdf);提示-r600指定 600 dpi 光栅化分辨率仅对含图像元素的图生效对于纯矢量图如本例该参数不影响线条质量但能确保图例阴影、渐变等效果正确。若导出后文字模糊请检查系统是否安装了对应字体推荐使用Helvetica或Computer Modern。4.2 批量生成多温度数据文件.mat与.csv双格式导出便于后续用 Python 或 Origin 二次分析% 将所有温度对应的 lambda 和 B_lambda 存入结构体 data_struct.T T_list; data_struct.lambda_um lambda * 1e6; % 波长μm data_struct.B_lambda zeros(length(T_list), length(lambda)); for i 1:length(T_list) % ...同上循环内计算 B_lambda data_struct.B_lambda(i, :) B_lambda; end % 导出为 .matMATLAB 原生保留双精度 save(planck_data.mat, data_struct); % 导出为 .csv首行为波长后续每行一个温度的 B_lambda csv_data [data_struct.lambda_um; data_struct.B_lambda]; writematrix(csv_data, planck_data.csv, Delimiter, ,);4.3 一行命令验证导出文件用readmatrix快速回读并重绘% 验证 csv 是否可逆 csv_check readmatrix(planck_data.csv); lambda_check csv_check(1, :); % 第一行是波长 B_check csv_check(2:end, :); % 后续是各温度数据 % 重绘第一条曲线300 K figure; semilogy(lambda_check, B_check(1, :), b-, LineWidth, 1.5); xlabel(\lambda (\mum)); ylabel(B_\lambda (W·sr^{-1}·m^{-3})); title(CSV 回读验证300 K 黑体谱);运行后应与原始图完全一致。若出现跳变或截断说明writematrix默认精度不足需改用writematrix(csv_data, planck_data.csv, Delimiter, ,, Precision, 15);5. 进阶技巧用fplot替代离散采样实现解析式动态绘图与交互式温度调节前述方法基于离散网格适合批量计算但若需实时探索如教学演示、参数敏感性分析fplot提供符号化绘图能力——它自动选择采样点避开奇点并支持回调更新。5.1 定义符号普朗克函数并用fplot绘制syms lambda_real % 符号变量单位米 T_sym 5800; % 符号温度 % 构建符号表达式注意所有常数必须用 sym() 转换 h_sym sym(6.62607015e-34); c_sym sym(2.99792458e8); kB_sym sym(1.380649e-23); x_sym (h_sym * c_sym) / (lambda_real * kB_sym * T_sym); B_sym (2 * h_sym * c_sym^2) / (lambda_real^5) / (exp(x_sym) - 1); % fplot 自动处理奇点lambda→0并优化采样 figure; fplot(B_sym, [1e-7, 3e-5], LineWidth, 1.6); % 0.1–30 μm xlabel(\lambda (m)); ylabel(B_\lambda (W·sr^{-1}·m^{-3})); title(符号普朗克函数fplot 自适应绘图);5.2 构建交互式滑块拖动实时更新曲线% 创建 UI需 R2019a fig uifigure(Name, 普朗克线交互演示); ax uiaxes(fig); ax.XScale log; ax.YScale log; % 初始温度滑块 slider uislider(fig, Limits, [300, 10000], Value, 5800); label uilabel(fig, Text, 温度: 5800 K, Position, [20, 40, 120, 22]); % 绘制初始曲线 [lambda_init, B_init] compute_planck_curve(5800); plot(ax, lambda_init*1e6, B_init, LineWidth, 1.8); % 滑块回调 slider.ValueChangedFcn (src,~) update_plot(src.Value, ax, label); function update_plot(T_val, ax_handle, label_handle) [lambda_new, B_new] compute_planck_curve(T_val); plot(ax_handle, lambda_new*1e6, B_new, LineWidth, 1.8); label_handle.Text sprintf(温度: %.0f K, T_val); ax_handle.YLim [1e4, 1e14]; end % 将 compute_planck_curve 封装为独立函数含前述全部数值逻辑 function [lambda_out, B_out] compute_planck_curve(T) h 6.62607015e-34; c 2.99792458e8; kB 1.380649e-23; lambda_min 2.897771955e-3/T * 1e-2; lambda_max 2.897771955e-3/T * 1e2; lambda_out logspace(log10(lambda_min), log10(lambda_max), 2000); x (h*c) ./ (lambda_out * kB * T); x(x 700) Inf; B_out (2*h*c^2) ./ (lambda_out.^5) ./ expm1(x); end运行后将弹出带滑块的窗口拖动即可实时看到峰值移动、曲线展宽、总辐射增强——这是理解“温度升高使辐射向短波迁移”最直观的方式。本文还有配套的精品资源点击获取