2014-01-13 50 views
3

下面的代碼段,以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);}} 

將調用DoSomething用下面的x,y對:

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的計算感到困惑。這種轉換如何工作?

+0

究竟是什麼讓你感到困惑?你的代碼片段只顯示「int」,所以不涉及任何轉換。 –

+2

'i'遍歷對角線(不包括左上角)。所以'maxI'是對角線的數量。 'j'遍歷當前對角線上的元素。所以'maxJ'取當前的'i'並計算該對角線上的元素數量。 – mbeckish

回答

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)翻譯,因此該矩形的中心在原點:

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在您提供的代碼中將結果綁定到這些對角線的子集,代表矩形。