在Matlab中模拟一艘船在水波中航行
Simulating a ship sailing in water wave in Matlab
我有一个项目,我必须在其中模拟一艘在水浪中航行的船。我决定通过 3D 曲面图来完成它。我创造了水波,但我在制作应该位于情节中心的船时遇到了麻烦。以下是我的水波模拟代码:
clc; clear all ;
x_l = -20;
x_r = 20;
y_l = -20;
y_r = 20;
ds = 0.5;
A = 1;
k = 1;
dt = 0.05;
w = 1;
x = [x_l:ds:x_r];
y = [y_l:ds:y_r];
[X,Y] = meshgrid(x,y);
for i = 1:100
Z = A*sin(k*Y+(w*i/2));
CO(:,:,1) = 0.3*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
CO(:,:,2) = 0.3*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
CO(:,:,3) = 0.7*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
surf(X,Y,Z,CO);
hold on;
shading interp;
xlim([x_l x_r]);
ylim([y_l y_r]);
zlim([y_l y_r]);
Zc = sqrt(X.^2+Y.^2);
surf(X,Y,Zc);
shading interp;
hold off;
drawnow;
pause(dt);
end
如果我做错了,请指导我正确的方向。
我刚刚制作了一个简单的四边形帆船模型。这也允许我们使用 surf
函数来绘制它。这应该只是一个起点,看看你如何做到这一点。但请记住,这可能不是最好的方法。正如已经提到的评论,MATLAB 确实不是最好的软件,Blender 可能是更好的选择,但我们仍然可以制造一艘漂亮的小船。
第一步是在局部坐标系中创建固定模型。 NaN
s 只是为了分隔飞船的不同组件,否则我们会有额外的四边形连接,例如船体到船帆看起来不合适。 (如果不清楚,就换成任意坐标看看是什么情况。)
然后为了给它一些运动,我们必须合并时间组件。我只是在 y-z 平面中添加了轻微的摇摆运动,并在 z-direction 中添加了一点弹跳,使其看起来像一艘船在波浪中移动。我确保使用的频率 w/2
与您已经用于波浪的频率相同。这对于使船适应随 波浪摇摆很重要。
clc; clear all ;
x_l = -20;
x_r = 20;
y_l = -20;
y_r = 20;
ds = 0.5;
A = 1;
k = 1;
dt = 0.05;
w = 1;
x = [x_l:ds:x_r];
y = [y_l:ds:y_r];
[X,Y] = meshgrid(x,y);
%sailboat
U = 0.7*[0,-1,-1,1,1,0;...%hull
0,0,0,0,0,0; NaN(1,6);...
0,0,NaN,0,0,NaN; %sails
0,-1,NaN,0,0,NaN];
V = 0.7*[3,1,-3,-3,1,3;%hull
1,1,-2,-2,1,1; NaN(1,6);...
3,0,NaN,0,-3,NaN; %sails
3,-1,NaN,0,-3,NaN];
W = 0.7*[1,1,1,1,1,1;%hull
0,0,0,0,0,0; NaN(1,6);...
2,6,NaN,7,2,NaN; %sails
2,2,NaN,2,2,NaN];
H = ones(2,6);
S = ones(3,3);
C = cat(3,[H*0.4;S*1,S*1],[H*0.2;S*0.6,S*0],[H*0;S*0.8,S*0]);
for i = 1:100
clf;
hold on;
Z = A*sin(k*Y+(w*i/2));
CO(:,:,1) = 0.3*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
CO(:,:,2) = 0.3*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
CO(:,:,3) = 0.7*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
surf(X,Y,Z,CO);
xlabel('x'); ylabel('y');
% rocking the boat
angle = 0.5*cos(w*i/2); %control rocking
Vs = V*cos(angle) - W*sin(angle);
Ws = V*sin(angle) + W*cos(angle) + 0.4 + 0.8*cos(w*(i - 0.5 * 2*pi)/2);%control amplitude
surf(U,Vs,Ws,C);
camproj('perspective');
xlim([x_l x_r]);
ylim([y_l y_r]);
zlim([y_l y_r]);
Zc = sqrt(X.^2+Y.^2);
%surf(X,Y,Zc);
%view([-100,20])
az = interp1([1,100],[-30, -120],i);
el = interp1([1,100],[1,30],i);
view([az,el]);
axis([-20,20,-20,20,-20,20]*0.5);
shading interp;
hold off;
drawnow;
pause(dt);
end
编辑:创建这些 "models" 的关键是了解 surf
的工作原理:给定一些矩阵 X,Y,Z
,这些矩阵的每个 2x2 子矩阵定义四边形的顶点。所以这个想法是将我们的模型分解成四边形(并在我们不希望中间有任何四边形的矩阵中添加 NaN
)。查看以下仅显示船体和所涉及四边形的片段。显示的数字表示坐标矩阵U,V,W
中对应点坐标的index。我添加了一个小数字 e
将接缝拉开,以便您可以真正看到四边形。设置为0
看原形:
e = 0.2; %small shift to visualize seams
%sailboat
U = 0.7*[0-e,-1-e,-1-e,1+e,1+e,0+e;...%hull
0-e,0-e,0-e,0+e,0+e,0+e];
V = 0.7*[3+e,1,-3,-3,1,3+e;%hull
1+e,1,-2,-2,1,1+e];
W = 0.7*[1,1,1,1,1,1;%hull
0,0,0,0,0,0];
surf(U,V,W);
axis equal
view([161,30])
hold on
for i=1:2
for j=1:6
text(U(i,j),V(i,j),W(i,j),[num2str(i),',',num2str(j)]); %plot indices of points
end
end
xlabel('U')
ylabel('V')
zlabel('W')
title('i,j refers to the point with coordinates (U(i,j),V(i,j),W(i,j))')
hold off
我有一个项目,我必须在其中模拟一艘在水浪中航行的船。我决定通过 3D 曲面图来完成它。我创造了水波,但我在制作应该位于情节中心的船时遇到了麻烦。以下是我的水波模拟代码:
clc; clear all ;
x_l = -20;
x_r = 20;
y_l = -20;
y_r = 20;
ds = 0.5;
A = 1;
k = 1;
dt = 0.05;
w = 1;
x = [x_l:ds:x_r];
y = [y_l:ds:y_r];
[X,Y] = meshgrid(x,y);
for i = 1:100
Z = A*sin(k*Y+(w*i/2));
CO(:,:,1) = 0.3*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
CO(:,:,2) = 0.3*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
CO(:,:,3) = 0.7*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
surf(X,Y,Z,CO);
hold on;
shading interp;
xlim([x_l x_r]);
ylim([y_l y_r]);
zlim([y_l y_r]);
Zc = sqrt(X.^2+Y.^2);
surf(X,Y,Zc);
shading interp;
hold off;
drawnow;
pause(dt);
end
如果我做错了,请指导我正确的方向。
我刚刚制作了一个简单的四边形帆船模型。这也允许我们使用 surf
函数来绘制它。这应该只是一个起点,看看你如何做到这一点。但请记住,这可能不是最好的方法。正如已经提到的评论,MATLAB 确实不是最好的软件,Blender 可能是更好的选择,但我们仍然可以制造一艘漂亮的小船。
第一步是在局部坐标系中创建固定模型。 NaN
s 只是为了分隔飞船的不同组件,否则我们会有额外的四边形连接,例如船体到船帆看起来不合适。 (如果不清楚,就换成任意坐标看看是什么情况。)
然后为了给它一些运动,我们必须合并时间组件。我只是在 y-z 平面中添加了轻微的摇摆运动,并在 z-direction 中添加了一点弹跳,使其看起来像一艘船在波浪中移动。我确保使用的频率 w/2
与您已经用于波浪的频率相同。这对于使船适应随 波浪摇摆很重要。
clc; clear all ;
x_l = -20;
x_r = 20;
y_l = -20;
y_r = 20;
ds = 0.5;
A = 1;
k = 1;
dt = 0.05;
w = 1;
x = [x_l:ds:x_r];
y = [y_l:ds:y_r];
[X,Y] = meshgrid(x,y);
%sailboat
U = 0.7*[0,-1,-1,1,1,0;...%hull
0,0,0,0,0,0; NaN(1,6);...
0,0,NaN,0,0,NaN; %sails
0,-1,NaN,0,0,NaN];
V = 0.7*[3,1,-3,-3,1,3;%hull
1,1,-2,-2,1,1; NaN(1,6);...
3,0,NaN,0,-3,NaN; %sails
3,-1,NaN,0,-3,NaN];
W = 0.7*[1,1,1,1,1,1;%hull
0,0,0,0,0,0; NaN(1,6);...
2,6,NaN,7,2,NaN; %sails
2,2,NaN,2,2,NaN];
H = ones(2,6);
S = ones(3,3);
C = cat(3,[H*0.4;S*1,S*1],[H*0.2;S*0.6,S*0],[H*0;S*0.8,S*0]);
for i = 1:100
clf;
hold on;
Z = A*sin(k*Y+(w*i/2));
CO(:,:,1) = 0.3*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
CO(:,:,2) = 0.3*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
CO(:,:,3) = 0.7*ones((y_r-y_l)/ds + 1) + 0.3*cos(k*Y+(w*i/2));
surf(X,Y,Z,CO);
xlabel('x'); ylabel('y');
% rocking the boat
angle = 0.5*cos(w*i/2); %control rocking
Vs = V*cos(angle) - W*sin(angle);
Ws = V*sin(angle) + W*cos(angle) + 0.4 + 0.8*cos(w*(i - 0.5 * 2*pi)/2);%control amplitude
surf(U,Vs,Ws,C);
camproj('perspective');
xlim([x_l x_r]);
ylim([y_l y_r]);
zlim([y_l y_r]);
Zc = sqrt(X.^2+Y.^2);
%surf(X,Y,Zc);
%view([-100,20])
az = interp1([1,100],[-30, -120],i);
el = interp1([1,100],[1,30],i);
view([az,el]);
axis([-20,20,-20,20,-20,20]*0.5);
shading interp;
hold off;
drawnow;
pause(dt);
end
编辑:创建这些 "models" 的关键是了解 surf
的工作原理:给定一些矩阵 X,Y,Z
,这些矩阵的每个 2x2 子矩阵定义四边形的顶点。所以这个想法是将我们的模型分解成四边形(并在我们不希望中间有任何四边形的矩阵中添加 NaN
)。查看以下仅显示船体和所涉及四边形的片段。显示的数字表示坐标矩阵U,V,W
中对应点坐标的index。我添加了一个小数字 e
将接缝拉开,以便您可以真正看到四边形。设置为0
看原形:
e = 0.2; %small shift to visualize seams
%sailboat
U = 0.7*[0-e,-1-e,-1-e,1+e,1+e,0+e;...%hull
0-e,0-e,0-e,0+e,0+e,0+e];
V = 0.7*[3+e,1,-3,-3,1,3+e;%hull
1+e,1,-2,-2,1,1+e];
W = 0.7*[1,1,1,1,1,1;%hull
0,0,0,0,0,0];
surf(U,V,W);
axis equal
view([161,30])
hold on
for i=1:2
for j=1:6
text(U(i,j),V(i,j),W(i,j),[num2str(i),',',num2str(j)]); %plot indices of points
end
end
xlabel('U')
ylabel('V')
zlabel('W')
title('i,j refers to the point with coordinates (U(i,j),V(i,j),W(i,j))')
hold off