以下代码段,width=2
,height=2
int maxI = width + height;
for (int i = 1; i <= maxI; i++) {
int startJ = Math.Max(0, i - width);
int maxJ = Math.Min(i, height);
for (int j = startJ; j <= maxJ; j++) {
int x = i - j;
int y = j;
DoSomething(x,y);}}
将使用以下x,y对调用DoSomething
:
1: X=1,Y=0
2: X=0,Y=1 (Diagram: 0,0
3: X=2,Y=0 at bottom left)
4: X=1,Y=1 5 7 8
5: X=0,Y=2 2 4 6
6: X=2,Y=1 @ 1 3
7: X=1,Y=2
8: X=2,Y=2
这是理想的结果;迭代从0,0开始的矩形,但是对角扩展而不是(更受欢迎的)[y*width+x]
。但是,我对maxI=width+height
和x=i-j
计算感到困惑。这种转换如何运作?
答案 0 :(得分:3)
这里要实现的是x + y是特定对角线中每个单元的常量。例如,单元格3,4和5具有坐标{2, 0}; {1, 1}; {0, 2}
。请注意,每个加起来都是2。
所以maxI
实际上是其中一个总和的最大值。由于{width, height}
位于右上角,因此该对角线的总和为width + height
。这就是它的来源。
i - j
部分的出现是因为它基本上解决了上述等式。 i
的每个值都是坐标的总和。 j
被选择为该对角线内的单元格的y坐标。由于我们知道x + y = i
和y = j
,我们会得到x + j = i
或x = i - j
。
答案 1 :(得分:1)
这也可以通过几何变换来解释:
1)翻译,因此矩形的中心位于原点:
x' = x - width/2
bounds: [-width/2,width/2)
y' = y - height/2
bounds: [-height/2,height/2)
2)旋转45度:
x'' = x'cos(45) - y'sin(45) = (sqrt(2)/2)x' - (sqrt(2)/2)y'
y'' = x'sin(45) + y'cos(45) = (sqrt(2)/2)x' + (sqrt(2)/2)y'
3)按sqrt(2)/2
缩放:
x''' = x' - y' = x - width/2 - y + height/2
bounds: [-width/2-height/2,width/2+height/2)
y''' = x' + y' = x - width/2 + y - height/2
bounds: [-width/2-height/2,width/2+height/2)
4)仅在x
轴上翻译:
x'''' = x''' + width/2 = x - y + height/2
bounds: [-height/2,width/2+height/2)
y'''' = y'''
bounds: [-width/2-height/2,width/2+height/2)
5)引入参数变量:
i = y'''' + width/2 + height/2
bounds: [0,width+height)
j = x'''' + y'''' - width/2 - height/2
bounds: [-width-3*height/2,width/2+height/2)
对于这种转变,你得到了:
x = i - j
y = j
它将通过从屏幕的右下角到左上角的对角线逐点迭代。您提供的代码中的Max
和Min
将结果绑定到这些对角线的子集,代表一个矩形。