Le tri des points par leur angle polaire en Java
Je suis en utilisant Graham analyse de l'algorithme pour trouver la convexe-la coque d'un ensemble de points
Je suis en train de trier les points de par leur angle polaire mais je n'ai aucune idée de comment faire (j'ai déjà trié l'ensemble des points par leurs coordonnées Y).
Ce que j'ai déjà écrit, c'est comme ceci:
public double angle(Coord o, Coord a)
{
return Math.atan((double)(a.y - o.y) / (double)(a.x - o.x));
}
où Coord
est la classe où j'ai des coordonnées X et Y comme double
.
J'ai également regardé l'un de la des emplois similaires dans le Débordement de la Pile où quelqu'un avait essayé de mettre en œuvre cet angle avec le C++, mais je ne comprends pas qsqrt
. Avons-nous quelque chose comme cela en Java?
qreal Interpolation::dp(QPointF pt1, QPointF pt2)
{
return (pt2.x()-pt1.x())/qSqrt((pt2.x()-pt1.x())*(pt2.x()-pt1.x()) + (pt2.y()-pt1.y())*(pt2.y()-pt1.y()));
}
Je serai heureux si quelqu'un peut m'aider.
OriginalL'auteur Navid Koochooloo | 2013-05-12
Vous devez vous connecter pour publier un commentaire.
Vous n'avez pas besoin de calculer l'angle polaire de trier par elle. Puisque les fonctions trigonométriques sont monotones (toujours en augmentation ou toujours à la baisse) à l'intérieur d'un quadrant, en quelque sorte, par la fonction elle-même, par exemple, le bronzage dans votre cas. Si vous êtes à la mise en œuvre de la Graham analyse en commençant par le fond le plus de point, vous avez seulement besoin de regarder les deux premiers quarts de cercle, de sorte qu'il serait plus facile de trier par cotan, puisque c'est une fonction monotone sur deux quadrants.
En d'autres termes, vous pouvez simplement les trier par
- (x - x1) /(y - y1)
(où (x1, y1) sont les coordonnées de votre point de départ), qui sera plus rapide à calculer. D'abord, vous aurez besoin de séparer les points oùy == y1
, bien sûr, et les ajouter en haut ou en bas de la liste en fonction du signe de (x - x1)`, mais ils sont faciles à identifier, puisque vous avez déjà triés par y trouver votre point de départ.pour le point de démarrer, tous les où il est écrit autre chose. il importe par où commencer ?
(x - x1) / (y - y1)
est la formule pour le cotan (1/tan) -- adjacentes sur face. Je n'en ai fait dans la négative, de sorte qu'il augmente avec l'angle. Je n'avais pas entendu parler d'un balayage de Graham, donc j'ai basé mon intervention sur l'article de Wikipedia, qui suggère de commencer avec le fond le plus de point. L'idée n'aurait pas changé si vous avez commencé avec, disons, la plus à gauche du point. Dans ce cas, il serait plus facile d'utiliser la tangente:(y - y1) / (x - x1)
nécessaire d'avoir le signe négatif? cause j'ai utilisé votre formule, mais sans le signe négatif
Il permet simplement de l'ordre de tri. Classique angles augmentation dans le sens antihoraire, mais la cotangente augmente dans le sens horaire.
OriginalL'auteur maybeWeCouldStealAVan
Comme mentionné ci-dessus, le calcul de l'angle polaire lui-même est assez bâclée manière d'aborder les choses. Vous pouvez définir un simple comparateur et utilisez les produits à trier par angle polaire. Voici le code en C++ (que j'utilise pour mon propre Graham scan):
Vous pouvez implémenter la même chose en Java, par la définition d'un
Point
classe. Fondamentalement, je n'ai surchargé le^
opérateur pour retourner le produit croisé. Le reste est évident, espérons que cette aide!OriginalL'auteur akshat
Math.atan()
retourne un angle compris entre -pi/2 à pi/2. Vous aurez à ajuster les résultats pour les deux autres coordonnées.Si vous voulez l'angle à partir du centre de l'enveloppe convexe, vous devez d'abord traduire les coordonnées de sorte que le le centre de gravité est à l'origine.
OriginalL'auteur Andy Thomas