由于您没有指定滚轮的确切型号,我将以极坐标表示它们,即具有中心点和半径。每个滚筒上的墨水将由一个附加值表示,例如:
% # Initial state
C = [0, 0; -0.8, -0.6; 1, 0]; % # Roller centers (x, y)
R = [0.5, 0.5, 0.5]; % # Roller radii (r)
ink = [1, 0, 0]; % # Amount of ink on each roller
N = numel(R); % # Amount of rollers
此处仅在 #1 辊上有墨水(我随意选择了这些值,因此当然可以更改它们)。为了您的方便,您可以像这样绘制滚轮:
% # Draw the rollers
figure, hold on
ang = 0:0.1:(2 * pi);
for i = 1:N
plot(C(i, 2) + R(i) * cos(ang), C(i, 1) + R(i) * sin(ang))
text(C(i, 2), C(i, 1), num2str(i))
end
title('Ink rollers'), axis image
这应该会产生以下图像:
我会让你在每个滚筒上画墨水:P
现在开始做生意:
1)首先我们找到所有连接的滚子:
% # 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);
这将产生一个矩阵,如果辊i和辊j连接,则位置 ( i , j )中的每个元素为 1,否则为 0。在这个例子中,我们得到:
conn =
0 1 1
1 0 0
1 0 0
2) 下一步是通过运行预定数量的迭代来模拟墨水流动。在每次迭代中,我们模拟每个辊子的一转,即我们遍历每个辊子并在其自身和相邻辊子之间平均分配墨水。
% # Simulate ink flow for a number of revolutions
disp([sprintf('Initial state:\t\t'), '[', num2str(ink), ']'])
revolutions = 3;
for ii = 1:revolutions
new_ink = zeros(size(ink));
% # Iterate over each roller
for jj = 1:N
if (ink(jj) > 0)
delta_ink = ink(jj) / (sum(conn(jj, :)) + 1);
idx = [jj, find(conn(jj, :))]; % # roller jj and its neighbors
new_ink(idx) = new_ink(idx) + delta_ink;
end
end
ink = new_ink;
disp([sprintf('Revolution #%d:\t\t', ii), '[', num2str(ink), ']'])
end
很抱歉,我没有花太多精力通过矢量化来优化这些循环。无论如何,这些是每转中每个辊上的墨水量:
Initial state: [1 0 0]
Revolution #1: [0.33333 0.33333 0.33333]
Revolution #2: [0.44444 0.27778 0.27778]
Revolution #3: [0.42593 0.28704 0.28704]
显然,您可以轻松地将这段代码放入一个函数中,该函数返回滚轮的最后状态,或您选择的任何其他输出。此外,您还可以修改算法以根据辊子的半径处理不同的分流比。祝你好运!