这个需求就是要在一个正方形矩阵中,写入连续的自然数,且矩阵中任意两个差为1的自然数位置要相邻。
一切都是从一个[ 0 ]开始的。
然后选择一个增长方向。可以向右或向下。我以向右为例,第一次增长后得到如下矩阵:
0 | 1 |
3 | 2 |
这个矩阵很简单,可以直接手工填写。但我们需要让尽可能多的自然数以连续的方式填充到正方形矩阵中。
也就是达到这个效果:
0 | 1 | 14 | 15 | 16 | 19 | 20 | 21 | 234 | 235 | 236 | 239 | 240 | 241 | 254 | 255 |
3 | 2 | 13 | 12 | 17 | 18 | 23 | 22 | 233 | 232 | 237 | 238 | 243 | 242 | 253 | 252 |
4 | 7 | 8 | 11 | 30 | 29 | 24 | 25 | 230 | 231 | 226 | 225 | 244 | 247 | 248 | 251 |
5 | 6 | 9 | 10 | 31 | 28 | 27 | 26 | 229 | 228 | 227 | 224 | 245 | 246 | 249 | 250 |
58 | 57 | 54 | 53 | 32 | 35 | 36 | 37 | 218 | 219 | 220 | 223 | 202 | 201 | 198 | 197 |
59 | 56 | 55 | 52 | 33 | 34 | 39 | 38 | 217 | 216 | 221 | 222 | 203 | 200 | 199 | 196 |
60 | 61 | 50 | 51 | 46 | 45 | 40 | 41 | 214 | 215 | 210 | 209 | 204 | 205 | 194 | 195 |
63 | 62 | 49 | 48 | 47 | 44 | 43 | 42 | 213 | 212 | 211 | 208 | 207 | 206 | 193 | 192 |
64 | 67 | 68 | 69 | 122 | 123 | 124 | 127 | 128 | 131 | 132 | 133 | 186 | 187 | 188 | 191 |
65 | 66 | 71 | 70 | 121 | 120 | 125 | 126 | 129 | 130 | 135 | 134 | 185 | 184 | 189 | 190 |
78 | 77 | 72 | 73 | 118 | 119 | 114 | 113 | 142 | 141 | 136 | 137 | 182 | 183 | 178 | 177 |
79 | 76 | 75 | 74 | 117 | 116 | 115 | 112 | 143 | 140 | 139 | 138 | 181 | 180 | 179 | 176 |
80 | 81 | 94 | 95 | 96 | 97 | 110 | 111 | 144 | 145 | 158 | 159 | 160 | 161 | 174 | 175 |
83 | 82 | 93 | 92 | 99 | 98 | 109 | 108 | 147 | 146 | 157 | 156 | 163 | 162 | 173 | 172 |
84 | 87 | 88 | 91 | 100 | 103 | 104 | 107 | 148 | 151 | 152 | 155 | 164 | 167 | 168 | 171 |
85 | 86 | 89 | 90 | 101 | 102 | 105 | 106 | 149 | 150 | 153 | 154 | 165 | 166 | 169 | 170 |
它的规律就是把一个正方形矩阵放大成2×2倍的正方形矩阵,其中左上角是原来的矩阵,另外三个角是新的子矩阵。
对角位置和相邻位置的其中一个子矩阵的增长方式和方向与原矩阵的转置矩阵相同。另一个相邻的子矩阵的增长方式是原矩阵方向相反后再对称处理的。
由于新的子矩阵是以转置和对称方式创建的,新生成的子矩阵会保留原矩阵的连续性。
以下是生成这种矩阵的代码:
/**
* @param size
* 边长,自动修正成2的整数次幂
* @param startVertical
* 起始方向: true 1在0的下方,false 1在0的右方
* @return
*/
public static int[][] mazeCoverMatrix(int size, boolean startVertical) {
UnaryOperator<int[][]> generateA = (int[][] a) -> {
int[][] b = new int[a.length * 2][];
for (int i = 0; i < b.length; ++i) {
b[i] = new int[b.length];
}
int blockAddition = a.length * a.length;
for (int i = 0; i < a.length; ++i) {
for (int j = 0; j < a.length; ++j) {
b[i][j] = a[i][j];// 复制
b[i + a.length][j] = a[j][i] + blockAddition;// 转置
b[i + a.length][j + a.length] = a[j][i] + blockAddition * 2;// 转置
b[i][j + a.length] = a[a.length - 1 - i][a.length - 1 - j] + blockAddition * 3;// 对称
}
}
return b;
};
UnaryOperator<int[][]> generateB = (int[][] a) -> {
int[][] b = new int[a.length * 2][];
for (int i = 0; i < b.length; ++i) {
b[i] = new int[b.length];
}
int blockAddition = a.length * a.length;
for (int i = 0; i < a.length; ++i) {
for (int j = 0; j < a.length; ++j) {
b[i][j] = a[i][j];// 复制
b[i][j + a.length] = a[j][i] + blockAddition;// 转置
b[i + a.length][j + a.length] = a[j][i] + blockAddition * 2;// 转置
b[i + a.length][j] = a[a.length - 1 - i][a.length - 1 - j] + blockAddition * 3;// 对称
}
}
return b;
};
if (size < 1) {
size = 1;
}
int[][] matrix = new int[][] { { 0 } };
boolean operatorA = startVertical;
for (; matrix.length < size;) {
if (operatorA) {
matrix = generateA.apply(matrix);
} else {
matrix = generateB.apply(matrix);
}
operatorA = !operatorA;
}
return matrix;
}
在Solidworks中,界面常不是正方形的。多余的矩阵部分将被裁减。
按这种顺序进行图像处理似乎并不能提高性能,也不会提高画面质量。只是使工作人员在生成图片的时候不会感到无聊而已。