Suite

Ordre des sommets des polygones dans le SIG général : horaire ou antihoraire


Il y a deux jours, j'ai posé une question sur l'ordre de stockage interne des sommets d'un polygone dans les fichiers de formes ESRI. Cette question a été répondue (Les polygones sont-ils stockés dans le sens des aiguilles d'une montre ou dans le sens inverse dans un fichier de formes ?) et il a également été répondu dans un ancien message (Création de polygones (rotation dans le sens des aiguilles d'une montre ou non))

Mais maintenant ma question est plus générale, et je ne sais pas si elle a une réponse unique.

L'ordre dans le sens horaire est-il uniquement pour les fichiers de formes ESRI ou pour les formats SIG généraux ?

Et qu'en est-il de la représentation interne pour un logiciel SIG ?

Par exemple, si j'utilise QGIS et que je lis un fichier *.shp contenant des polygones, je suppose que la représentation interne de la limite extérieure est dans le sens des aiguilles d'une montre comme dans le fichier de formes d'origine, mais qu'en est-il de tous les formats de fichiers pris en charge par QGIS ?

Et pour ArcGIS ?

Et dans le cas où il existe un format de fichier avec des polygones stockés dans le sens antihoraire, si ces fichiers sont chargés dans QGIS, ArcGIS, etc., l'orientation est-elle modifiée en interne, donc si je lis les données à l'aide de PyQGIS, par exemple, les polygones sont dans le sens horaire commandé?

Mon objectif est d'écrire un plugin pour QGIS, mais la source de données peut être des fichiers de formes ESRI ou d'autres formats. Comme je dois vérifier les angles entre les côtés consécutifs des polygones en utilisant leurs azimuts, je dois savoir si l'ordre est dans le sens des aiguilles d'une montre. Une solution consiste à calculer l'aire de chaque polygone et, si je me souviens bien, s'il est positif, l'ordre est dans le sens des aiguilles d'une montre et s'il est négatif, l'ordre est dans le sens inverse.

Le calcul de zone n'est pas une tâche intensive, il ne ralentira donc pas autant mon plugin.

Mais dans le cas particulier de QGIS, quelqu'un sait s'il stocke les polygones dans le sens horaire ou antihoraire, quel que soit l'ordre dans la source d'origine ?

À l'heure actuelle, je travaille avec les fichiers de formes ESRI et les coordonnées danslayer.getFeatures().geometry().asPolygon()sont stockés dans le sens des aiguilles d'une montre pour la bordure extérieure et dans le sens inverse des aiguilles d'une montre pour les trous, i. e. comme dans le fichier *.shp d'origine.


Dans la spécification OGC, qui peut être téléchargée [ici], (http://www.opengeospatial.org/standards/sfs) ils indiquent :

"La rotation du polygone n'est pas définie par cette norme ; la rotation réelle du polygone peut être dans le sens des aiguilles d'une montre ou dans le sens inverse des aiguilles d'une montre."

Dans la documentation d'Oracle, il est clairement indiqué que les limites des anneaux extérieurs sont orientées dans le sens inverse des aiguilles d'une montre et les limites des anneaux intérieurs, dans le sens des aiguilles d'une montre. De même, dans SQL Server Spatial, le type de données géographie suit une règle dans le sens inverse des aiguilles d'une montre pour l'anneau extérieur et dans le sens des aiguilles d'une montre pour les anneaux intérieurs. Consultez ce blog MicroSoft pour plus de détails. Postgis semble l'autoriser de toute façon, pour les géométries, et a des fonctions qui forceront la géométrie d'un polygone à suivre une règle de droite ou de gauche, voir ST_ForceRHR et ForceLHR. JTS/Geos semblent avoir suivi la règle de la main droite, c'est-à-dire une orientation dans le sens des aiguilles d'une montre de l'anneau extérieur, donc tout est un peu flou, vraiment.

En général, il est logique qu'un type de données géographiques force l'orientation, car sinon il serait impossible de dire si un petit polygone n'était que cela ou l'anneau intérieur d'un polygone du monde entier. Avec un type de données de géométrie sur une surface plane, cette confusion ne peut pas survenir, car l'anneau extérieur et l'anneau intérieur se suivent dans l'ordre, et s'il n'y a qu'un seul anneau, il sera englobant (quelle que soit l'orientation), contrairement à un globe , qui s'enroule.


D'après un commentaire de @mxfh : OpenGIS Simple Features Access (ISO 19125-1) de l'OGC spécifie un sens antihoraire pour les anneaux extérieurs à partir de la version 1.2.1 du document [OGC 06-103r4] 6.1.11.1/page 26 de opengeospatial.org /normes/sfa. Le changement a été introduit entre les versions 1.1.0 et 1.2.0 en 2006 au plus tard. La note de bas de page que vous citez n'a pas été mise à jour depuis 2005


Les directions des anneaux (limites) sont nécessaires pour éviter les ambiguïtés pour les systèmes de coordonnées géographiques qui couvrent une surface finie, puisque la limite définirait deux zones, une à gauche et une à droite de la limite le long de sa direction. Déterminer laquelle de ces deux zones est la plus grande est possible, mais laisse toujours l'ambiguïté.

Voici un aperçu des directions de l'anneau extérieur des polygones dans divers formats selon leurs spécifications :

  • Simple Feature Access (ISO 19125-1) également utilisé dans WKT/GML/KML et diverses implémentations SQL :

    • anneaux extérieurs : dans le sens antihoraire
    • anneaux intérieurs (trous) : sens horaire.

    Un polygone est une surface plane définie par 1 limite extérieure et 0 ou plusieurs limites intérieures. Chaque limite intérieure définit un trou dans le polygone. […]

    La limite extérieure LinearRing définit le « sommet » de la surface qui est le côté de la surface à partir duquel le extérieur frontière semble traverser la frontière dans un dans le sens inverse des aiguilles d'une montre direction. Le intérieur Les anneaux linéaires auront l'orientation opposée et apparaîtront comme dans le sens des aiguilles d'une montre vu du « haut »… Spécifications d'accès aux fonctionnalités simples

    Dans la plupart des implémentations, l'ordre des anneaux dans un POLYGONE est important (par opposition aux fichiers de formes)

    Pour un polygone avec des trous, son premier sous-élément est son anneau extérieur, son deuxième sous-élément est son premier anneau intérieur, son troisième sous-élément est son deuxième anneau intérieur, et ainsi de suite. Oracle spatial

    Les nids plus profonds, alias île-dans-un-lac-sur-une-île-… doivent être représentés sous forme de multipolygones (voir figure 2.10 (4)), car il ne peut y avoir qu'une seule bordure extérieure et des nids plus profonds que les anneaux intérieurs ne le sont pas. défini.

  • Fichiers de formes ESRI/SHP :

    • anneaux extérieurs: dans le sens des aiguilles d'une montre
    • anneaux intérieurs : dans le sens antihoraire

    Un polygone est constitué d'un ou plusieurs anneaux. Un anneau est une séquence connectée de quatre points ou plus qui forment une boucle fermée qui ne se coupe pas. Un polygone peut contenir plusieurs anneaux extérieurs. L'ordre des sommets ou l'orientation d'un anneau indique de quel côté de l'anneau se trouve l'intérieur du polygone. Le voisinage à droite d'un observateur marchant le long de l'anneau dans l'ordre des sommets est le voisinage à l'intérieur du polygone. Sommets des anneaux définissant des trous dans les polygones sont dans un dans le sens antihoraire direction. Les sommets d'un seul polygone annelé sont donc toujours en dans le sens des aiguilles d'une montre ordre. […]

    L'ordre des anneaux dans le tableau des points n'est pas significatif. Livre blanc ESRI

    Étant donné que plusieurs limites extérieures sont autorisées, des configurations d'île dans un lac sur une île sont possibles avec cette définition de polygone. Topologiquement, l'île dans un lac ne serait qu'un autre anneau extérieur dans le sens des aiguilles d'une montre. En fait, cela fait d'un polygone ESRI Shapefile une fonction simple MultiPolygon

    Si vous n'ordonnez pas correctement les points, vous n'aurez que des polygones qui se chevauchent. pyshp

  • GeoJSON (RFC7946) :

    REMARQUE : La spécification GeoJSON 2008 d'origine n'avait pas d'ordre d'enroulement appliqué

    • ordre de remontage : la bague extérieure est dans le sens antihoraire (règle de la main droite)
    • les anneaux intérieurs sont dans le sens des aiguilles d'une montre
    • l'ordre des anneaux est important :

      Pour les polygones avec plusieurs anneaux, le premier doit être l'anneau extérieur et tous les autres doivent être des anneaux ou des trous intérieurs. Spécification GeoJSON

  • TopoJSON : force les anneaux extérieurs dans le sens des aiguilles d'une montre par défaut

Excursion:

Le raisonnement mathématique expliquant pourquoi les ordres d'enroulement des anneaux imbriqués alternent est que le calcul de l'aire avec la formule du lacet (explication visuelle) calcule les aires signées en fonction de la direction de l'anneau.

En général, les anneaux imbriqués (limites intérieures) sont considérés comme des trous et ont la direction alternative de l'anneau extérieur. Leur valeur de zone signée contributive est négative. Alors que les anneaux extérieurs sont positifs. L'aire totale de toutes les entités annulaires est la somme de toutes les aires signées.

Tel qu'implémenté par ESRI, voir cette entrée de la base de connaissances : Quel algorithme est utilisé par ArcGIS pour déterminer la superficie d'un polygone ?

Mnémonique proposé

Extrémités ouvertes des lettres interprétées comme des flèches :

  • Sfichier hape : S → ᔑ → ↻
  • F simpleeatures : e → ᘓ (enroulement vers l'extérieur dans le sens cc) → ↺
  • GeoJSON : G (la racine de G est la flèche) → ↺

Je ne sais pas si quiconque sera en mesure de fournir une réponse définitive à votre question, car chaque format de fichier vectoriel est différent et chaque SIG, en termes de gestion interne de ces données, sera également différent. Mais je peux vous dire avec certitude que l'ordre dans le sens des aiguilles d'une montre n'est pas seulement pour ESRI Shapefiles. Il existe d'autres formats qui utilisent une désignation similaire d'ordre dans le sens horaire pour les anneaux externes et dans le sens antihoraire pour les polygones de trous intérieurs. Par exemple, la structure de polygone vectoriel JTS utilise un format similaire. En fait, il est indiqué ici qu'historiquement, cela devait être similaire à l'approche ESRI. Je peux aussi dire définitivement que non, tous les formats n'ont pas cette exigence. Par exemple, les spécifications du format GeoJSON n'imposent pas une telle exigence concernant l'ordre des sommets dans leur format de polygone. La spécification KML indique en fait :

Les polygones pour doivent être spécifiés dans le sens inverse des aiguilles d'une montre. Les polygones suivent la "règle de la main droite", qui stipule que si vous placez les doigts de votre main droite dans la direction dans laquelle les coordonnées sont spécifiées, votre pouce pointe dans la direction générale de la normale géométrique du polygone.

Ainsi, la gamme complète d'options existe et est mise en œuvre là-bas. C'est un monde sauvage!


Maillage polygonal


UNE maillage polygonal ou grille non structurée est une collection de sommets, d'arêtes et de faces qui définit la forme d'un objet polyédrique en infographie 3D et en modélisation solide. Les faces sont généralement constituées de triangles, de quadrilatères ou d'autres polygones convexes simples, car cela simplifie le rendu, mais peuvent aussi être composées de polygones concaves plus généraux, ou de polygones avec des trous.

L'étude des maillages polygonaux est un vaste sous-domaine de l'infographie et de la modélisation géométrique. Différentes représentations de maillages polygonaux sont utilisées pour différentes applications et objectifs. La variété des opérations effectuées sur les maillages peut inclure la logique booléenne, le lissage, la simplification et bien d'autres. Des représentations de réseau, des maillages "streaming" et "progressifs", sont utilisées pour transmettre des maillages polygonaux sur un réseau. Les maillages volumétriques se distinguent des maillages polygonaux en ce qu'ils représentent explicitement à la fois la surface et le volume d'une structure, tandis que les maillages polygonaux ne représentent explicitement que la surface (le volume est implicite). Comme les maillages polygonaux sont largement utilisés en infographie, des algorithmes existent également pour le lancer de rayons, la détection de collision et la dynamique des corps rigides des maillages polygonaux.


Contenu

Nombre de côtés

Les polygones sont principalement classés par le nombre de côtés, voir les polygones de nommage ci-dessous.

Convexité

Les polygones peuvent être caractérisés par leur degré de convexité :

  • Convexe: toute ligne tracée à travers le polygone (et non tangente à une arête ou à un coin) rencontre sa limite exactement deux fois.
  • Non convexe: une ligne peut être trouvée qui rencontre sa limite plus de deux fois.
  • Simple: la limite du polygone ne se croise pas. Tous les polygones convexes sont simples.
  • Concave: Non convexe et simple.
  • En forme d'étoile: tout l'intérieur est visible d'un seul point, sans traverser aucun bord. Le polygone doit être simple et peut être convexe ou concave.
  • Auto-intersection: la limite du polygone se croise. Branko Grünbaum appelle ces copte, bien que ce terme ne semble pas être largement utilisé. Le terme complexe est parfois utilisé par opposition à Facile, mais cela risque de se confondre avec l'idée d'un polygone complexe comme celui qui existe dans le plan de Hilbert complexe composé de deux dimensions complexes.
  • Polygone en étoile: un polygone qui s'auto-intersecte de façon régulière.

Symétrie

  • Équiangle: tous ses angles de coin sont égaux.
  • Cyclique: tous les coins se trouvent sur un seul cercle.
  • Isogonal ou alors sommet-transitif: tous les coins se trouvent dans la même orbite de symétrie. Le polygone est également cyclique et équiangulaire.
  • Équilatéral: toutes les arêtes ont la même longueur. (Un polygone avec 5 côtés ou plus peut être équilatéral sans être convexe.) (Williams 1979, p. 31-32)
  • Isotoxal ou alors bord-transitif: tous les côtés se trouvent dans la même orbite de symétrie. Le polygone est également équilatéral.
  • Régulier. Un polygone est régulier s'il est à la fois cyclique et équilatéral. Un polygone régulier non convexe est appelé un polygone étoilé régulier.

Divers

  • Rectiligne: un polygone dont les côtés se rencontrent à angle droit, c'est-à-dire que tous ses angles intérieurs sont de 90 ou 270 degrés.
  • Monotone par rapport à une ligne donnée L, si chaque ligne orthogonale à L coupe le polygone pas plus de deux fois.

Certaines des méthodes suggérées échoueront dans le cas d'un polygone non convexe, tel qu'un croissant. En voici un simple qui fonctionnera avec des polygones non convexes (il fonctionnera même avec un polygone à intersection automatique comme un huit, vous indiquant si c'est principalement dans le sens des aiguilles d'une montre).

Somme sur les arêtes, (x2 − x1)(y2 + oui1). Si le résultat est positif, la courbe est dans le sens des aiguilles d'une montre, s'il est négatif, la courbe est dans le sens inverse des aiguilles d'une montre. (Le résultat est le double de la zone fermée, avec une convention +/-.)

Je vais jeter une autre solution car elle est simple et pas mathématiquement intensive - elle utilise simplement l'algèbre de base. Calculer l'aire signée du polygone. S'il est négatif, les points sont dans le sens des aiguilles d'une montre, s'il est positif, ils sont dans le sens inverse. (Ceci est très similaire à la solution de Beta.)

Notez que si vous ne vérifiez que la commande, vous n'avez pas besoin de vous embêter à diviser par 2.

Trouvez le sommet avec le plus petit y (et le plus grand x s'il y a des liens). Soit le sommet A et le sommet précédent de la liste B et le sommet suivant de la liste C . Calculez maintenant le signer du produit croisé de AB et AC .

Le produit vectoriel mesure le degré de perpendiculaire de deux vecteurs. Imaginez que chaque arête de votre polygone est un vecteur dans le plan x-y d'un espace xyz tridimensionnel (3-D). Ensuite, le produit vectoriel de deux arêtes successives est un vecteur dans la direction z (direction z positive si le deuxième segment est dans le sens des aiguilles d'une montre, direction z moins s'il est dans le sens inverse des aiguilles d'une montre). L'amplitude de ce vecteur est proportionnelle au sinus de l'angle entre les deux arêtes d'origine, il atteint donc un maximum lorsqu'elles sont perpendiculaires, et diminue pour disparaître lorsque les arêtes sont colinéaires (parallèles).

Ainsi, pour chaque sommet (point) du polygone, calculez la magnitude du produit vectoriel des deux arêtes adjacentes :

Donc, étiquetez les bords consécutivement comme
edgeA est le segment du point0 au point1 et
bordB entre point1 à point2
.
edgeE est compris entre point4 et point0 .

Alors le sommet A ( point0 ) est compris entre
edgeE [Du point4 au point0 ]
edgeA [Du point0 au `point1'

Ces deux arêtes sont elles-mêmes des vecteurs, dont les coordonnées x et y peuvent être déterminées en soustrayant les coordonnées de leurs points de départ et d'arrivée :

edgeE = point0 - point4 = (1, 0) - (5, 0) = (-4, 0) et
bordA = point1 - point0 = (6, 4) - (1, 0) = (5, 4) et

Et le produit vectoriel de ces deux arêtes adjacentes est calculé en utilisant le déterminant de la matrice suivante, qui est construite en plaçant les coordonnées des deux vecteurs sous les symboles représentant les trois axes de coordonnées ( i , j , & k ). La troisième coordonnée (zéro) est là parce que le concept de produit croisé est une construction 3-D, et donc nous étendons ces vecteurs 2-D en 3-D afin d'appliquer le produit croisé :

Étant donné que tous les produits croisés produisent un vecteur perpendiculaire au plan de deux vecteurs multipliés, le déterminant de la matrice ci-dessus n'a qu'une composante k , (ou axe z).
La formule pour calculer l'amplitude de la composante de l'axe k ou z est
a1*b2 - a2*b1 = -4* 4 - 0* 1 = -16

L'amplitude de cette valeur ( -16 ), est une mesure du sinus de l'angle entre les 2 vecteurs originaux, multiplié par le produit des amplitudes des 2 vecteurs.
En fait, une autre formule pour sa valeur est
A X B (produit croisé) = |A| * |B| * péché(AB) .

Donc, pour revenir à une mesure de l'angle, vous devez diviser cette valeur, ( -16 ), par le produit des magnitudes des deux vecteurs.

Donc la mesure de sin(AB) = -16 / 16,4924 = -,97014.

Il s'agit d'une mesure pour savoir si le segment suivant après le sommet s'est plié vers la gauche ou la droite, et de combien. Il n'est pas nécessaire de prendre l'arc sinusoïdal. Nous ne nous soucierons que de sa magnitude, et bien sûr de son signe (positif ou négatif) !

Faites cela pour chacun des 4 autres points autour du chemin fermé et additionnez les valeurs de ce calcul à chaque sommet.

Si la somme finale est positive, vous êtes allé dans le sens horaire, négatif, antihoraire.


Il n'y a aucun moyen de déduire automatiquement l'ordre d'enroulement d'un maillage 3D qui fonctionnera pour chaque entrée possible.

Par exemple, si je vous donne le triangle (0, 0, 0), (1, 0, 0), (0, 1, 0) seul sans autre contexte, vous ne savez pas s'il est destiné à être enroulé contre -dans le sens des aiguilles d'une montre (donc son avant est orienté vers l'extérieur le long de l'axe z-) ou dans le sens des aiguilles d'une montre (donc son avant est orienté vers l'extérieur le long de l'axe z+). (En supposant un système de coordonnées gaucher, mais le système de coordonnées pourrait tout aussi bien être droitier, en retournant le tout)

Ces deux interprétations seraient valides, et vous devrez demander au créateur ou utiliser des connaissances sur le format du maillage ou sur ce qu'il est censé représenter pour déterminer quelle version est destinée.

Mais il existe un cas particulier courant où nous pouvons déduire le revêtement correct avec une plus grande confiance : si vos maillages représentent des objets solides et que vous avez une géométrie de collecteur étanche. (Cela signifie que le maillage forme une surface continue sans trous, espaces, bords lâches ou ailettes unilatérales)

Si vous avez un tel maillage, vous pouvez deviner son enroulement, puis vérifiez si cette supposition a du sens en voyant si elle place la face avant de chaque polygone face "à l'extérieur" du solide plutôt qu'à l'intérieur. (Mais attention : il y a de rares cas où nous fabriquons des maillages qui ont été délibérément retournés pour divers effets, donc même ce test n'est pas infaillible !)

Choisissez un triangle/polygone arbitrairement

Construisez ce polygone normal en fonction de votre enroulement deviné

Lancez un rayon à travers un point de ce polygone, dans la direction opposée à sa normale. Testez ce rayon contre tous les autres polygones du maillage (cela peut coûter cher)

Si vous obtenez un nombre impair de coups (en frappant l'arrière d'un autre polygone, puis peut-être l'avant d'un autre puis l'arrière d'un autre, ou n'importe quel nombre de paires avant-arrière), alors votre estimation sinueuse semble correcte. C'est le modèle que nous nous attendrions à voir lors du tir dans une forme solide.

Si vous obtenez un nombre pair de coups, alors votre estimation d'enroulement était probablement incorrecte et vous devriez utiliser l'enroulement opposé à la place.

Vous pouvez exécuter ce test pour plusieurs exemples de polygones différents dans votre maillage pour obtenir un consensus et essayer d'éliminer les valeurs aberrantes dues à une géométrie non multiple comme les nageoires foliaires unilatérales.

Comme vous pouvez le voir cependant, c'est beaucoup plus de travail et moins de garanties que de simplement inspecter le format de votre source de géométrie pour déterminer quel enroulement est standard pour ce type, ou de demander à celui qui a créé le maillage.

(J'ai à l'origine ignoré ce cas parce que vous avez dit que vous vouliez générer des normales et que vous n'avez pas mentionné que vous les aviez disponibles en entrée. Mais pour être complet.)

Si votre maillage a des vecteurs normaux, alors vous pouvez les utiliser comme vérité terrain pour la direction de face avant prévue (à condition que le créateur du modèle ne fasse rien de trop bizarre avec des normales ajustées manuellement. )

Disons que vous avez un triangle avec des points (dans l'ordre) a , b , c

Calculez la normale attendue de votre triangle en prenant le produit vectoriel :

Maintenant, comparez cela aux normales fournies avec votre maillage (si votre maillage a des normales définies par sommet, vous pouvez faire la moyenne des trois normales de sommet d'un triangle pour obtenir un triangle normal. Ou vous pouvez faire la moyenne de toutes les valeurs normales attendues pour les triangles bordant un sommet pour obtenir un sommet normal à la place)

Si accord > 0, votre maillage est enroulé dans le sens inverse des aiguilles d'une montre lorsque vous le regardez par rapport à sa normale dans un système de coordonnées droitier, ou dans le sens des aiguilles d'une montre si vous êtes dans un système de coordonnées gaucher. Si accord < 0 alors votre maillage est enroulé dans le sens des aiguilles d'une montre dans un système de coordonnées droitier, ou dans le sens inverse des aiguilles d'une montre si vous êtes dans un système de coordonnées gaucher. Si la concordance est nulle, le test n'est pas concluant pour ce triangle (quelqu'un a poussé les normales d'entrée pour qu'elles soient proches de zéro ou presque parallèles à la surface pour une raison quelconque), et vous pouvez réessayer avec une autre partie du maillage.


AsSVG

Accepte un champ ou une expression géographique unique et renvoie une représentation graphique vectorielle évolutive (SVG) de la géométrie.

Argument de mot clé La description
relatif Si défini sur True , les données de chemin seront implémentées en termes de déplacements relatifs. La valeur par défaut est False , ce qui signifie que les déplacements absolus sont utilisés à la place.
précision Ce mot-clé peut être utilisé pour spécifier le nombre de chiffres significatifs pour les coordonnées dans la représentation SVG – la valeur par défaut est 8.


3 réponses 3

Votre question n'est pas assez précise. Un tableau de points est uniquement « 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 horaire à droite, exactement les mêmes points sont ordonnés dans le sens antihoraire.

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 :

  • soit P[0], P[1], . P[n-1] la liste des points à trier
  • soit M le barycentre de tous les points
  • calculer a[0], a[1], . a[n-1] tel que a[i] = atan2(P[i].y - M.y, P[i].x - M.x)
  • trier les points par rapport à leur valeur a, en utilisant qsort 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 de atan2 est toujours valide, mais n'utilisez tout simplement pas qsort .

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 le sens des aiguilles d'une montre ou dans le sens inverse des aiguilles d'une montre, et donc tout ce que vous avez à faire est de vérifier lequel de ces deux c'est et d'inverser l'ordre des indices si l'enroulement n'est pas celui que tu veux.

Voici l'idée générale, en supposant que les trois sommets d'un triangle sont une, b, et c, et que vous avez une simple opération de soustraction vectorielle :

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 des aiguilles d'une montre" et "dans le sens inverse des aiguilles d'une montre" peuvent être inversés par rapport à la façon dont je les ai étiquetés dans les commentaires de cet exemple de code.

Pouvez-vous donner plus d'informations? Vous voulez un ordre de points CCW, mais quel point doit être le centre de l'ordre ?

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 (3ème coordonnée est 1). Si le déterminant est > 0, les points sont dans l'ordre CCW. Sinon, vous pouvez basculer par exemple les deux derniers points et vous obtiendrez une commande CCW.

Si vous avez les 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 avec zéro. Si c'est > 0, retourne les points A, B, C, si ce n'est pas le cas, retourne A, C, B.

Si vous avez un ensemble de points et savez, ils font un polygone convexe (tous font partie d'une coque convexe), et que vous voulez obtenir leur ordre, vous pouvez utiliser Graham Scan ou Jarvis's March (ce sont des algorithmes pour trouver une coque convexe à partir de nombreux points, mais ça devrait aussi marcher ici :) )


Syntaxe

Raster en entrée à partir duquel les cellules seront extraites.

Un polygone (ou des polygones) qui définit la zone du raster en entrée à extraire.

Chaque partie de polygone est une liste de sommets définis par des classes de points. Les points sont spécifiés sous forme de paires de coordonnées x,y dans les mêmes unités de carte que le raster en entrée.

La forme de l'objet pour un seul polygone est la suivante :

Facultativement, un groupe de plusieurs polygones peut être spécifié à l'aide d'une classe Polygon pour définir une liste de parties de polygone. Notez que pour ce faire, toutes les parties doivent être contiguës, et donc être englobées par une seule forme de périmètre. La forme de l'objet dans ce cas serait dans une liste contiguë comme suit :

Dans tous les cas, la dernière coordonnée de chaque partie de polygone doit être la même que la première afin de la fermer.

Identifie s'il faut extraire les cellules à l'intérieur ou à l'extérieur du polygone en entrée.

  • INSIDE —Un mot-clé spécifiant que seules les cellules à l'intérieur du polygone en entrée doivent être sélectionnées et écrites dans le raster en sortie. Toutes les cellules en dehors du polygone recevront des valeurs NoData sur le raster en sortie.
  • OUTSIDE —Un mot-clé spécifiant que les cellules en dehors du polygone en entrée doivent être sélectionnées et écrites dans le raster en sortie. Toutes les cellules à l'intérieur du polygone recevront NoData.

Valeur de retour

Raster en sortie contenant les valeurs de cellule extraites du raster en entrée.


Syntaxe

Raster en entrée à partir duquel les cellules seront extraites.

Un polygone (ou des polygones) qui définit la zone du raster en entrée à extraire.

Chaque partie de polygone est une liste de sommets définis par des classes de points. En option, une classe Polygon peut être utilisée pour définir une liste de parties de polygone.

Les points sont spécifiés sous forme de paires de coordonnées x,y dans les mêmes unités de carte que le raster en entrée. La forme de l'objet est :

Notez que la dernière coordonnée doit être la même que la première afin de fermer un polygone.

Identifie s'il faut extraire les cellules à l'intérieur ou à l'extérieur du polygone en entrée.

  • INSIDE — Un mot-clé spécifiant que les cellules à l'intérieur du polygone en entrée doivent être sélectionnées et écrites dans le raster en sortie. Toutes les cellules en dehors du polygone recevront des valeurs NoData sur le raster en sortie.
  • OUTSIDE — Un mot-clé spécifiant que les cellules à l'extérieur du polygone en entrée doivent être sélectionnées et écrites dans le raster en sortie. Toutes les cellules à l'intérieur du polygone recevront des valeurs NoData sur le raster en sortie.

Valeur de retour

Raster en sortie contenant les valeurs de cellule extraites du raster en entrée.


API ArcGIS pour JavaScript 3.36

Un moteur de géométrie côté client. Si plusieurs géométries sont requises pour l'une des méthodes ci-dessous, toutes les géométries doivent avoir la même référence spatiale pour que la méthode fonctionne comme prévu. Voir la méthode union pour un exemple de code.

Limite connue : Cette classe n'est prise en charge qu'en utilisant la syntaxe de codage de style AMD.

Échantillons

Méthodes

NomType de retourRésumé
buffer(géométrie, distance, unité, unionResults ?) Polygone | Polygone[] Crée des polygones tampons planaires (ou euclidiens) à une distance spécifiée autour des géométries en entrée.
clip (géométrie, enveloppe) Géométrie Calcule la géométrie découpée à partir d'une géométrie cible par une enveloppe.
contient (containerGeometry, insideGeometry) booléen Indique si une géométrie contient une autre géométrie.
convexHull(géométrie, fusionner?) Géométrie | Géométrie[] Calcule l'enveloppe convexe de la géométrie en entrée.
croix(géométrie1, géométrie2) booléen Indique si une géométrie croise une autre géométrie.
coupe (géométrie, fraise) Géométrie[] Divisez la polyligne ou le polygone d'entrée à l'endroit où il croise une polyligne de coupe.
densifier(géométrie, maxSegmentLength, maxSegmentLengthUnit) Géométrie Densifier les géométries en traçant des points entre les sommets existants.
différence (inputGeometry, soustracteur) Géométrie | Géométrie[] Crée la différence de deux géométries.
disjoint(géométrie1, géométrie2) booléen Indique si une géométrie est disjointe (n'intersecte en aucune façon) avec une autre géométrie.
distance(géométrie1, géométrie2, distanceUnit) Numéro Calcule la distance plane la plus courte entre deux géométries.
égal(géométrie1, géométrie2) booléen Indique si deux géométries sont égales.
ExtendedSpatialReferenceInfo(spatialReference) Objet Renvoie un objet contenant des informations supplémentaires sur la référence spatiale d'entrée.
flipHorizontal(géométrie, flipOrigin?) Géométrie Inverse une géométrie sur l'axe horizontal.
flipVertical(géométrie, flipOrigin ?) Géométrie Inverse une géométrie sur l'axe vertical.
generalize(geometry, maxDeviation, removeDegenerateParts?, maxDeviationUnit?) Géométrie Effectue l'opération de généralisation sur les géométries du curseur.
geodesicArea(géométrie, unité) Numéro Calcule l'aire de la géométrie en entrée.
geodesicBuffer(géométrie, distance, unité, unionResults ?) Polygone | Polygone[] Crée des polygones tampons géodésiques à une distance spécifiée autour des géométries en entrée.
geodesicDensify(geometry, maxSegmentLength, maxSegmentLengthUnit ?) Géométrie Renvoie une version géodésiquement densifiée de la géométrie en entrée.
geodesicLength(géométrie, unité) Numéro Calcule la longueur de la géométrie d'entrée.
intersection(géométrie, intersecteur) Géométrie | Géométrie[] Crée une nouvelle géométrie par intersection entre deux géométries.
intersection(géométrie1, géométrie2) booléen Indique si une géométrie croise une autre géométrie.
estSimple (géométrie) booléen Indique si la géométrie donnée est topologiquement simple.
la coordonnée la plus proche (géométrie, point d'entrée) Objet Recherche la coordonnée de la géométrie la plus proche du point spécifié.
le plus procheVertex(géométrie, inputPoint) Objet Recherche le sommet de la géométrie la plus proche du point spécifié.
NearVertices(geometry, inputPoint, searchRadius, maxVertexCountToReturn) Objet[] Recherche tous les sommets à la distance donnée du point spécifié, triés du plus proche au plus éloigné et les renvoie sous forme de tableau d'objets.
offset(geometry, offsetDistance, offsetUnit, joinType, bevelRatio?, flattenError?) Géométrie | Géométrie[] L'opération de décalage crée une géométrie qui est à une distance plane constante d'une polyligne ou d'un polygone en entrée.
chevauchements(géométrie1, géométrie2) booléen Indique si une géométrie chevauche une autre géométrie.
planarArea(géométrie, unité) Numéro Calcule l'aire de la géométrie en entrée.
planarLength(géométrie, unité) Numéro Calcule la longueur de la géométrie d'entrée.
relier(géométrie1, géométrie2, relation) booléen Indique si la relation DE-9IM donnée est valable pour les deux géométries.
rotation(géométrie, angle, rotationOrigine ?) Géométrie Fait pivoter une géométrie d'un angle spécifié.
simplifier (la géométrie) Géométrie Effectue l'opération de simplification sur la géométrie qui modifie les géométries données pour rendre leurs définitions topologiquement légales par rapport à leur type de géométrie.
symétriqueDifférence(leftGeometry, rightGeometry) Géométrie | Géométrie[] Crée la différence symétrique de deux géométries.
touche(géométrie1, géométrie2) booléen Indique si une géométrie touche une autre géométrie.
union(géométries) Géométrie Toutes les entrées doivent être du même type de géométries et partager une référence spatiale.
inside(innerGeometry, externalGeometry) booléen Indique si une géométrie se trouve dans une autre géométrie.

Buffer(géométrie, distance, unité, unionResults ?)

Crée des polygones tampons planaires (ou euclidiens) à une distance spécifiée autour des géométries en entrée.


Voir la vidéo: Les pôlygones ; cotés et sommets. Géométrie (Octobre 2021).