这种坐标转换如何达到预期效果?

时间:2014-01-13 17:18:23

标签: c#

以下代码段,width=2height=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+heightx=i-j计算感到困惑。这种转换如何运作?

2 个答案:

答案 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 = iy = j,我们会得到x + j = ix = 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

它将通过从屏幕的右下角到左上角的对角线逐点迭代。您提供的代码中的MaxMin将结果绑定到这些对角线的子集,代表一个矩形。