2011-08-09 352 views
2

我使用的是.NET 2.0,因此我無法訪問漂亮的Linq;不過,我已經編寫了一些順時針/逆時針排列點的代碼。C#排序X,Y座標順時針方向的列表

我的問題是,排序工作完全正常,如果列表尚未排序,但如果由於某種原因列表已排序排序功能失敗悲慘。

我在徘徊,如果有人能幫助我指出正確的方向,爲什麼這可能是原因。

這裏是我的電話給排序:

positions.Sort(new Comparison<Position>(MapUtils.SortCornersClockwise)); 

這裏是SortCornersClockwise功能:

public static int SortCornersClockwise(Position A, Position B) 
    { 
     // Variables to Store the atans 
     double aTanA, aTanB; 

     // Reference Point 
     Pixels reference = Program.main.reference; 

     // Fetch the atans 
     aTanA = Math.Atan2(A.Pixel.Y - reference.Y, A.Pixel.X - reference.X); 
     aTanB = Math.Atan2(B.Pixel.Y - reference.Y, B.Pixel.X - reference.X); 

     // Determine next point in Clockwise rotation 
     if (aTanA < aTanB) return -1; 
     else if (aTanB > aTanA) return 1; 
     return 0; 
    } 

凡我引用我從中確定各自的角度對每個點的點我的點數列表。

現在說我有個名單:

15778066, 27738237 
15778169, 27738296 
15778185, 27738269 
15778082, 27738210 

這些已經排序以正確的順序,但調用排序功能得到:

15778082, 27738210 
15778066, 27738237 
15778185, 27738269 
15778169, 27738296 

現在採取另一套取樣點:

15778180, 27738255 
15778081, 27738192 
15778064, 27738219 
15778163, 27738282 

此列表尚未按正確順序調用sort func產量:

15778064, 27738219 
15778081, 27738192 
15778180, 27738255 
15778163, 27738282 

這是排序正確。這種模式爲已經排序的每一組座標和沒有排序的座標重複一次。有任何想法嗎?

+3

你真的應該把你的參考點傳遞給方法,而不是引用(沒有雙關語意思)一個'全局'變量。 –

回答

8
if (aTanA < aTanB) return -1; 
else if (aTanB > aTanA) return 1; 

這兩個條件是一樣的! 或者交換變量轉過來不等號,但不是兩個。

+0

現在我感到很蠢,我在玩這個功能,並輸入錯誤的線路。謝謝。 –

1

難道不應該是:

else if(aTanA > aTanB) return 1; 

不知道這會導致雖然您的問題。

3

除了Henning所做的出色觀察之外,您一旦解決該問題,也可能會對輸出感到驚訝。

與完全有序域上的正常排序相比,圓對稱使得這種排序算法有點不尋常。由於存在圓形對稱性,因此有n個有效的順時針排序,給定n個點,這對您更喜歡哪種排序可能很重要。

既然這樣,使用未修飾的ATAN2的將導致具有座標的切割線(X,0),其中x 0 <

考慮座標A =(-10,1)和B =( - 10,-1),相對於參考測量。你可能想象A在結果中應該出現在B之前,但事實上它會是另一種方式,因爲atan2對A的返回小於π,但對於B只有大於-π。

如果你想要一個帶座標(x,0)的剪切線(x> 0)只需將2π添加到從atan2返回的任何負值即可。

+0

優秀的觀察。我注意到在2個(或更多)點在-X平面上的情況也是如此。解決方案的重要提示......如果(X == ref.X),我即將開始更困難的事情。 – IAbstract