Comment calculer l’aire d’un polygone 2D?

En supposant une série de points dans un espace 2D qui ne s’auto-intersectent pas, quelle est une méthode efficace pour déterminer l’aire du polygone résultant?

En passant, ce n’est pas un devoir et je ne cherche pas de code. Je cherche une description que je peux utiliser pour implémenter ma propre méthode. J’ai mes idées sur le fait de tirer une séquence de sortingangles de la liste des points, mais je sais qu’il ya beaucoup de cas de bord concernant des polygones convexes et concaves que je n’accepterai probablement pas.

    Voici la méthode standard , AFAIK. Sommez les produits croisés autour de chaque sumt. Beaucoup plus simple que la sortingangulation.

    Code Python, à partir d’un polygone représenté sous la forme d’une liste de coordonnées de sumt (x, y), s’enroulant implicitement du dernier sumt au premier:

    def area(p): return 0.5 * abs(sum(x0*y1 - x1*y0 for ((x0, y0), (x1, y1)) in segments(p))) def segments(p): return zip(p, p[1:] + [p[0]]) 

    Commentaires de David Lehavi: Il convient de mentionner pourquoi cet algorithme fonctionne: c’est une application du théorème de Green pour les fonctions −y et x; exactement comme un planimètre fonctionne. Plus précisement:

    Formule ci-dessus =
    integral_over_perimeter(-y dx + x dy) =
    integral_over_area((-(-dy)/dy+dx/dx) dy dx) =
    2 Area

    Le produit croisé est un classique.

    Si vous avez un tel calcul à faire, essayez la version optimisée suivante qui nécessite deux fois moins de multiplications:

     area = 0; for( i = 0; i < N; i += 2 ) area += x[i+1]*(y[i+2]-y[i]) + y[i+1]*(x[i]-x[i+2]); area /= 2; 

    J'utilise l'indice de tableau pour plus de clarté. Il est plus efficace d'utiliser des pointeurs. Bien que de bons compilateurs le feront pour vous.

    Le polygone est supposé être "fermé", ce qui signifie que vous copiez le premier point en tant que point avec l'indice N. Il suppose également que le polygone a un nombre pair de points. Ajoutez une copie supplémentaire du premier point si N n'est pas pair.

    L'algorithme est obtenu en déroulant et en combinant deux itérations successives de l'algorithme cross produit classique.

    Je ne suis pas sûr de la façon dont les deux algorithmes se comparent en ce qui concerne la précision numérique. Mon impression est que l'algorithme ci-dessus est meilleur que l'algorithme classique, car la multiplication a tendance à restaurer la perte de précision de la soustraction. Lorsqu'elles sont contraintes d'utiliser des flottants, comme avec les GPU, cela peut faire une différence significative.

    EDIT: "Zone de sortingangles et de polygones 2D et 3D" décrit une méthode encore plus efficace

     // "close" polygon x[N] = x[0]; x[N+1] = x[1]; y[N] = y[0]; y[N+1] = y[1]; // compute area area = 0; for( size_t i = 1; i <= N; ++i ) area += x[i]*( y[i+1] - y[i-1] ); area /= 2; 

    Cette page montre que la formule

    entrer la description de l'image ici

    peut être simplifié pour:

    entrer la description de l'image ici

    Si vous écrivez quelques termes et que vous les groupez selon des facteurs communs à xi , l’égalité n’est pas difficile à voir.

    La sommation finale est plus efficace car elle ne nécessite que n multiplications au lieu de 2n .

     def area(x, y): return abs(sum(x[i] * (y[i + 1] - y[i - 1]) for i in xrange(-1, len(x) - 1))) / 2.0 

    J’ai appris cette simplification de Joe Kington, ici .


    Si vous avez NumPy, cette version est plus rapide (pour tous les tableaux sauf les très petits):

     def area_np(x, y): x = np.asanyarray(x) y = np.asanyarray(y) n = len(x) shift_up = np.arange(-n+1, 1) shift_down = np.arange(-1, n-1) return (x * (y.take(shift_up) - y.take(shift_down))).sum() / 2.0 

    Un ensemble de points sans aucune autre contrainte ne définit pas nécessairement un polygone de manière unique.

    Donc, vous devez d’abord décider quel polygone construire à partir de ces points – peut-être la shell convexe? http://en.wikipedia.org/wiki/Convex_hull

    Ensuite, sortingangulez et calculez la surface. http://www.mathopenref.com/polygonirregulararea.html

    Pour développer les zones de sortingangle sortingangular et sum, celles-ci fonctionnent si vous avez un polygone convexe OU si vous choisissez un point qui ne génère pas de lignes à chaque autre point qui coupe le polygone.

    Pour un polygone général sans intersection, vous devez additionner le produit croisé des vecteurs (sharepoint référence, point a), (sharepoint référence, point b), où a et b sont “à côté” l’un de l’autre.

    En supposant que vous ayez une liste de points qui définissent le polygone dans l’ordre (l’ordre étant les points i et i + 1 forment une ligne du polygone):

    Somme (produit croisé ((point 0, point i), (point 0, point i + 1)) pour i = 1 à n – 1.

    Prenez l’ampleur de ce produit croisé et vous avez la surface.

    Cela manipulera les polygones concaves sans avoir à se soucier de choisir un bon sharepoint référence; les trois points qui génèrent un sortingangle qui ne se trouve pas dans le polygone auront un produit croisé qui pointe dans la direction opposée de tout sortingangle situé à l’intérieur du polygone, de sorte que les zones sont correctement additionnées.

    Pour calculer l’aire du polygone

    http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=geometry1#polygon_area

     int cross(vct a,vct b,vct c) { vct ab,bc; ab=ba; bc=cb; return ab.x*bc.y-ab.y*bc.x; } double area(vct p[],int n) { int ar=0; for(i=1;i+1 

    Ou faire une intégrale de contour. Le théorème de Stokes vous permet d’exprimer une intégrale de zone en tant qu’intégrale de contour. Une petite quadrature de Gauss et Bob est ton oncle.

    Une façon de le faire serait de décomposer le polygone en sortingangles , de calculer l’aire des sortingangles et de prendre la sum comme surface du polygone.

    1. Définissez un sharepoint base (le point le plus convexe). Ce sera votre sharepoint pivotement des sortingangles.
    2. Calculez le point le plus à gauche (arbitraire), autre que votre sharepoint base.
    3. Calculez le deuxième point le plus à gauche pour compléter votre sortingangle.
    4. Enregistrez cette zone sortingangulée.
    5. Passez d’un point à l’autre chaque itération.
    6. Somme les zones sortingangulées

    Mieux que sumr les sortingangles, on fait la sum des trapèzes dans l’espace cartésien:

     area = 0; for (i = 0; i < n; i++) { i1 = (i + 1) % n; area += (vertex[i].y + vertex[i1].y) * (vertex[i1].x - vertex[i].x) / 2.0; } 

    solution indépendante de la langue:

    DONNÉ: un polygone peut TOUJOURS être composé de n-2 sortingangles qui ne se chevauchent pas (n = nombre de points OU côtés). 1 sortingangle = polygone à 3 côtés = 1 sortingangle; 1 carré = polygone à 4 côtés = 2 sortingangles; etc ad nauseam QED

    par conséquent, un polygone peut être réduit en “découpant” des sortingangles et la surface totale sera la sum des surfaces de ces sortingangles. essayez-le avec un morceau de papier et des ciseaux, il est préférable de visualiser le processus avant de le suivre.

    Si vous prenez 3 points consécutifs dans un tracé de polygones et créez un sortingangle avec ces points, vous aurez un et un seul des trois scénarios possibles:

    1. le sortingangle résultant est complètement à l’intérieur du polygone d’origine
    2. le sortingangle résultant est totalement en dehors du polygone d’origine
    3. le sortingangle résultant est partiellement contenu dans le polygone d’origine

    nous nous intéressons uniquement aux cas relevant de la première option (totalement contenus).

    chaque fois que nous en trouvons un, nous le découpons, calculons sa surface (easy peasy, n’expliquera pas la formule ici) et créons un nouveau polygone avec un côté de moins (équivalent au polygone avec ce sortingangle coupé). jusqu’à ce qu’il ne rest plus qu’un sortingangle.

    comment mettre en œuvre ce programme par programmation:

    créer un tableau de points (consécutifs) représentant le chemin AROUND du polygone. commencer au point 0. exécuter le tableau en faisant des sortingangles (un à la fois) à partir des points x, x + 1 et x + 2. Transformez chaque sortingangle d’une forme en une zone et recoupez-le avec la zone créée à partir du polygone. Si l’intersection résultante est identique au sortingangle d’origine, alors ce sortingangle est totalement contenu dans le polygone et peut être coupé. retirer x + 1 du tableau et recommencer à partir de x = 0. sinon (si le sortingangle est en dehors du polygone [partiellement ou complètement]), passez au point suivant x + 1 dans le tableau.

    De plus, si vous souhaitez intégrer le mappage et que vous démarrez à partir de géopoints, vous devez convertir les géopoints en points de contrôle FIRST. cela nécessite de choisir un modèle et une formule pour la forme de la terre (bien que nous ayons tendance à considérer la terre comme une sphère, il s’agit en réalité d’un ovoïde irrégulier (forme d’œuf), avec des bosses). il existe de nombreux modèles, pour plus d’informations wiki. Une question importante est de savoir si vous considérerez ou non la zone comme un avion ou une courbe. En général, les “petites” zones, séparées les unes des autres par des points, ne génèrent pas d’erreur significative si elles sont planes et non convexes.

    La mise en œuvre de la formule de lacet pourrait être faite dans Numpy. En supposant ces sumts:

     import numpy as np x = np.arange(0,1,0.001) y = np.sqrt(1-x**2) 

    Nous pouvons définir la fonction suivante pour trouver une zone:

     def PolyArea(x,y): return 0.5*np.abs(np.dot(x,np.roll(y,1))-np.dot(y,np.roll(x,1))) 

    Et obtenir des résultats:

     print PolyArea(x,y) # 0.26353377782163534 

    Éviter la boucle rend cette fonction ~ 50 fois plus rapide que PolygonArea :

     %timeit PolyArea(x,y) # 10000 loops, best of 3: 42 µs per loop %timeit PolygonArea(zip(x,y)) # 100 loops, best of 3: 2.09 ms per loop 

    Note: j’avais écrit cette réponse pour une autre question , je mentionne simplement ceci ici pour avoir une liste complète des solutions.

    Mon inclination serait simplement de commencer à couper des sortingangles. Je ne vois pas comment autre chose pourrait éviter d’être terriblement poilue.

    Prenez trois points séquentiels qui composent le polygone. Assurez-vous que l’angle est inférieur à 180. Vous avez maintenant un nouveau sortingangle qui ne devrait poser aucun problème, supprimez le point central de la liste de points du polygone. Répétez jusqu’à ce qu’il ne vous rest plus que trois points.

    C façon de faire cela:

     float areaForPoly(const int numVerts, const Point *verts) { Point v2; float area = 0.0f; for (int i = 0; i 

    Code Python

    Comme décrit ici: http://www.wikihow.com/Calculate-the-Area-of-a-Polygon

    Avec des pandas

     import pandas as pd df = pd.DataFrame({'x': [10, 20, 20, 30, 20, 10, 0], 'y': [-10, -10, -10, 0, 10, 30, 20]}) df = df.append(df.loc[0]) first_product = (df['x'].shift(1) * df['y']).fillna(0).sum() second_product = (df['y'].shift(1) * df['x']).fillna(0).sum() (first_product - second_product) / 2 600 

    Je vais donner quelques fonctions simples pour calculer la surface du polygone 2D. Cela fonctionne pour les polygones convexes et concaves. nous divisons simplement le polygone en plusieurs sous-sortingangles.

     //don't forget to include cmath for abs function struct Point{ double x; double y; } // cross_product double cp(Point a, Point b){ //returns cross product return ax*by-ay*bx; } double area(Point * vertices, int n){ //n is number of sides double sum=0.0; for(i=0; i