2011-10-06 33 views
9

Permite tomar puntos.Cómo pedir puntos en sentido contrario a las agujas del reloj

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}}; 

Ahora están en cierto orden (para mí es un desorden!) Que puede ser visto si nos fijamos en el 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

pero tenemos que pedirlos como la imagen de abajo

enter image description here

¿Alguien tiene alguna sugerencia para un algoritmo para ordenar dichos puntos 2D en sentido contrario a las agujas del reloj para que podamos reordenar la lista de puntos para crear una geometría como la última pic sólo mediante el uso ListLinePlot en el reordenado ¿¿¿¿puntos????

Al utilizar la sugerencia obtenemos algo como lo siguiente.

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

"hacia la derecha" necesita un centro y una orientación en el espacio ... el problema es el centro ... –

+2

permítame recordar tres cosas que normalmente hacemos aquí: 1) Al recibir ayuda, trate de darle también ** respondiendo preguntas ** en su área de especialización 2) ['Lea las preguntas frecuentes'] (http://tinyurl.com/2vycnvr) 3) Cuando vea buenas preguntas y respuestas, vote por ellas usando el triángulo gris '] (http://i.imgur.com/kygEP.png), ya que la credibilidad del sistema se basa en la reputación que obtienen los usuarios al compartir sus conocimientos. También recuerde aceptar la respuesta que mejor resuelva su problema, en caso de haberlo, ['presionando el signo de la marca de verificación '] (http://tinyurl.com/4srwe2t) –

+0

Gracias @belisarius Haré todo lo posible para seguir las sugerencias. Por cierto, ¿cree que la respuesta con 'FindShortestTour' es válida para un conjunto de puntos cóncavo general? – PlatoManiac

Respuesta

4

Acabo de leer en un comentario al nikie's answer que lo que realmente quiere es el algoritmo para un perfil aerodinámico.Por lo tanto, estoy publicando otra respuesta (relación) a este problema:

enter image description here

parece más fácil que el problema general, ya que es "casi convexa". Creo que el siguiente algoritmo reducir los riesgos que FindShortestTour tiene inherentemente en el vértice agudo:

  1. Encuentra la ConvexHull (que da cuenta de las superficies superior e ataque)
  2. eliminar del conjunto de los puntos en el convexo casco
  3. Realizar una FindShortestTour con los puntos restantes
  4. unir las dos curvas en los extremos más cercanos
  5. Voilà

De esta manera:

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

¿Por qué no acaba de ordenar los puntos ?:

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

Tenga en cuenta que el polígono en su última trama es cóncava, por lo que los puntos son ¡No ordenado en sentido horario!

+0

Todavía no es la formación que quiero después de la clasificación. No es como la última foto de mi publicación. Pero gracias por la respuesta. – PlatoManiac

+1

@PlatoManiac: Eso es lo que he intentado decirte con la última frase: la trama que mostraste es * no * en el sentido de las agujas del reloj. ¿Qué tipo de pedido * quieres * quieres? ¿Para qué necesitas esto? – Niki

+0

Mire esto simplemente tomando el punto más derecho y luego ordene el resto de los puntos no en sentido horario sino en sentido antihorario y vuelva al punto más a la derecha. Esto forma un ciclo cerrado comenzando con el punto más a la derecha y terminando en el mismo punto. Necesito ordenar estos puntos para una superficie aerodinámica 2D. http://enda1312.files.wordpress.com/2011/03/airfoil.gif – PlatoManiac

10

Quizás podría hacer algo con FindShortestTour. Por ejemplo

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

produce algo así como

plot of shortest tour

+0

Gracias soluciona un poco mi problema. – PlatoManiac

10

he publicado el siguiente comentario a continuación su pregunta: I don't think you'll find a general solution. Esta respuesta intenta cavar un poco sobre eso.

La solución de Heike parece justa, pero FindShortestTour se basa en las propiedades métricas del conjunto, mientras que su requisito es probablemente más en el aspecto topológico.

Aquí es una comparación de dos conjuntos de puntos y los métodos disponibles para 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}}] 

      grasa estrella         Delgado Estrella

enter image description here

Como se puede ver , varios métodos entregan el resultado esperado en la columna de la izquierda, mientras solo uno lo hace en el correcto. Además, el único método útil para el conjunto de la derecha está completamente desactivado para la columna de la izquierda.

-1

Aquí es una función de Python que ordena puntos hacia la izquierda. Es el teorema de Graham's Scan. Lo escribí porque malentendí una tarea. Sin embargo, necesita optimización.

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 
Cuestiones relacionadas