Matlab 辊间乳化液裂开

Matlab 辊间乳化液裂开,matlab,Matlab,以下是一个真正的简化: 我有许多相互连接的滚筒,最初其中一个上面有墨水,它们彼此相对旋转。当滚筒旋转时,油墨在滚筒之间以50/50的比例共享。有些滚筒有不止一个连接,因此油墨分裂发生的顺序很重要。下面是一个可视化: 我基本上是在寻找允许程序按顺序遍历连接的东西。 我的想法是: for each roller if number_of_connections > 2 % # more than one connection for roller % # Itera

以下是一个真正的简化:

我有许多相互连接的滚筒,最初其中一个上面有墨水,它们彼此相对旋转。当滚筒旋转时,油墨在滚筒之间以50/50的比例共享。有些滚筒有不止一个连接,因此油墨分裂发生的顺序很重要。下面是一个可视化:

我基本上是在寻找允许程序按顺序遍历连接的东西。 我的想法是:

for each roller
    if number_of_connections > 2  % # more than one connection for roller
        % # Iterate through connections sequentially, depending on the direction
        % # of rotation
    end
end

这实际上是一个评论,而不是一个答案

你和EitanT所采用的方法似乎是一个有趣的数学问题,可以转化为计算机代码。但我有点怀疑你的数学模型能否准确预测真实物理系统的行为。我能想到的一些问题:

  • 您将讨论应用墨水拆分的顺序。这种方式对于初次通过系统是有意义的,但是一旦所有的辊子都有了墨水,我就不清楚是否有合理的“顺序”来迭代通过辊子。如果一开始不止一个滚筒有墨水,那么即使是第一次,也没有意义
  • 较小的滚轴比较大的滚轴转动得更快,因此,使算法的一次迭代对应于所有滚轴的一次旋转并不能真正起作用
  • 油墨在滚筒之间不断扩散,因此每个滚筒上的油墨高度取决于滚筒上的位置
  • 换句话说,在物理系统中有很多你似乎忽略的复杂性。也许这是可以的,这种方法抓住了90%重要的东西。那会让我吃惊的。。。但也有意思的是,如此复杂的系统可以如此容易地建模

    添加:

    我刚刚意识到,在你关于这个话题的另一个问题中,你在滚筒间循环的顺序并不重要。因此,“分割顺序”在这里可能是一条红鲱鱼


    我也相信,你可以从一个简单的矩阵乘法中得到结果,但还没有尝试出相关的矩阵。但这可能很容易弄明白

    我一直在想,对于这个问题,您最终会得到什么样的解决方案。根据您的评论:

    我现在的想法是在其中一个滚轮上有一个固定的分段分辨率(可能是最大的),而所有其他滚轮上的分段分辨率应该是该分辨率的相对整数比,以便分段在系统旋转时匹配

    看起来您目前正在开发一个与我这里的解决方案类型相同的解决方案

    注意:末尾有一个便于复制的版本

    首先,我使用了EitanT在回答前一个问题时使用的结构

    % # Initial state
    C = [0, 0;   % # Roller centers (x, y)
         2, 0;
         2, 4;
         2,-5;
         8, 4;
         8,-5;
         8,-1];
    R = [1,1,3,4,3,2,2];    % # Roller radii (r)
    N = numel(R);           % # Amount of rollers
    
    % # Draw the rollers
    figure, hold on
    ang = 0:0.1:(2 * pi);
    for i = 1:N
        plot(C(i, 1) + R(i) * cos(ang), C(i, 2) + R(i) * sin(ang))
        text(C(i, 1), C(i, 2), num2str(i))
    end
    title('Ink rollers'), axis image
    
    % # Find connected rollers
    isconn = @(m, n)(sum(([1, -1] * C([m, n], :)) .^ 2) - sum(R([m, n])) .^ 2 < eps);
    [Y, X] = meshgrid(1:N, 1:N);
    conn = reshape(arrayfun(isconn, X(:), Y(:)), N, N) - eye(N);
    
    然后,我为最小的滚筒指定箱子的数量,并放大所有其他滚筒的箱子

    % # Number of bins specified for smallest roller
    nBins_min = 20;
    nBins = round(nBins_min*R/min(R));
    
    下一步是初始化滚轮。我在同一个变量中使用了struct来保存墨水、连接和滚筒方向。这样做的目的是保持油墨的价值,并跟踪所有滚筒的每个部分的连接情况。如果压路机
    ii
    的一段
    jj
    未连接到另一个压路机,则表示为
    压路机(ii).连接(jj)
    。否则,如果已连接,此单元格元素将包含其连接到的滚轮的滚轮索引

    % # Initialize roller struct
    rollers = struct('ink',{},'connections',{},'rotDirection',{});
    
    % # Ink
    for ii = 1:N
        rollers(ii).ink = zeros(1,nBins(ii));
    end
    rollers(1).ink = ones(1,nBins(1));
    
    % # Connections
    for ii = 1:N
        rollers(ii).connections = zeros(1,nBins(ii));
    end
    for ii = 1:N
        for jj = 1:N
            if(ii~=jj)
                if(conn(ii,jj) == 1)
                    connInd = getConnectionIndex(C,ii,jj,nBins(ii));
                    rollers(ii).connections(connInd) = jj;
                end
            end
        end
    end
    
    % # Direction of rotation
    for ii = 1:N
        rollers(ii).rotDirection = rotDir(ii);
    end
    
    我以以下(非常丑陋)的方式实现了上面使用的函数
    getConnectionIndex()

    对每个时间步骤执行以下步骤

    % # Iterate through timesteps
    for tt = 2:nTimeSteps
    
    第一个滚筒充满墨水,所有滚筒根据其旋转方向旋转一步

    % # Fill first roller with ink
    rollers(1).ink = ones(1,nBins(1));
    
    % # Rotate all rollers
    for ii = 1:N
            rollers(ii).ink(:) = ...
                circshift(rollers(ii).ink(:),rollers(ii).rotDirection);
    end
    
    然后,通过找到匹配的连接并将这两个连接的墨水平均分配来更新所有的滚筒连接

    % # Update all roller-connections
    for ii = 1:N
        for jj = 1:nBins(ii)
            if(rollers(ii).connections(jj) ~= 0)
                index1 = rollers(ii).connections(jj);
                index2 = find(ii == rollers(index1).connections);
                ink1 = rollers(ii).ink(jj);
                ink2 = rollers(index1).ink(index2);
                rollers(ii).ink(jj) = (ink1+ink2)/2;
                rollers(index1).ink(index2) = (ink1+ink2)/2;
            end
        end
    end
    
    作为最后一步,计算滚筒上的平均墨水量,并在循环完成后绘制这些值

        % # Calculate average amount of ink on each roller
        for ii = 1:N
            averageAmountOfInk(tt,ii) = mean(rollers(ii).ink);
        end
    end
    
    figure
    plot(averageAmountOfInk,'b')
    xlabel('Timesteps')
    ylabel('Ink')
    
    运行该代码,它将生成以下所有滚筒的平均墨水量图

    对于最小滚轮的20段和60个时间步,我们得到下图:

    如果我们运行2000个时间步的模拟,我们可以看到当所有的滚筒充满墨水时,向一个方向收敛

    易于复制的版本:

    function averageAmountOfInk = inkRollerModel()
    % # Initial state
    C = [0, 0;   % # Roller centers (x, y)
         2, 0;
         2, 4;
         2,-5;
         8, 4;
         8,-5;
         8,-1];
    R = [1,1,3,4,3,2,2];    % # Roller radii (r)
    N = numel(R);           % # Amount of rollers
    
    % # Draw the rollers
    figure, hold on
    ang = 0:0.1:(2 * pi);
    for i = 1:N
        plot(C(i, 1) + R(i) * cos(ang), C(i, 2) + R(i) * sin(ang))
        text(C(i, 1), C(i, 2), num2str(i))
    end
    title('Ink rollers'), axis image
    
    % # Find connected rollers
    isconn = @(m, n)(sum(([1, -1] * C([m, n], :)) .^ 2) - sum(R([m, n])) .^ 2 < eps);
    [Y, X] = meshgrid(1:N, 1:N);
    conn = reshape(arrayfun(isconn, X(:), Y(:)), N, N) - eye(N);
    
    % # Direction of rotation (clockwise = -1, anticlockwise = 1)
    rotDir = [1,-1,1,1,-1,-1,1];
    
    % # Number of bins for smallest roller
    nBins_min = 20;
    nBins = round(nBins_min*R/min(R));
    
    % # Initialize roller struct
    rollers = struct('ink',{},'connections',{},'rotDirection',{});
    
    % # Ink
    for ii = 1:N
        rollers(ii).ink = zeros(1,nBins(ii));
    end
    rollers(1).ink = ones(1,nBins(1));
    
    % # Connections
    for ii = 1:N
        rollers(ii).connections = zeros(1,nBins(ii));
    end
    for ii = 1:N
        for jj = 1:N
            if(ii~=jj)
                if(conn(ii,jj) == 1)
                    connInd = getConnectionIndex(C,ii,jj,nBins(ii));
                    rollers(ii).connections(connInd) = jj;
                end
            end
        end
    end
    
    % # Direction of rotation
    for ii = 1:N
        rollers(ii).rotDirection = rotDir(ii);
    end
    
    % # Initialize averageAmountOfInk and calculate initial distribution
    nTimeSteps = 200;
    averageAmountOfInk = zeros(nTimeSteps,N);
    for ii = 1:N
        averageAmountOfInk(1,ii) = mean(rollers(ii).ink);
    end
    
    % # Iterate through timesteps
    for tt = 2:nTimeSteps
        % # Fill first roller with ink
        rollers(1).ink = ones(1,nBins(1));
    
        % # Rotate all rollers
        for ii = 1:N
                rollers(ii).ink(:) = ...
                    circshift(rollers(ii).ink(:),rollers(ii).rotDirection);
        end
    
        % # Update all roller-connections
        for ii = 1:N
            for jj = 1:nBins(ii)
                if(rollers(ii).connections(jj) ~= 0)
                    index1 = rollers(ii).connections(jj);
                    index2 = find(ii == rollers(index1).connections);
                    ink1 = rollers(ii).ink(jj);
                    ink2 = rollers(index1).ink(index2);
                    rollers(ii).ink(jj) = (ink1+ink2)/2;
                    rollers(index1).ink(index2) = (ink1+ink2)/2;
                end
            end
        end
    
        % # Calculate average amount of ink on each roller
        for ii = 1:N
            averageAmountOfInk(tt,ii) = mean(rollers(ii).ink);
        end
    end
    
    figure
    plot(averageAmountOfInk,'b')
    xlabel('Timesteps')
    ylabel('Ink')
    
    end
    
    function connectionIndex = getConnectionIndex(C,ii,jj,nBins)
    
    p1 = C(ii, :);
    p2 = C(jj, :);
    
    if(abs(p1(2)-p2(2))<eps)
        if(p2(1)>p1(1))
            angle = 0;
        else
            angle = pi;
        end
    elseif(abs(p1(1)-p2(1))<eps)
        if(p2(2)>p1(2))
            angle = pi/2;
        else
            angle = 3*pi/2;
        end
    else
        angle = mod( atan((p2(1)-p1(1))/(p2(2)-p1(2))), 2*pi);
    end
    
    connectionIndex = 1+floor(nBins*angle/(2*pi));
    
    end
    

    你好您的“顺序”是如何定义的,即当您迭代所有连接时,一个滚轮如何优先于另一个滚轮?早上Eitan,没有优先级,因此,我尝试发布一个图像失败…假设我有一个滚轮在圆周上的不同点连接到其他三个滚轮(即从垂直方向测量,我们有35°、127°、285°),如果这个滚筒是顺时针旋转的,那么我希望程序能够识别出,在有2个以上连接的地方,墨水分离是按顺序进行的。无论有多少个连接,当前的程序都会平均分割墨水。实际上,墨水分割会根据每个滚筒的旋转方向依次发生。实现该程序并不困难(但可能会很乏味)。您应该创建一个带有每个滚轮旋转方向的二进制数组,对于每个滚轮,计算连接滚轮的角度并推导它们的队列顺序。然后修改循环,根据每个滚轮的旋转方向及其相邻队列在每个滚轮上迭代。我会想一想,然后试着想出一个简单而聪明的方法来轻松做到这一点。非常感谢Eitan,我尝试了各种方法(为每个滚轮创建位置矩阵,然后使用更大的旋转矩阵)但我尝试过的一切逻辑上都失败了……您最初提供的代码运行得非常好——在寻求帮助时,我没有考虑到我可能需要更多的功能,因此我知道我找到了自己的位置!谢谢你的帮助解决了你的问题
    % # Update all roller-connections
    for ii = 1:N
        for jj = 1:nBins(ii)
            if(rollers(ii).connections(jj) ~= 0)
                index1 = rollers(ii).connections(jj);
                index2 = find(ii == rollers(index1).connections);
                ink1 = rollers(ii).ink(jj);
                ink2 = rollers(index1).ink(index2);
                rollers(ii).ink(jj) = (ink1+ink2)/2;
                rollers(index1).ink(index2) = (ink1+ink2)/2;
            end
        end
    end
    
        % # Calculate average amount of ink on each roller
        for ii = 1:N
            averageAmountOfInk(tt,ii) = mean(rollers(ii).ink);
        end
    end
    
    figure
    plot(averageAmountOfInk,'b')
    xlabel('Timesteps')
    ylabel('Ink')
    
    function averageAmountOfInk = inkRollerModel()
    % # Initial state
    C = [0, 0;   % # Roller centers (x, y)
         2, 0;
         2, 4;
         2,-5;
         8, 4;
         8,-5;
         8,-1];
    R = [1,1,3,4,3,2,2];    % # Roller radii (r)
    N = numel(R);           % # Amount of rollers
    
    % # Draw the rollers
    figure, hold on
    ang = 0:0.1:(2 * pi);
    for i = 1:N
        plot(C(i, 1) + R(i) * cos(ang), C(i, 2) + R(i) * sin(ang))
        text(C(i, 1), C(i, 2), num2str(i))
    end
    title('Ink rollers'), axis image
    
    % # Find connected rollers
    isconn = @(m, n)(sum(([1, -1] * C([m, n], :)) .^ 2) - sum(R([m, n])) .^ 2 < eps);
    [Y, X] = meshgrid(1:N, 1:N);
    conn = reshape(arrayfun(isconn, X(:), Y(:)), N, N) - eye(N);
    
    % # Direction of rotation (clockwise = -1, anticlockwise = 1)
    rotDir = [1,-1,1,1,-1,-1,1];
    
    % # Number of bins for smallest roller
    nBins_min = 20;
    nBins = round(nBins_min*R/min(R));
    
    % # Initialize roller struct
    rollers = struct('ink',{},'connections',{},'rotDirection',{});
    
    % # Ink
    for ii = 1:N
        rollers(ii).ink = zeros(1,nBins(ii));
    end
    rollers(1).ink = ones(1,nBins(1));
    
    % # Connections
    for ii = 1:N
        rollers(ii).connections = zeros(1,nBins(ii));
    end
    for ii = 1:N
        for jj = 1:N
            if(ii~=jj)
                if(conn(ii,jj) == 1)
                    connInd = getConnectionIndex(C,ii,jj,nBins(ii));
                    rollers(ii).connections(connInd) = jj;
                end
            end
        end
    end
    
    % # Direction of rotation
    for ii = 1:N
        rollers(ii).rotDirection = rotDir(ii);
    end
    
    % # Initialize averageAmountOfInk and calculate initial distribution
    nTimeSteps = 200;
    averageAmountOfInk = zeros(nTimeSteps,N);
    for ii = 1:N
        averageAmountOfInk(1,ii) = mean(rollers(ii).ink);
    end
    
    % # Iterate through timesteps
    for tt = 2:nTimeSteps
        % # Fill first roller with ink
        rollers(1).ink = ones(1,nBins(1));
    
        % # Rotate all rollers
        for ii = 1:N
                rollers(ii).ink(:) = ...
                    circshift(rollers(ii).ink(:),rollers(ii).rotDirection);
        end
    
        % # Update all roller-connections
        for ii = 1:N
            for jj = 1:nBins(ii)
                if(rollers(ii).connections(jj) ~= 0)
                    index1 = rollers(ii).connections(jj);
                    index2 = find(ii == rollers(index1).connections);
                    ink1 = rollers(ii).ink(jj);
                    ink2 = rollers(index1).ink(index2);
                    rollers(ii).ink(jj) = (ink1+ink2)/2;
                    rollers(index1).ink(index2) = (ink1+ink2)/2;
                end
            end
        end
    
        % # Calculate average amount of ink on each roller
        for ii = 1:N
            averageAmountOfInk(tt,ii) = mean(rollers(ii).ink);
        end
    end
    
    figure
    plot(averageAmountOfInk,'b')
    xlabel('Timesteps')
    ylabel('Ink')
    
    end
    
    function connectionIndex = getConnectionIndex(C,ii,jj,nBins)
    
    p1 = C(ii, :);
    p2 = C(jj, :);
    
    if(abs(p1(2)-p2(2))<eps)
        if(p2(1)>p1(1))
            angle = 0;
        else
            angle = pi;
        end
    elseif(abs(p1(1)-p2(1))<eps)
        if(p2(2)>p1(2))
            angle = pi/2;
        else
            angle = 3*pi/2;
        end
    else
        angle = mod( atan((p2(1)-p1(1))/(p2(2)-p1(2))), 2*pi);
    end
    
    connectionIndex = 1+floor(nBins*angle/(2*pi));
    
    end
    
    C = [-276.4, 565.08;...  % # Duct
         -27.82, 616.11;...  % # r2
          41.26, 562.41;...  % # r3
          52.12, 473.07;...  % # r4
         -44.97, 366.25;...  % # ink drum
          137.22, 443.76;... % # r6
          99.32, 362.13;...  % # r7
          141.22, 272.79;... % # r8
          51.67, 237.7;...   % # r9
          173.99, 177.07;... % # r10
         -203.02, 230.52;... % # r11
         -110.9, 213.53;...  % # r12
         -207.33, 131.94;... % # r13
         -187.4, 330.49;...  % # r14
          0,0...             % # Plate cylinder
    ];% # Roller centres (x, y)
    
    R = [...
    95/2,...  % # Duct
    80/2,...  % # r2
    95/2,...  % # r3
    85/2,...  % # r4
    208/2,... % # Drum
    96/2,...  % # r6
    85/2,...  % # r7
    112.35/2,... % # r8
    81/2,...  % # r9
    90/2,...  % # r10
    112.35/2,... % # r11
    75/2,...  % # r12
    86/2,...  % # r13
    90/2,...  % # r14
    406.5/2 % # Plate
    ]; % # Roller radii (r)