在Matlab中模拟在水浪中航行的船

时间:2019-02-23 05:01:21

标签: matlab plot simulation surface

我有一个项目,其中我必须模拟一艘在水浪中航行的船。我决定通过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

如果我以错误的方式这样做,请以正确的方向引导我。

1 个答案:

答案 0 :(得分:3)

我刚刚制作了一个由四边形组成的帆船的简单模型。这使我们也可以使用surf函数来绘制它。这只是作为了解如何实现的起点。但是请记住,这可能不是最佳方法。正如已经提到的评论,MATLAB实际上并不是最好的软件,Blender可能是一个更好的选择,但我们仍然可以制造出不错的飞船。

第一步是在局部坐标系中创建固定模型。 NaN仅用于分隔船的不同组件,因为否则我们将有其他四边形连接,例如船帆的船体看上去会不合适。 (如果不清楚,只需用一些任意坐标替换它们,以查看发生了什么。)

然后要使其运动,我们必须合并时间分量。我只是在y-z平面上添加了轻微的摇摆运动,并在z方向上添加了一些弹跳,使它看起来像一艘船在波浪中移动。我确保使用与您已经用于波浪的频率w/2相同的频率。这对于使船只随波摆动 至关重要。

row, row, row your boat...

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

编辑:创建这些“模型”的关键是了解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

hull construction