用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  # 相似变换

完整的偏振系统模拟流程:

  1. 定义入射光偏振状态
  2. 依次应用各光学元件(偏振片、波片)的Jones矩阵
  3. 计算输出光强和偏振态
  4. 可视化结果

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. 1/4波片效应

    • 当入射偏振方向与快轴成45°时,产生圆偏振光
    • 其他角度产生椭圆偏振光
    • 平行或垂直时保持线偏振
  2. 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

扩展功能建议:

  1. 添加偏振态可视化(邦加球表示)
  2. 模拟部分偏振光和自然光
  3. 实现多波长模拟(色散效应)
  4. 构建GUI界面替代命令行

实际项目中的经验技巧:

  • 使用 @ 进行矩阵乘法比 np.dot() 更直观
  • 对于大量角度计算,向量化操作比循环效率更高
  • 可视化时使用 plt.quiver() 可以直观显示偏振方向
  • 保存中间结果有助于调试复杂系统

偏振光模拟不仅具有教学价值,在光学设计、VR/AR设备测试等领域都有实际应用。通过调整参数观察效应,比传统实验更灵活高效。

更多推荐