1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
clc; clear; close all;



%% 基本参数设置

lambda_all = [450e-9, 550e-9, 650e-9]; % 多波长:蓝、绿、红

colors = [0 0 1; 0 1 0; 1 0 0]; % RGB颜色

f = 20e-3; % 透镜焦距

R = 100e-3; % 曲率半径(调大,更明显)

lens_z = 0; % 透镜位置

screen_z = 25e-3; % 屏幕位置



num_frames = 50; % 动画帧数

num_rays = 30; % 光线数量

theta = linspace(-pi/12, pi/12, num_rays); % 光线角度



%% 视频设置

v = VideoWriter('newton_rings_full_fixed.avi');

v.FrameRate = 15;

open(v);



%% 设置固定大小的图窗

fig = figure('Color','w', 'Position', [100, 100, 800, 600]);



%% 动画主循环

for t = 1:num_frames



clf;

hold on; axis equal; grid on;

xlabel('X (m)'); ylabel('Y (m)'); zlabel('Z (m)');

xlim([-0.02 0.02]); ylim([-0.02 0.02]); zlim([0 0.03]);

view([0 90]); % 俯视(XY 平面)



title('多波长牛顿环光线传播');



%% 光线追踪(多波长)

for w = 1:length(lambda_all)

lambda = lambda_all(w);

color = colors(w, :);

for i = 1:num_rays

angle = theta(i);

% 初始点和方向

x0 = 0; y0 = 0; z0 = 0;

vx1 = sin(angle); vy1 = 0; vz1 = cos(angle);

t1 = (lens_z - z0) / vz1;

x1 = x0 + vx1 * t1;

y1 = y0 + vy1 * t1;

z1 = lens_z;



% 折射计算

n1 = 1.0; n2 = 1.5;

theta2 = asin(n1/n2 * sin(angle));

vx2 = sin(theta2); vy2 = 0; vz2 = cos(theta2);

t2 = (screen_z - lens_z) / vz2;

x2 = x1 + vx2 * t2;

y2 = y1 + vy2 * t2;

z2 = screen_z;



% 动态比例

scale1 = min(1, t / num_frames);

scale2 = max(0, t/num_frames - 0.5) * 2;



% 绘制第一段(空气中)

xa = x0 + vx1 * t1 * scale1;

ya = y0 + vy1 * t1 * scale1;

za = z0 + vz1 * t1 * scale1;

plot3([x0 xa], [y0 ya], [z0 za], 'Color', color, 'LineWidth', 1.2);



% 绘制第二段(透镜中)

if t > num_frames/2

xb = x1 + vx2 * t2 * scale2;

yb = y1 + vy2 * t2 * scale2;

zb = z1 + vz2 * t2 * scale2;

plot3([x1 xb], [y1 yb], [z1 zb], 'Color', color * 0.8 + 0.2, ...

'LineStyle','--', 'LineWidth', 1);

end

end

end



%% 牛顿环绘制(增强可视化)

num_rings = 20;

for w = 1:length(lambda_all)

lambda = lambda_all(w);

color = colors(w,:);

bright_color = color * 0.8 + 0.2; % 提亮颜色

for n = 1:num_rings

r_n = sqrt(n * lambda * R); % Newton ring 半径

theta_ring = linspace(0, 2*pi, 200);

x_ring = r_n * cos(theta_ring);

y_ring = r_n * sin(theta_ring);

z_ring = (screen_z + 1e-4) * ones(size(x_ring)); % 抬高,避免遮挡



fill3(x_ring, y_ring, z_ring, bright_color, ...

'FaceAlpha', 0.15 + 0.02*w, ...

'EdgeColor', bright_color * 0.9, 'LineWidth', 0.5);

end

end



%% 写入帧,强制统一为 800x600 尺寸

raw_frame = getframe(fig);

resized_frame = imresize(raw_frame.cdata, [600 800]); % 高度 × 宽度

writeVideo(v, im2frame(resized_frame));

end



close(v);

img

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
clc; clear; close all;



%% 基本参数设置

lambda = 550e-9; % 单色光:绿光

color = [1 1 1]; % 白色光线

f = 20e-3; % 透镜焦距

R = 10e-3; % 曲率半径

lens_z = 0; % 透镜位置

screen_z = 25e-3; % 屏幕位置



num_frames = 50; % 动画帧数

num_rays = 30; % 光线数量

theta = linspace(-pi/12, pi/12, num_rays); % 光线角度



%% 视频设置

v = VideoWriter('newton_rings_white_on_black.avi');

v.FrameRate = 15;

open(v);



%% 设置固定大小的图窗

fig = figure('Color','k', 'Position', [100, 100, 800, 600]);



%% 动画主循环

for t = 1:num_frames

clf;

hold on; axis equal; grid on;

xlabel('X (m)', 'Color', 'w'); ylabel('Y (m)', 'Color', 'w'); zlabel('Z (m)', 'Color', 'w');

xlim([-0.01 0.01]); ylim([-0.01 0.01]); zlim([-0.005 0.03]);

set(gca, 'Color', 'k', 'XColor', 'w', 'YColor', 'w', 'ZColor', 'w');

view(2); % 改为俯视图(更容易看出环)



title('白光牛顿环', 'Color', 'w');



%% 光线追踪

for i = 1:num_rays

angle = theta(i);

x0 = 0; y0 = 0; z0 = -5e-3;

vx1 = sin(angle); vy1 = 0; vz1 = cos(angle);

t1 = (lens_z - z0) / vz1;

x1 = x0 + vx1 * t1;

y1 = y0 + vy1 * t1;

z1 = lens_z;



n1 = 1.0; n2 = 1.5;

theta2 = asin(n1/n2 * sin(angle));

vx2 = sin(theta2); vy2 = 0; vz2 = cos(theta2);

t2 = (screen_z - lens_z) / vz2;

x2 = x1 + vx2 * t2;

y2 = y1 + vy2 * t2;

z2 = screen_z;



scale1 = min(1, t / num_frames);

scale2 = max(0, t/num_frames - 0.5) * 2;



xa = x0 + vx1 * t1 * scale1;

ya = y0 + vy1 * t1 * scale1;

za = z0 + vz1 * t1 * scale1;

plot3([x0 xa], [y0 ya], [z0 za], 'Color', color, 'LineWidth', 1.2);



if t > num_frames/2

xb = x1 + vx2 * t2 * scale2;

yb = y1 + vy2 * t2 * scale2;

zb = z1 + vz2 * t2 * scale2;

plot3([x1 xb], [y1 yb], [z1 zb], 'Color', color * 0.8 + 0.2, ...

'LineStyle','--', 'LineWidth', 1);

end

end



%% 屏幕贴图牛顿环图案(灰度)

[xg, yg] = meshgrid(linspace(-0.002, 0.002, 600)); % 缩小范围

rg = sqrt(xg.^2 + yg.^2);

intensity = cos(pi * rg.^2 / (lambda * R)).^2; % 经典牛顿环表达式

zg = screen_z * ones(size(xg));

surf(xg, yg, zg, intensity, 'EdgeColor', 'none');

colormap(gray);



%% 写入帧

raw_frame = getframe(fig);

resized_frame = imresize(raw_frame.cdata, [600 800]);

writeVideo(v, im2frame(resized_frame));

end



close(v);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
clc; clear; close all;

%% 基本参数设置
lambda = 550e-9; % 中心波长
f = 20e-3; % 透镜焦距
R = 10e-3; % 曲率半径
lens_z = 0; % 透镜位置
screen_z = 25e-3; % 屏幕位置

num_frames = 50; % 动画帧数
num_rays = 30; % 光线数量
theta = linspace(-pi/12, pi/12, num_rays); % 光线角度

%% 视频设置
v = VideoWriter('newton_rings_color_dynamic.avi');
v.FrameRate = 15;
open(v);

%% 设置固定大小的图窗
fig = figure('Color','k', 'Position', [100, 100, 800, 600]);

%% 动画主循环
for t = 1:num_frames
clf;
hold on; axis equal; grid on;
xlabel('X (m)', 'Color', 'w'); ylabel('Y (m)', 'Color', 'w'); zlabel('Z (m)', 'Color', 'w');
xlim([-0.005 0.005]); ylim([-0.005 0.005]); zlim([-0.005 0.03]);
set(gca, 'Color', 'k', 'XColor', 'w', 'YColor', 'w', 'ZColor', 'w');
view(3); % 三维视角

title('彩色动态三维牛顿环', 'Color', 'w');

%% 光线追踪
for i = 1:num_rays
angle = theta(i);
x0 = 0; y0 = 0; z0 = -5e-3;
vx1 = sin(angle); vy1 = 0; vz1 = cos(angle);
t1 = (lens_z - z0) / vz1;
x1 = x0 + vx1 * t1;
y1 = y0 + vy1 * t1;
z1 = lens_z;

n1 = 1.0; n2 = 1.5;
theta2 = asin(n1/n2 * sin(angle));
vx2 = sin(theta2); vy2 = 0; vz2 = cos(theta2);
t2 = (screen_z - lens_z) / vz2;
x2 = x1 + vx2 * t2;
y2 = y1 + vy2 * t2;
z2 = screen_z;

scale1 = min(1, t / num_frames);
scale2 = max(0, t/num_frames - 0.5) * 2;

xa = x0 + vx1 * t1 * scale1;
ya = y0 + vy1 * t1 * scale1;
za = z0 + vz1 * t1 * scale1;
plot3([x0 xa], [y0 ya], [z0 za], 'Color', [1 1 1], 'LineWidth', 1.2);

if t > num_frames/2
xb = x1 + vx2 * t2 * scale2;
yb = y1 + vy2 * t2 * scale2;
zb = z1 + vz2 * t2 * scale2;
plot3([x1 xb], [y1 yb], [z1 zb], 'Color', [1 1 1]*0.8, ...
'LineStyle','--', 'LineWidth', 1);
end
end

%% 彩色动态干涉牛顿环(模拟RGB三波段)
[xg, yg] = meshgrid(linspace(-0.002, 0.002, 400));
rg = sqrt(xg.^2 + yg.^2);
zg = screen_z + 0.0002 * sin(2*pi*t/num_frames) * sin(50 * rg); % 三维起伏
lambda_rgb = [620e-9, 550e-9, 470e-9]; % R G B
img = zeros([size(xg), 3]);

for k = 1:3
phase = pi * rg.^2 / (lambda_rgb(k) * R) + 2*pi*t/num_frames;
img(:,:,k) = 0.5 + 0.5 * cos(phase).^2;
end

surf(xg, yg, zg, img, 'EdgeColor', 'none');

%% 可视化透镜
[X,Y,Z] = cylinder(linspace(0.001, 0.01, 50), 60);
Z = -Z * 1e-3 + 0.5e-3;
surf(X, Y, Z + lens_z, 'FaceAlpha', 0.3, 'EdgeColor', 'none', ...
'FaceColor', [0.3 0.6 1]);

%% 写入帧
raw_frame = getframe(fig);
resized_frame = imresize(raw_frame.cdata, [600 800]);
writeVideo(v, im2frame(resized_frame));
end

close(v);