Existe-t-il un tel algorithme pour trier un tableau de points 2D dans le sens horaire?
Je traite spécifiquement du triangle rectangle dans mon cas, donc seulement 3 points.
Cependant, je suis intéressé à savoir si un tel algorithme existe, sinon quel est un moyen simple de retourner les 3 points de mon triangle dans le sens horaire?
Edit: j'essaie de calculer les points dans le sens horaire par rapport au centre de gravité du polygone, qui est convexe.
Mise à jour: c'est l'implémentation que j'ai fini par utiliser en fonction de la réponse choisie, ce n'est pas critique en termes de performances et ne se produit que de temps en temps, donc ça marche.
ArrayList<PVector> pointList = new ArrayList<PVector>();
pointList.add(A);
pointList.add(B);
pointList.add(C);
Collections.sort( pointList, new TriangleVectorComparator(origin) );
return pointList;
// Comparator
package triangleeditor;
import java.util.Comparator;
import processing.core.PVector;
public class TriangleVectorComparator implements Comparator<PVector> {
private PVector M;
public TriangleVectorComparator(PVector origin) {
M = origin;
}
public int compare(PVector o1, PVector o2) {
double angle1 = Math.atan2(o1.y - M.y, o1.x - M.x);
double angle2 = Math.atan2(o2.y - M.y, o2.x - M.x);
//For counter-clockwise, just reverse the signs of the return values
if(angle1 < angle2) return 1;
else if (angle2 < angle1) return -1;
return 0;
}
}
2d
mathematics
algorithm
onedayitwillmake
la source
la source
Réponses:
Votre question n'est pas assez précise. Un tableau de points est uniquement «dans le sens horaire» ou «anti-horaire» par rapport à un point de référence. Sinon, tout tableau de trois points peut toujours être CW ou CCW. Voir l'image suivante: à gauche, les points sont ordonnés dans le sens des aiguilles d'une montre; à droite, les mêmes points sont ordonnés dans le sens inverse des aiguilles d'une montre.
Dans votre cas, je pense qu'il est raisonnable d'utiliser le barycentre des points comme point de référence.
Une bonne méthode pour un nombre inconnu de points pourrait être la suivante:
P[0], P[1], ... P[n-1]
être la liste des points pour triera[0], a[1], ... a[n-1]
telle sorte quea[i] = atan2(P[i].y - M.y, P[i].x - M.x);
a
valeur, en utilisantqsort
par exemple.Cependant, vous pouvez être sûr qu'un bon algorithme de tri fonctionnera mal avec trois valeurs d'entrée par rapport à une méthode ad hoc. L'utilisation
atan2
est toujours valide, mais ne l'utilisez pasqsort
.la source
qsort
ici est minuscule par rapport àatan2
.Je crois que ce que vous demandez en fait ici, c'est l'ordre d'enroulement du triangle, qui est en fait assez simple à tester.
Puisqu'il n'y a que trois points dans votre triangle, votre triangle est déjà dans un sens horaire ou antihoraire, et donc tout ce que vous devez faire est de vérifier lequel de ces deux il est, et inverser l'ordre des indices si le bobinage ce n'est pas celui que vous voulez.
Voici l'idée générale, en supposant que les trois sommets d'un triangle sont a , b et c , et que vous avez une opération de soustraction vectorielle simple:
Notez que selon la façon dont vous avez orienté votre axe + y (vers le haut ou vers le bas), les cas "dans le sens horaire" et "anti-horaire" peuvent être inversés par rapport à la façon dont je les ai étiquetés dans les commentaires de cet exemple de code.
la source
Pouvez-vous donner plus d'informations? Vous voulez un ordre de points CCW, mais quel point devrait être le centre de la commande?
Si vous n'avez qu'un triangle (3 points) dans le plan, vous pouvez calculer le déterminant à partir de la matrice, où les lignes sont les coordonnées des points (la 3e coordonnée est 1). Si le déterminant est> 0, les points sont dans l'ordre CCW. Sinon, vous pouvez par exemple passer les deux derniers points et vous obtiendrez l'ordre CCW.
Si vous avez des points A, B, C, alors votre matrice ressemble à:
Le déterminant est: xA * yB + xB * yC + xC * yA - yB * xC - yC * xA - yA * xB. Ensuite, vous pouvez le comparer à zéro. Si c'est> 0, retournez les points A, B, C, sinon, retournez A, C, B.
Si vous avez défini des points et que vous savez qu'ils font un polygone convexe (tous font partie d'une coque convexe) et que vous souhaitez obtenir leur commande, vous pouvez utiliser Graham Scan ou Jarvis's March (ce sont des algorithmes pour trouver la coque convexe à partir de nombreux points, mais ça devrait aussi marcher ici :))
la source