2011-10-06 51 views
9

讓我們拿點。如何訂購點逆時針

pt={{-4.65371,0.1},{-4.68489,0.103169},{-4.78341,0.104834},{-4.83897,0.100757}, 
{-4.92102,0.0949725},{-4.93456,0.100181},{-4.89166,0.122666},{-4.78298,0.129514}, 
{-4.72723,0.121442},{-4.68355,0.11023},{-4.65371,0.1},{-4.66924,0.10173}, 
{-4.93059,0.0966989},{-4.93259,0.105094},{-4.91074,0.116966},{-4.90635,0.094878}, 
{-4.66846,0.105327},{-4.92647,0.0956182},{-4.93433,0.102498},{-4.9333,0.0982262}, 
{-4.66257,0.10102}}; 

現在,他們都在一定的順序(對我來說是一個障礙!)由此可以看出,如果我們看一下ListLinePLot

picUnorder=ListLinePlot[pt,Frame-> True,Mesh-> All,MeshStyle-> PointSize[Large]]; 
SeepicUnorder=ListLinePlot[pt,Frame-> True,Mesh-> All,MeshStyle-> 
PointSize[Large]]/.Line[rest_]:>{Arrowheads[Table[0.02,{i,0,1,.02}]],Arrow[rest]}; 
GraphicsGrid[{{picUnorder,SeepicUnorder}}] 

enter image description here

但我們需要訂購他們像下面的圖片。

enter image description here

有誰有一些建議的算法,這樣的2D點沿逆時針方向進行排序,以便我們可以只通過在重新安排使用ListLinePlot重新排列點的列表來創建像上次PIC幾何點????

使用建議我們得到如下內容。

center=Mean[pt]; 
pts=SortBy[pt,Function[p,{x,y}=p-center;ArcTan[x,y]]]; 
Show[ListPlot[pt],ListLinePlot[pts,Mesh-> All,MeshStyle-> 
PointSize[Large]],Frame-> True] 

enter image description here

BR

+0

「順時針」需要一箇中心和空間定位...問題是中心...... –

+2

允許我提醒三件事,我們通常在這裏做的:1)當你得到幫助,儘量給它**在您的專業領域回答問題** 2)['閱讀常見問題解答'](http://tinyurl.com/2vycnvr)3)當您看到良好的問答時,通過['使用灰色三角形'](http://i.imgur.com/kygEP.png),因爲系統的可信度基於用戶通過分享知識獲得的聲譽。另外請記住接受更好地解決您的問題的答案,如果有的話,['通過按複選標記](http://tinyurl.com/4srwe2t) –

+0

謝謝@belisarius我會盡我所能按照建議。順便說一下,你認爲FindShortestTour的答案適用於一般的凹點集合嗎? – PlatoManiac

回答

4

我剛剛讀了nikie's answer的評論,你真正想要的是翼型算法。所以,我張貼另一個(無關)回答了這個問題:

enter image description here

似乎比一般的問題更容易,因爲它是「幾乎凸」。我想下面的算法減少FindShortestTour本身具有的尖銳頂點的風險:

  1. 找到ConvexHull(即占上和攻擊面)
  2. 從集凸取出點船體
  3. ,其餘點進行一個FindShortestTour
  4. 在最近的端點加入兩條曲線

像這樣:

pt1 = [email protected]; 
<< ComputationalGeometry` 
convexhull = ConvexHull[pt1, AllPoints -> True]; 
pt2 = pt1[[convexhull]]; 
pt3 = Complement[pt1, pt2]; 
pt4 = pt3[[([email protected])[[2]]]]; 
If[Norm[[email protected] - [email protected]] > Norm[[email protected] - [email protected]], pt4 = [email protected]]; 
pt5 = Join[pt4, pt2, {pt4[[1]]}]; 
Graphics[{Arrowheads[.02], [email protected][pt5, 2, 1], 
      Red, PointSize[Medium], [email protected]}] 

enter image description here

9

你爲什麼不只是點?:

center = Mean[pt]; 
pts = SortBy[pt, Function[p, {x, y} = p - center; ArcTan[x, y]]] 
Show[ListPlot[pt], ListPlot[pts, Joined -> True]] 

注意,在你的最後情節的多邊形是凹的,所以點排序不順時針順序!

+0

它仍然不是我想排序後的陣型。這不像我的文章的最後一張照片。但謝謝你的答案。 – PlatoManiac

+1

@PlatoManiac:這就是我一直試圖告訴你的最後一句話:你顯示的情節是*不*順時針。你想要什麼樣的訂購?你需要做什麼? – Niki

+0

簡單地通過採取最右邊的點來看待這一點,然後對其餘的點進行排序,而不是順時針而是逆時針並回到最右邊的點。這通過從最右點開始並在相同點結束而形成閉環。我需要將這一點排序爲二維翼型。 http://enda1312.files.wordpress.com/2011/03/airfoil.gif – PlatoManiac

10

也許你可以用FindShortestTour做些什麼。例如

ptsorted = pt[[FindShortestTour[pt][[2]]]]; 
ListPlot[ptsorted, Joined -> True, Frame -> True, PlotMarkers -> Automatic] 

產生類似

plot of shortest tour

+0

謝謝它解決了我的問題。 – PlatoManiac

10

我發佈你的問題如下的評論:I don't think you'll find a general solution。這個答案試圖挖掘一點。

Heike的解決方案看起來很公平,但FindShortestTour基於集合的度量屬性,而您的要求可能更多的是拓撲方面。

這裏是兩個點集和方法比較適用於FindShortestTour

pl[method_, k_] := 
    Module[{ptsorted, pt,s}, 
    little[x_] := {{1, 0}, {2, 1}, {1, 2}, {0, 1}}/x - (1/x) + 2; 
    pt = Join[{{0, 0}, {4, 4}, {4, 0}, {0, 4}}, little[k]]; 
    ptsorted = Join[s = pt[[FindShortestTour[pt,Method->method][[2]]]], {s[[1]]}]; 
    ListPlot[ptsorted, Joined -> True, Frame -> True, 
         PlotMarkers -> Automatic, 
         PlotRange -> {{-1, 5}, {-1, 5}}, 
         Axes -> False, AspectRatio -> 1, PlotLabel -> method]]; 
[email protected] 
Table[pl[i, j], 
     {i, {"AllTours", "CCA", "Greedy", "GreedyCycle", 
      "IntegerLinearProgramming", "OrOpt", "OrZweig", "RemoveCrossings", 
      "SpaceFillingCurve", "SimulatedAnnealing", "TwoOpt"}}, 
     {j, {1, 1.8}}] 

     胖星       修身星

enter image description here

正如你所看到的,有幾種方法可以在左列上提供預期的結果只有一個在正確的一個。而且,對於左側的列,右側的唯一有用的方法是完全關閉的。

-1

這裏是一個Python函數逆時針訂單分。它是格雷厄姆的掃描定理。我寫過,因爲我誤解了作業。不過,它需要優化。

def order(a): 
from math import atan2 
arctangents=[] 
arctangentsandpoints=[] 
arctangentsoriginalsandpoints=[] 
arctangentoriginals=[] 
centerx=0 
centery=0 
sortedlist=[] 
firstpoint=[] 
k=len(a) 
for i in a: 
    x,y=i[0],i[1] 
    centerx+=float(x)/float(k) 
    centery+=float(y)/float(k) 
for i in a: 
    x,y=i[0],i[1] 
    arctangentsandpoints+=[[i,atan2(y-centery,x-centerx)]] 
    arctangents+=[atan2(y-centery,x-centerx)] 
    arctangentsoriginalsandpoints+=[[i,atan2(y,x)]] 
    arctangentoriginals+=[atan2(y,x)] 
arctangents=sorted(arctangents) 
arctangentoriginals=sorted(arctangentoriginals) 
for i in arctangents: 
    for c in arctangentsandpoints: 
     if i==c[1]: 
      sortedlist+=[c[0]] 
for i in arctangentsoriginalsandpoints: 
    if arctangentoriginals[0]==i[1]: 
     firstpoint=i[0] 
z=sortedlist.index(firstpoint) 
m=sortedlist[:z] 
sortedlist=sortedlist[z:] 
sortedlist.extend(m) 
return sortedlist