用Python模拟偏振光实验:从马吕斯定律到波片可视化(附完整代码)
·
用Python模拟偏振光实验:从马吕斯定律到波片可视化(附完整代码)
偏振光是光学中一个既基础又充满魅力的现象。对于程序员和科技爱好者来说,用代码模拟物理实验不仅能加深理解,还能获得直观的可视化效果。本文将带你用Python构建完整的偏振光模拟系统,涵盖从基础的马吕斯定律验证到复杂的波片效应分析。
1. 环境准备与基础概念
在开始编码前,我们需要配置Python环境和理解关键物理概念。推荐使用Anaconda创建独立环境:
conda create -n polarization python=3.9
conda activate polarization
pip install numpy matplotlib scipy
偏振光的核心参数 可以用一个二维向量表示:
- 电场强度E_x = E_0 * cos(θ)
- 电场强度E_y = E_0 * sin(θ)
偏振片的作用相当于一个投影算子。当偏振光通过偏振化方向为φ的偏振片时,输出光强遵循马吕斯定律:
I = I₀ * cos²(φ - θ)
提示:在模拟中,我们将自然光视为大量随机偏振方向的光的叠加,其通过偏振片后的强度恒为入射强度的一半。
2. 马吕斯定律的数值验证
让我们先用代码验证这个基本定律。创建一个 Polarizer 类来模拟偏振片行为:
import numpy as np
import matplotlib.pyplot as plt
class Polarizer:
def __init__(self, angle=0):
self.angle = np.radians(angle)
def apply(self, E_in, wavelength=550e-9):
# 投影矩阵
P = np.array([
[np.cos(self.angle)**2, np.sin(self.angle)*np.cos(self.angle)],
[np.sin(self.angle)*np.cos(self.angle), np.sin(self.angle)**2]
])
return P @ E_in
验证马吕斯定律的实验模拟:
def verify_malus_law():
angles = np.linspace(0, 180, 100)
I0 = 1.0 # 初始强度
theta = 45 # 入射偏振方向
results = []
for phi in angles:
polarizer = Polarizer(phi)
E_in = np.array([I0*np.cos(np.radians(theta)),
I0*np.sin(np.radians(theta))])
E_out = polarizer.apply(E_in)
intensity = np.sum(E_out**2)
results.append(intensity)
plt.figure(figsize=(10,6))
plt.plot(angles, results, 'b-', label='模拟结果')
plt.plot(angles, I0*np.cos(np.radians(angles - theta))**2, 'r--',
label='理论预测')
plt.xlabel('检偏器角度(度)')
plt.ylabel('相对光强')
plt.legend()
plt.title('马吕斯定律验证')
plt.grid(True)
plt.show()
运行后会得到光强随角度变化的完美余弦平方曲线,这是偏振光学最基础的规律。
3. 波片系统的建模与实现
波片的模拟比偏振片复杂,因为它会引入相位延迟。我们需要建立Jones矩阵来表示各种波片:
| 波片类型 | Jones矩阵 | 相位延迟 |
|---|---|---|
| 1/4波片 | [[1,0],[0,i]] | π/2 |
| 1/2波片 | [[1,0],[0,-1]] | π |
class WavePlate:
def __init__(self, delta, angle=0):
self.delta = delta # 相位延迟量
self.angle = np.radians(angle) # 快轴角度
def jones_matrix(self):
c, s = np.cos(self.angle), np.sin(self.angle)
R = np.array([[c, -s], [s, c]]) # 旋转矩阵
J = np.array([[1, 0], [0, np.exp(1j*self.delta)]]) # Jones矩阵
return R @ J @ R.T # 相似变换
完整的偏振系统模拟流程:
- 定义入射光偏振状态
- 依次应用各光学元件(偏振片、波片)的Jones矩阵
- 计算输出光强和偏振态
- 可视化结果
4. 动态可视化与交互设计
为了让模拟更加直观,我们创建交互式可视化:
from ipywidgets import interact, FloatSlider
def interactive_simulation(incident_angle=0, polarizer_angle=0,
qwp_angle=0, hwp_angle=0):
# 初始化光学元件
polarizer = Polarizer(polarizer_angle)
qwp = WavePlate(np.pi/2, qwp_angle) # 1/4波片
hwp = WavePlate(np.pi, hwp_angle) # 1/2波片
# 入射光 (线偏振)
E_in = np.array([np.cos(np.radians(incident_angle)),
np.sin(np.radians(incident_angle))])
# 通过光学系统
E_p = polarizer.apply(E_in)
E_qwp = qwp.jones_matrix() @ E_p
E_hwp = hwp.jones_matrix() @ E_qwp
# 可视化...
典型模拟结果分析:
-
1/4波片效应 :
- 当入射偏振方向与快轴成45°时,产生圆偏振光
- 其他角度产生椭圆偏振光
- 平行或垂直时保持线偏振
-
1/2波片效应 :
- 总是输出线偏振光
- 偏振方向旋转角度是波片旋转角度的两倍
常见问题解决方案:
报错:复数结果无法直接可视化
- 解决方法:计算光强时取模的平方
np.abs(E_out)**2
现象:模拟结果与理论预测存在偏差
- 检查点:
- 角度单位是否统一(度 vs 弧度)
- 矩阵乘法顺序是否正确
- 相位延迟量是否准确
5. 高级应用与扩展
将上述系统封装成完整的光学模拟类:
class PolarizationSystem:
def __init__(self):
self.components = []
def add_component(self, component):
self.components.append(component)
def propagate(self, E_in):
E = E_in
for comp in self.components:
if isinstance(comp, Polarizer):
E = comp.apply(E)
else: # WavePlate
E = comp.jones_matrix() @ E
return E
扩展功能建议:
- 添加偏振态可视化(邦加球表示)
- 模拟部分偏振光和自然光
- 实现多波长模拟(色散效应)
- 构建GUI界面替代命令行
实际项目中的经验技巧:
- 使用
@进行矩阵乘法比np.dot()更直观 - 对于大量角度计算,向量化操作比循环效率更高
- 可视化时使用
plt.quiver()可以直观显示偏振方向 - 保存中间结果有助于调试复杂系统
偏振光模拟不仅具有教学价值,在光学设计、VR/AR设备测试等领域都有实际应用。通过调整参数观察效应,比传统实验更灵活高效。
更多推荐

所有评论(0)