1

I have a project in which I have to simulate a ship which is sailing in a water wave. I have decided to do it in by 3D surface plot. I have created water waves but I'm having trouble making the ship which should sit right at the centre of the plot. Following is my water wave simulation code:

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

Please guide me in the right direction if I'm doing this in the wrong way.

Vishal Gupta
  • 57
  • 1
  • 6
  • Are you simulating or rendering an animation? The former doesn’t necessarily involve graphics, and MATLAB (especially Simulink) is very good for it. The latter is better done in software designed for it, maybe Blender. Simulation involves calculating through all the physics equations that govern motion, to determine how the ship behaves when exposed to waves and wind and so on. – Cris Luengo Feb 23 '19 at 15:10
  • next fun project, when you have a good grip on how to render/locate the boat, make it float on [these waves](https://stackoverflow.com/a/28289263/3460361) ;-) – Hoki Apr 18 '19 at 16:05

1 Answers1

5

I just made a simple model of a sailing boat that is made up of quads. This allows us to use the surf function to draw it too. This should just serve as a starting point to see how you could do it. But keep in mind that this is probably not the best way of doing it. As a comment already mentioned, MATLAB is really not the best software for this, Blender is probably a way better option, but still we can make a nice little ship.

The first step is creating the fixed model in a local coordinate system. The NaNs are just to separate the different components of the ship, because otherwise we would have additional quads connecting e.g. the hull to the sails that would look out of place. (If it is unclear, just replace them with some arbitrary coordinates to see what is happening.)

Then to give it some movement, we have to incorporate the temporal component. I just added a slight rocking motion in the y-z plane as well as a little bouncing in the z-direction to give it the look of a ship moving through waves. I made sure to use the same frequency w/2 as you already used for the waves. This is important to make the boat to apper to rock with the waves.

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

EDIT: The key to creating these "models" is knowign how surf works: Given some matrices X,Y,Z, each 2x2 submatrix of these matrices define the vertices of a quadrilateral. So the idea is decomposing our models into quadrilaterals (and adding NaN in this matrix where we do not want any quadrilaterals in between). Check out following snippet that shows just the hull and the quadrilaterals involved. The displayed numbers show the index of the coordinates of the corresponding points in the coordinate matrices U,V,W. I added a small number e that pulls the seams apart so that you can actually see the quadrilaterals. Set it to 0 to see the original shape:

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

flawr
  • 10,814
  • 3
  • 41
  • 71
  • Can you please tell me how the ship is created. I want to make a proper ship hull. I'm just not getting how you plotted the ship? – Vishal Gupta Apr 18 '19 at 06:34