MATLAB运用——计算船舶浮心(切面法)

上一次的运用中,我们计算了水花号的质心。
在这一篇文章中,我们的任务是计算在任意水线下,浪花号的浮心。

问题:

计算浪花号在任意水线下的浮心。

分析

  1. 船舶的浮心就是它排开水的部分的水的质心。所以计算浮心的问题最终还是回归到计算质心上来。
  2. 我们可以利用我们平时计算三维物体体积的积分的方式计算浮心:
    简单的说就是(原谅我的灵魂画图)
    在这里插入图片描述
  • 我们把船切成一个一个平面(紫色的线)
  • 把【平面的面积X区间长度】近似地看作一个区间的排开水的体积(红色区域)
  • 把每个区域的的水的质心算出来(橙色的点)
  • 最后算出整体的质心就是船的浮心了(蓝色的点)

解决过程(完整代码在最后):

构建船体曲线

这次构造船体曲线和以往有些不同:
我们需要使用多项式拟合:原因是我们需要得到拟合图像的确切的公式。
有了这个公式我们才能计算出截面图形(定X变换Y得到Z)
同以前一样:我们把数据导入:
在这里插入图片描述
选择多项式拟合(我选择的是x,y各3次方):
在这里插入图片描述
我们就可以得到图像:
在这里插入图片描述
最关键的是得到拟合的公式:
在这里插入图片描述
我们把这个公式写入matlab里面:我们就可以由x,y得到z了。

function z=caculate(x,y)       
       p00 =       24.74;
       p10 =     -0.7374;
       p01 =  -1.124e-16; 
       p20 =    0.002366; 
       p11 =    1.44e-18; 
       p02 =     0.01779; 
       p30 =  -1.795e-06; 
       p21 =  -3.016e-21; 
       p12 =  -1.137e-05; 
       p03 =  -1.453e-20; 
        z = p00 + p10*x + p01*y + p20*x^2 + p11*x*y + p02*y^2 + p30*x^3 + p21*x^2*y 
                    + p12*x*y^2 + p03*y^3;
end

定义各项数据:(所有代码都是MATLAB下运行)

船体与水的相关:

clear all
boat.L = 400;          %船的长度
boat.W = 100;          %船的宽度
boat.HB = boat.W / 2;  %船的半宽
boat.D = 60;           %船的深度
boat.HD = boat.D / 2;  %船的半宽

max_area = boat.D * boat.W     %沿X轴的切面(Y_Z平面切面)的最大面积
max_volume = max_area * boat.L %立方体的体积
density_water = 28.312;          %水的密度 (千克/立方英尺)
max_mass = max_volume * density_water  %排开水的最大质量

微元相关

dy = 1;   % meters(微元_Y轴)
dz = 1;   % meters(微元_X轴)

mesh.ys = -boat.HB:dy:boat.HB;        % meters  Y轴切片
mesh.zs = -boat.HD:dz:boat.HD;        % meters  Z轴切片

[mesh.ygrid,mesh.zgrid] = meshgrid(mesh.ys,mesh.zs);

total_area = boat.W * boat.D       %平方英尺
mesh.dA = total_area / numel(mesh.ygrid)  %微元面积

浮心相关:

%XMass,YMass,ZMass记录的是每个切片的浮心(2D)
ZMass=[];
XMass=[];
YMass=[];
MMass=[];%每个浮心点的权重(质量)
tot_mass=0;%总质量

切片

%对每个x所对应的点切片:
for i=2 : 11   %对每个x积分
    ZZ=[];%记录该X下的Z轴坐标
    for j=1 : 101 %讨论y从[-60,60]
        t=caculate(i*36,mesh.ys(1,j));
        ZZ=[ZZ t];
    end
    y = mesh.ys;
    figure(i);%绘制不同的图
    
    hull = mesh.zgrid > ZZ%在所计算的Z的值之上的就是船的截面
    redmap = [1,1,1;1,0,0];
    colormap(redmap);
    image(mesh.ys,mesh.zs,flipud(hull),'AlphaData',0.5);

我们就可以得到各个截面的图像了:
在这里插入图片描述
在这里插入图片描述
等等共11个图像

描述水线

   %描述水线 y=kx+d
    d = 0.05; 
    theta = 10;
    y = mesh.ys;
    z = tand(theta) .* y + d;%每个水线对应的方程
	water = mesh.zgrid < z;
	bluemap = [1,1,1; 0,0,1];
    plotMatrix(water,mesh,bluemap);%画出水线

在这里插入图片描述

计算水线和船体的公共面积

%计算水线与切面的公共面积
    sub_region = hull & water;%&位与运算(都是1才得1)
    purplemap = [1,1,1; 1,0,1];
    plotMatrix(sub_region,mesh,purplemap);%绘制图像

运行后得到图像:
在这里插入图片描述
等11个图像

分别计算每个区域的质心(2D)

 %计算浮心2D
    COB = centerOfMass2(sub_region,mesh);
function M = matrixSum(A)
    % matrixSum: returns total of all elements in the matrix
    % A: matrix
    % returns: scalar
    
    % normally sum(m) computes the sums of the columns
    % selecting m(:) flattens the matrix and computes the sum of all elements
    % see https://stackoverflow.com/questions/1721987/what-are-the-ways-to-sum-matrix-elements-in-matlab
    M = sum(A(:));
end

function COM = centerOfMass2(masses,mesh)
    % centerOfMass2: computes center of mass in 2D
    % masses: matrix of masses
    % mesh: structure containing ygrid and zgrid
    % returns: Vector [ycom,zcom]
    M = matrixSum(masses);
    ycom = matrixSum(masses .* mesh.ygrid) / M;
    zcom = matrixSum(masses .* mesh.zgrid) / M;
    COM = [ycom,zcom];
end

再根据2D的质心计算浮心(3D)

ANS=centerOfMass3(XMass,YMass,ZMass,MMass,tot_mass);%计算三维浮心
function ANS=centerOfMass3(XMass,YMass,ZMass,MMass,m)
x=0;
y=0;
z=0;
    for i=1:10
        x=x+XMass(1,i)*MMass(1,i)/m;
        y=y+YMass(1,i)*MMass(1,i)/m;
        z=z+YMass(1,i)*MMass(1,i)/m;
    end
    ANS=[x,y,z];
end

最后得到浪花号在z=tan(10)y+0.05的水线下的浮心是:
在这里插入图片描述

完整代码:(.mlx)

这是用多项式拟合出来的函数图像数据
X = [ 0.000000 36.000000 36.000000 36.000000 36.000000 36.000000 36.000000 36.000000 36.000000 36.000000 36.000000 36.000000 36.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 72.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 108.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 144.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 180.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 216.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 252.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 288.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 324.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 360.000000 396.000000 396.000000 396.000000 396.000000 396.000000 396.000000 396.000000 396.000000 396.000000 396.000000 396.000000 396.000000 432.000000 ];
Y = [ 0.000000 -27.750000 -27.750000 -17.000000 -16.000000 -9.750000 -7.500000 7.500000 9.750000 16.000000 17.000000 27.750000 27.750000 -41.750000 -41.750000 -39.375000 -36.500000 -32.500000 -29.500000 -24.375000 -16.500000 -9.750000 9.750000 16.500000 24.375000 29.500000 32.500000 36.500000 39.375000 41.750000 41.750000 -51.250000 -50.875000 -50.875000 -49.750000 -46.250000 -41.250000 -36.250000 -27.500000 -16.250000 -6.250000 6.250000 16.250000 27.500000 36.250000 41.250000 46.250000 49.750000 50.875000 50.875000 51.250000 -57.250000 -57.250000 -55.250000 -54.000000 -51.875000 -48.625000 -44.125000 -35.250000 -25.500000 -9.250000 9.250000 25.500000 35.250000 44.125000 48.625000 51.875000 54.000000 55.250000 57.250000 57.250000 -59.750000 -58.750000 -56.750000 -56.250000 -56.250000 -53.500000 -51.125000 -41.750000 -27.500000 -14.750000 14.750000 27.500000 41.750000 51.125000 53.500000 56.250000 56.250000 56.750000 58.750000 59.750000 -58.750000 -58.250000 -58.000000 -56.500000 -56.500000 -55.250000 -49.250000 -43.000000 -28.750000 -17.500000 17.500000 28.750000 43.000000 49.250000 55.250000 56.500000 56.500000 58.000000 58.250000 58.750000 -58.500000 -58.500000 -57.250000 -57.000000 -56.750000 -53.875000 -50.000000 -46.500000 -16.250000 -15.250000 15.250000 16.250000 46.500000 50.000000 53.875000 56.750000 57.000000 57.250000 58.500000 58.500000 -55.750000 -55.750000 -55.000000 -54.750000 -53.500000 -49.000000 -43.500000 -33.000000 -19.500000 -10.750000 10.750000 19.500000 33.000000 43.500000 49.000000 53.500000 54.750000 55.000000 55.750000 55.750000 -50.500000 -50.500000 -50.000000 -48.500000 -48.000000 -45.500000 -33.500000 -21.000000 -11.500000 -8.750000 8.750000 11.500000 21.000000 33.500000 45.500000 48.000000 48.500000 50.000000 50.500000 50.500000 -48.000000 -48.000000 -47.500000 -45.875000 -43.000000 -34.000000 -16.875000 -10.500000 -6.500000 -4.500000 4.500000 6.500000 10.500000 16.875000 34.000000 43.000000 45.875000 47.500000 48.000000 48.000000 -42.625000 -41.375000 -41.000000 -41.000000 -33.500000 -11.500000 11.500000 33.500000 41.000000 41.000000 41.375000 42.625000 0.000000 ];
Z = [ 24.000000 24.000000 18.000000 12.000000 6.000000 0.000000 -6.000000 -6.000000 0.000000 6.000000 12.000000 24.000000 18.000000 24.000000 18.000000 12.000000 6.000000 0.000000 -6.000000 -12.000000 -18.000000 -24.000000 -24.000000 -18.000000 -12.000000 -6.000000 0.000000 6.000000 12.000000 24.000000 18.000000 12.000000 18.000000 24.000000 6.000000 0.000000 -6.000000 -12.000000 -18.000000 -24.000000 -30.000000 -30.000000 -24.000000 -18.000000 -12.000000 -6.000000 0.000000 6.000000 18.000000 24.000000 12.000000 24.000000 18.000000 12.000000 6.000000 0.000000 -6.000000 -12.000000 -18.000000 -24.000000 -30.000000 -30.000000 -24.000000 -18.000000 -12.000000 -6.000000 0.000000 6.000000 12.000000 18.000000 24.000000 12.000000 6.000000 0.000000 24.000000 18.000000 -6.000000 -12.000000 -18.000000 -24.000000 -30.000000 -30.000000 -24.000000 -18.000000 -12.000000 -6.000000 18.000000 24.000000 0.000000 6.000000 12.000000 12.000000 6.000000 0.000000 24.000000 18.000000 -6.000000 -12.000000 -18.000000 -24.000000 -30.000000 -30.000000 -24.000000 -18.000000 -12.000000 -6.000000 18.000000 24.000000 0.000000 6.000000 12.000000 24.000000 18.000000 12.000000 6.000000 0.000000 -6.000000 -12.000000 -18.000000 -24.000000 -30.000000 -30.000000 -24.000000 -18.000000 -12.000000 -6.000000 0.000000 6.000000 12.000000 18.000000 24.000000 24.000000 18.000000 12.000000 6.000000 0.000000 -6.000000 -12.000000 -18.000000 -24.000000 -30.000000 -30.000000 -24.000000 -18.000000 -12.000000 -6.000000 0.000000 6.000000 12.000000 18.000000 24.000000 24.000000 18.000000 12.000000 6.000000 0.000000 -6.000000 -12.000000 -18.000000 -24.000000 -30.000000 -30.000000 -24.000000 -18.000000 -12.000000 -6.000000 0.000000 6.000000 12.000000 18.000000 24.000000 24.000000 18.000000 12.000000 6.000000 0.000000 -6.000000 -12.000000 -18.000000 -24.000000 -30.000000 -30.000000 -24.000000 -18.000000 -12.000000 -6.000000 0.000000 6.000000 12.000000 24.000000 18.000000 6.000000 12.000000 24.000000 18.000000 0.000000 -6.000000 -6.000000 0.000000 24.000000 18.000000 12.000000 6.000000 24.000000 ];
[a,b]=createFit(X,Y,Z)
axis('equal');%使得各个坐标轴长度相等
zlim([-40,40]);%限定Z轴范围[-40,40]
计算浮心(单位:英尺):
clear all
boat.L = 400;          %船的长度
boat.W = 100;          %船的宽度
boat.HB = boat.W / 2;  %船的半宽
boat.D = 60;           %船的深度
boat.HD = boat.D / 2;  %船的半宽

max_area = boat.D * boat.W     %沿X轴的切面(Y_Z平面切面)的最大面积
max_volume = max_area * boat.L %立方体的体积
density_water = 28.312;          %水的密度 (千克/立方英尺)
max_mass = max_volume * density_water  %排开水的最大质量
从Y,Z轴切片(取微元):
dy = 1;   % meters(微元_Y轴)
dz = 1;   % meters(微元_X轴)

mesh.ys = -boat.HB:dy:boat.HB;        % meters  Y轴切片
mesh.zs = -boat.HD:dz:boat.HD;        % meters  Z轴切片

[mesh.ygrid,mesh.zgrid] = meshgrid(mesh.ys,mesh.zs);

total_area = boat.W * boat.D       %平方英尺
mesh.dA = total_area / numel(mesh.ygrid)  %微元面积
XMass,YMass,ZMass记录的是每个切片的浮心(2D)
ZMass=[];
XMass=[];
YMass=[];
MMass=[];%每个浮心点的权重(质量)
tot_mass=0;%总质量
对每个x所对应的点切片:
for i=2 : 11   %对每个x积分
    ZZ=[];%记录该X下的Z轴坐标
    for j=1 : 101 %讨论y从[-60,60]
        t=caculate(i*36,mesh.ys(1,j));
        ZZ=[ZZ t];
    end
    y = mesh.ys;
    figure(i);%绘制不同的图
    
    hull = mesh.zgrid > ZZ%在所计算的Z的值之上的就是船的截面
    redmap = [1,1,1;1,0,0];
    colormap(redmap);
    image(mesh.ys,mesh.zs,flipud(hull),'AlphaData',0.5);
    
    %描述水线 y=kx+d
    d = 0.05; 
    theta = 10;
    y = mesh.ys;
    z = tand(theta) .* y + d;%每个水线对应的方程
    
   
    water = mesh.zgrid < z;
    bluemap = [1,1,1; 0,0,1];
    plotMatrix(water,mesh,bluemap);
     %计算水线与切面的公共面积
    
     sub_region = hull & water;%&位与运算(都是1才得1)
    purplemap = [1,1,1; 1,0,1];
    plotMatrix(sub_region,mesh,purplemap);%绘制图像
    
    %计算浮心2D
    COB = centerOfMass2(sub_region,mesh);
    ZMass=[ZMass COB(1,1)];
    YMass=[YMass COB(1,2)];
    XMass=[XMass (i-0.5)*36];
    MMass=[MMass matrixSum(sub_region)];
    tot_mass=tot_mass+matrixSum(sub_region);
end
ANS=centerOfMass3(XMass,YMass,ZMass,MMass,tot_mass);%计算三维浮心
ANS

function ANS=centerOfMass3(XMass,YMass,ZMass,MMass,m)
x=0;
y=0;
z=0;
    for i=1:10
        x=x+XMass(1,i)*MMass(1,i)/m;
        y=y+YMass(1,i)*MMass(1,i)/m;
        z=z+YMass(1,i)*MMass(1,i)/m;
    end
    ANS=[x,y,z];
end

function M = matrixSum(A)
    % matrixSum: returns total of all elements in the matrix
    % A: matrix
    % returns: scalar
    
    % normally sum(m) computes the sums of the columns
    % selecting m(:) flattens the matrix and computes the sum of all elements
    % see https://stackoverflow.com/questions/1721987/what-are-the-ways-to-sum-matrix-elements-in-matlab
    M = sum(A(:));
end

function COM = centerOfMass2(masses,mesh)
    % centerOfMass2: computes center of mass in 2D
    % masses: matrix of masses
    % mesh: structure containing ygrid and zgrid
    % returns: Vector [ycom,zcom]
    M = matrixSum(masses);
    ycom = matrixSum(masses .* mesh.ygrid) / M;
    zcom = matrixSum(masses .* mesh.zgrid) / M;
    COM = [ycom,zcom];
end
function plotMatrix(A,mesh,cmap)
    % plotMatrix: plots a matrix using image
    % A: matrix
    % mesh: srtruct containing ys and zs
    % cmap: Colormap
    colormap(cmap);
    image(mesh.ys,mesh.zs,flipud(A),'AlphaData',0.5);
end

function [fitresult, gof] = createFit(X, Y, Z)
%CREATEFIT(X,Y,Z)
%  Create a fit.
%
%  Data for 'untitled fit 1' fit:
%      X Input : X
%      Y Input : Y
%      Z Output: Z
%  Output:
%      fitresult : a fit object representing the fit.
%      gof : structure with goodness-of fit info.
%
%  另请参阅 FIT, CFIT, SFIT.

%  由 MATLAB 于 12-Mar-2022 16:36:02 自动生成


%% Fit: 'untitled fit 1'.
[xData, yData, zData] = prepareSurfaceData( X, Y, Z );

% Set up fittype and options.
ft = fittype( 'poly33' );

% Fit model to data.
[fitresult, gof] = fit( [xData, yData], zData, ft, 'Normalize', 'on' );

% Plot fit with data.
figure( 'Name', 'untitled fit 1' );
h = plot( fitresult, [xData, yData], zData );
legend( h, 'untitled fit 1', 'Z vs. X, Y', 'Location', 'NorthEast', 'Interpreter', 'none' );
% Label axes
xlabel( 'X', 'Interpreter', 'none' );
ylabel( 'Y', 'Interpreter', 'none' );
zlabel( 'Z', 'Interpreter', 'none' );
grid on
view( 10.1, 31.6 );
end
多项式函数拟合部分:
Linear model Poly33:
     f(x,y) = p00 + p10*x + p01*y + p20*x^2 + p11*x*y + p02*y^2 + p30*x^3 + p21*x^2*y 
                    + p12*x*y^2 + p03*y^3
Coefficients (with 95% confidence bounds):
       p00 =       24.74  (18.55, 30.93)
       p10 =     -0.7374  (-0.8701, -0.6048)
       p01 =  -1.124e-16  (-0.1365, 0.1365)
       p20 =    0.002366  (0.001669, 0.003062)
       p11 =    1.44e-18  (-0.001667, 0.001667)
       p02 =     0.01779  (0.01487, 0.02072)
       p30 =  -1.795e-06  (-2.821e-06, -7.681e-07)
       p21 =  -3.016e-21  (-3.618e-06, 3.618e-06)
       p12 =  -1.137e-05  (-2.312e-05, 3.759e-07)
       p03 =  -1.453e-20  (-3.92e-05, 3.92e-05)
 
function z=caculate(x,y)       
       p00 =       24.74;
       p10 =     -0.7374;
       p01 =  -1.124e-16; 
       p20 =    0.002366; 
       p11 =    1.44e-18; 
       p02 =     0.01779; 
       p30 =  -1.795e-06; 
       p21 =  -3.016e-21; 
       p12 =  -1.137e-05; 
       p03 =  -1.453e-20; 
        z = p00 + p10*x + p01*y + p20*x^2 + p11*x*y + p02*y^2 + p30*x^3 + p21*x^2*y 
                    + p12*x*y^2 + p03*y^3;
end

可待提升的空间:

  1. 多项式拟合可以使用更高的次数,结果会更精确。
  2. 船的切片可以切得更密集一些,这样进度会更高。下面是制造更多切面的代码(C++)
#include<stdio.h>
#include<bits/stdc++.h>
using namespace std;
double XY_Plane[22][12]=//这是船的 XY平面 
{   //Y轴负半轴 
   0,0,0,0,0,0,0,0,0,0,0,0, 
   0,0,	0,	6.25,	9.25,	14.75,	17.5,	15.25,	10.75,	8.75,	4.5,	0,
   0,0,	9.75,	16.25,	25.5,	27.5,	28.75,	16.25,	19.5,	11.5,	6.5,	0,
   0,0,	16.5,	27.5,	35.25,	41.75,	43,	46.5,	33,	21,	10.5,	0,
   0,0,	24.375,	36.25,	44.125,	51.125,	49.25,	50,	43.5,	33.5,	16.875,	0,
   0,7.5,	29.5,	41.25,	48.625,	53.5,	55.25,	53.875,	49,	45.5,	34,	11.5,
   0,9.75,	32.5,	46.25,	51.875,	56.75,	58,	56.75,	53.5,	48,	43,	33.5,//DWL(水平面) XY_Plane[6][N]
   0,16,	36.5,	49.75,	54,	58.75,	58.25,	57,	54.75,	48.5,	45.875,	42.625,
   0,17,	39.375,	51.25,	55.25,	59.75,	58.75,	57.25,	55,	50,	47.5,	41.375,
   0,27.75,	41.75,	50.875,	57.25,	56.25,	56.5,	58.5,	55.75,	50.5,	48,	41,
   0,27.75,	41.75,	50.875,	57.25,	56.25,	56.5,	58.5,	55.75,	50.5,	48,	41,
   0,0,0,0,0,0,0,0,0,0,0,0,//----------------------------------->x轴 XY_Plane[11][N] 
   0,27.75,	41.75,	50.875,	57.25,	56.25,	56.5,	58.5,	55.75,	50.5,	48,	41,
   0,27.75,	41.75,	50.875,	57.25,	56.25,	56.5,	58.5,	55.75,	50.5,	48,	41,
   0,17,	39.375,	51.25,	55.25,	59.75,	58.75,	57.25,	55,	50,	47.5,	41.375,
   0,16,	36.5,	49.75,	54,	58.75,	58.25,	57,	54.75,	48.5,	45.875,	42.625,
   0,9.75,	32.5,	46.25,	51.875,	56.75,	58,	56.75,	53.5,	48,	43,	33.5,//DWL(水平面) XY_Plane[16][N]
   0,7.5,	29.5,	41.25,	48.625,	53.5,	55.25,	53.875,	49,	45.5,	34,	11.5,
   0,0,	24.375,	36.25,	44.125,	51.125,	49.25,	50,	43.5,	33.5,	16.875,	0,
   0,0,	16.5,	27.5,	35.25,	41.75,	43,	46.5,	33,	21,	10.5,	0,
   0,0,	9.75,	16.25,	25.5,	27.5,	28.75,	16.25,	19.5,	11.5,	6.5,	0,
   0,0,	0,	6.25,	9.25,	14.75,	17.5,	15.25,	10.75,	8.75,	4.5,	0,//21
   //Y轴正半轴 
};//每一行代表一个水线 
vector<double> XX,YY,ZZ;//存储算好的X,Y,Z数据  
double Z[22][12];//Z[i][j]表示在第一张图中第i行第j列的点的高度
void Insert_Num(){
   for(int i=1;i<=21;i++){
   	if(i==11)continue;
   	for(int j=1;j<11;j++){
   		if(XY_Plane[i][j]&&XY_Plane[i][j+1]){
   			XX.push_back( (j+0.5)*36);
   			YY.push_back( (XY_Plane[i][j]+XY_Plane[i][j+1])/2 );
   			ZZ.push_back( Z[i][j] );
   		}
   	}
   }
}
int main(){
   //高于DWL 
   for(int i=12,k=4;i<=15;i++,k--){
   	for(int j=1;j<=11;j++){
   		if(XY_Plane[i][j]==0)continue;
   		//Z为正值 
   		Z[i][j]=(k)*6;//Y轴正半轴 
   		Z[22-i][j]=Z[i][j];//Y轴负半轴
   	} 
   }
   //低于DWL
   for(int i=17;i<=21;i++){
   	for(int j=1;j<=11;j++){
   		if(XY_Plane[i][j]==0)continue;
   		//Z为负值 
   		Z[i][j]=-1*(i-16)*6;//Y轴正半轴 
   		Z[22-i][j]=Z[i][j];//Y轴负半轴 
   	}
   }
   //导出数据
   
   for(int j=1;j<=11;j++){//列 
   	for(int i=12;i<=21;i++){//行 
   		if(XY_Plane[i][j]){
   			XX.push_back(j*36);
   			YY.push_back(XY_Plane[i][j]);
   			ZZ.push_back(Z[i][j]);//Y轴正半轴 
   			
   			XX.push_back(j*36);
   			YY.push_back(-XY_Plane[i][j]);
   			ZZ.push_back(Z[i][j]);//Y轴负半轴  
   		}
   	}
   }
   //(0,0,288)最左顶点 
   XX.push_back(0); 
   YY.push_back(0);
   ZZ.push_back(24);
   //最右顶点
   XX.push_back(12*36);
   YY.push_back(0);
   ZZ.push_back(24); 
   
   Insert_Num(); 
   
   	//导出X轴
   printf("X = [ ");
   for(int i=0;i<XX.size();i++){
   	printf("%lf ",XX[i]);
   }
   printf("];\n");
   
   //导出Y轴 
   printf("Y = [ ");
   for(int i=0;i<YY.size();i++){
   	printf("%lf ",YY[i]);
   }
   printf("];\n");
   
   //导出Z轴 
   printf("Z = [ ");
   for(int i=0;i<ZZ.size();i++){
   	printf("%lf ",ZZ[i]);
   }
   printf("];\n");
}
  • 9
    点赞
  • 29
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
以下是一个简单的Matlab船舶六自由度代码示例: ```matlab % 定义常数 g = 9.81; % 重力加速度 rho = 1025; % 海水密度 m = 100000; % 船舶质量 Iz = 20000000; % 船舶绕z轴转动惯量 B = 20; % 船宽 L = 100; % 船长 T = 10; % 船吃水深度 xg = 0; % 质心x坐标 yg = 0; % 质心y坐标 zg = 0; % 质心z坐标 xb = 0; % 浮心x坐标 yb = 0; % 浮心y坐标 zb = 0; % 浮心z坐标 % 定义初值 u0 = 0; % 初始速度 v0 = 0; % 初始横向速度 w0 = 0; % 初始垂向速度 p0 = 0; % 初始横摇速度 q0 = 0; % 初始纵摇速度 r0 = 0; % 初始航向角速度 phi0 = 0; % 初始横摇角 theta0 = 0; % 初始纵摇角 psi0 = 0; % 初始航向角 % 定义时间间隔和模拟时间 dt = 0.1; % 时间间隔 t_end = 100; % 模拟时间 % 初始化状态变量 u = u0; v = v0; w = w0; p = p0; q = q0; r = r0; phi = phi0; theta = theta0; psi = psi0; % 定义控制量 delta = 0; % 舵角 thrust = 0; % 推力 % 循环计算状态变量 for t=0:dt:t_end % 计算水动力力矩 X = 0; % 船舶横向力 Y = 0; % 船舶纵向力 Z = -rho*g*T*B*L; % 船舶垂向力 K = 0; % 船舶横摇力矩 M = 0; % 船舶纵摇力矩 N = 0; % 船舶航向力矩 % 计算控制力矩 K_delta = 0; % 舵面横摇力矩系数 N_delta = 0; % 舵面航向力矩系数 K_thr = 0; % 推力横摇力矩系数 N_thr = 0; % 推力航向力矩系数 K_control = K_delta*delta + K_thr*thrust; N_control = N_delta*delta + N_thr*thrust; % 计算运动方程 u_dot = r*v-q*w-X/m; v_dot = p*w-r*u+Y/m; w_dot = q*u-p*v+Z/m; p_dot = (K-K_control)/Iz; q_dot = (M)/Iz; r_dot = (N-N_control)/Iz; phi_dot = p + tan(theta)*(q*sin(phi)+r*cos(phi)); theta_dot = q*cos(phi)-r*sin(phi); psi_dot = (q*sin(phi)+r*cos(phi))/cos(theta); % 更新状态变量 u = u + u_dot*dt; v = v + v_dot*dt; w = w + w_dot*dt; p = p + p_dot*dt; q = q + q_dot*dt; r = r + r_dot*dt; phi = phi + phi_dot*dt; theta = theta + theta_dot*dt; psi = psi + psi_dot*dt; end ``` 这只是一个简单的示例,实际情况可能更加复杂。具体实现要根据船舶的具体情况和模型来确定。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

go_bananas

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值