IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Mathématiques Discussion :

Polygone minimum englobant


Sujet :

Mathématiques

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Août 2005
    Messages
    346
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 346
    Points : 119
    Points
    119
    Par défaut Polygone minimum englobant
    Bonjour,

    j'ai un petit probleme de geometrie que je n'arrive pas à resoudre:

    j'ai une liste de rectangles (4 coordonnées [x,y] par rectangle).
    Je dois determiner le polygone englobant tous ces rectangles.

    Avec le module Math-Geometry-Planar, j'arrive à obtenir le rectangle minimum englobant (plus grand que le polygone que je veux pouvoir obtenir en général) ou l'enveloppe convexe englobant ces polygones... qui est presque ce que je veux sauf que c'est convexe, justement... (c'est à dire encore plus grand que le polygone que je dois obtenir, generalement).

    Sur l'image, on devine en traits fins 2 rectangles (1 petit et un plus grand dessous). En traits gras, c'est le polygone minimum englobant mes 2 rectangles. C'est ce que je veux obtenir, mais je n'y arrive pas.

    Y-a-t-il un géomathématicien dans la salle ?

    Merci de m'avoir lu...
    Images attachées Images attachées  

  2. #2
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    il faut une methode optimisée pour les rectangles, ou une methode générale ?
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Août 2005
    Messages
    346
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 346
    Points : 119
    Points
    119
    Par défaut
    MMmh... il me faut une methode qui marche, je n'ai pas besoin d'un truc optimisé niveau vitesse d'exécution, je n'aurai pas des milliers de rectangles dans ma liste.

    Je précisais juste ce dont je disposais. Mon principal souci, c'est le fait que le polygone final (l'enveloppe) peut etre concave.
    Autre précision: je controle l'ordre et le sens des points de mes rectangles.

    En fait, en terme math je crois que je cherche l'union de tous mes polygones ? mais je ne suis pas matheux, je cherche un pédagogue en plus d'un geomathicien

  4. #4
    Membre éclairé

    Profil pro
    Inscrit en
    Septembre 2006
    Messages
    717
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2006
    Messages : 717
    Points : 858
    Points
    858
    Par défaut
    Regarde du coté des algorithmes d'union de polygones, cela ce trouve facilement sur le net. Ton problème est juste un cas particulier ou tous les polygones sont des rectangles.

  5. #5
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Oups... désolé pour l'attente, un petit pb avec une base SQL

    En fait, en terme math je crois que je cherche l'union de tous mes polygones ? mais je ne suis pas matheux, je cherche un pédagogue en plus d'un geomathicien
    Arf... pas de bol, moi je fais juste dans l'algorithmie.

    Citation Envoyé par Splug Voir le message
    MMmh... il me faut une methode qui marche, je n'ai pas besoin d'un truc optimisé niveau vitesse d'exécution, je n'aurai pas des milliers de rectangles dans ma liste.

    Bon, deja il faut savoir que ce probleme (minimum area hull) n'est pas simple.

    Une methode simple (mais pas rapide), consiste a partir d'un sommet (exterieur) et suivre une des arretes. A chaque intersection, on choisi de se déplacer sur une arrete qui mene directement a un sommet/intersection exterieur.

    Ca a l'air compliqué comme ca, mais on peut faire plein d'optimisation et calculer les intersections et les points exterieurs au fur et a mesure de la progression.

    Hum... je viens de me relire et ca n'a pas l'air clair. Essaye avec un papier et un crayon et dis moi si tu vois de quoi je parle...
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Août 2005
    Messages
    346
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 346
    Points : 119
    Points
    119
    Par défaut
    Une methode simple (mais pas rapide), consiste a partir d'un sommet (exterieur) et suivre une des arretes. A chaque intersection, on choisi de se déplacer sur une arrete qui mene directement a un sommet/intersection exterieur.

    Ca a l'air compliqué comme ca, mais on peut faire plein d'optimisation et calculer les intersections et les points exterieurs au fur et a mesure de la progression.
    Oui, je vois tout à fait la méthode, c'est comme ça que ferait mon cerveau, mais je ne vois pas comment écrire ça en code ... , le fait de suivre les arretes. Ca devient vectoriel là et ce n'est pas non plus mon fort (me demandez pas ce que je fous à faire ça, dans ce cas, svp )

    Merci en tout cas pour ta réponse pseudocode

  7. #7
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Splug Voir le message
    Oui, je vois tout à fait la méthode, c'est comme ça que ferait mon cerveau, mais je ne vois pas comment écrire ça en code ... , le fait de suivre les arretes. Ca devient vectoriel là et ce n'est pas non plus mon fort (me demandez pas ce que je fous à faire ça, dans ce cas, svp )

    Merci en tout cas pour ta réponse pseudocode
    Deja, si tu as pigé le principe, c'est bon.

    Maintenant, tu peux chercher/copier/coller sur le net l'algo de Weiler-Atherton qui est une application de ce principe.

    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Août 2005
    Messages
    346
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 346
    Points : 119
    Points
    119
    Par défaut
    oui c'est ce que j'ai compris ensuite, je regarderai la version 'english' car celle en français http://pilat.free.fr/pdf/weiler.pdf m'est aussi hermétique qu'elle l'est à aidos sur ce topic http://www.developpez.net/forums/sho...d.php?t=254203

    Ca semble clair, mais en fait non .
    Je regarderai dans http://www.cs.drexel.edu/~david/Clas...214-weiler.pdf qui est peut-être mieux.

    Bonne journée et encore merci.

  9. #9
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    Citation Envoyé par Splug Voir le message
    oui c'est ce que j'ai compris ensuite, je regarderai la version 'english' car celle en français http://pilat.free.fr/pdf/weiler.pdf m'est aussi hermétique qu'elle l'est à aidos sur ce topic http://www.developpez.net/forums/sho...d.php?t=254203
    bah, si t'as compris le principe de suivre les arrêtes vers les points exterieurs, ca roule tout seul.

    L'astuce dans Weiler-Atherton c'est de remarquer que lorsqu'on cherche le perimetre exterieur de 2 polygones, on passe d'un polygone a l'autre a chaque intersection (sinon on entre dans la surface commune au lieu d'en faire le tour).

    Je savais pas que la question avait deja été résolue par Nemerle (). Désolé Nemerle, j'ai fait une recherche sur "Weiler-Atherton" et pas juste sur "Weiler".
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  10. #10
    Membre éprouvé Avatar de Nemerle
    Inscrit en
    Octobre 2003
    Messages
    1 106
    Détails du profil
    Informations personnelles :
    Âge : 53

    Informations forums :
    Inscription : Octobre 2003
    Messages : 1 106
    Points : 1 213
    Points
    1 213
    Par défaut
    C'est moi qui avait répondu à ça??? Ma mémoire me lache.... gnéégnééé
    Nemerle, mathématicopilier de bars, membre du triumvirat du CSTM, 3/4 centre

  11. #11
    En attente de confirmation mail
    Inscrit en
    Novembre 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 3
    Points : 3
    Points
    3
    Par défaut Une réponse en C#
    Hello,

    Mon code, en C# (je n'ai rien pompé nul part):
    Il n'utilise aucune lib externe (si ce ne sont quelques structures classiques: tableaux, listes, points [x, y], rectangles [x, y, width, height], ...)
    Il est donc aisement traduisible en d'autres langages, et abondemment commenté.
    L'unique appel se fait par le méthode "compute" ci-dessous, à laquelle on passe une liste de rectangles et qui vous retourne une liste de polygones fermés (= une liste de tableaux de points).
    Il peut en effet y avoir plusieurs polygones s'il n'y a aucune intersection entre certains rectangles.
    A améliorer si des idées vous viennent:

    Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
            /// <summary>
            /// Calcule l'union de plusieurs rectangles (quand ceux-ci s'intersectent)
            /// </summary>
            /// <param name="rectangles">Une liste de rectangles</param>
            /// <returns>Une liste de polygones (un polygone = un tableau de points)</returns>
            public List<Point[]> compute(List<Rectangle> rectangles)
            {
                List<Point[]> result = new List<Point[]>();
                List<Rectangle> intRectangles = new List<Rectangle>(rectangles);
                while (intRectangles.Count > 0)
                {
                    // Conversion du rectangle en polygone, puis destruction du rectangle:
                    Point[] polygon = getPolygon(intRectangles[0]);
                    intRectangles.RemoveAt(0);
     
                    // On réitére sur tous les rectangles tant que le polygone en absorbe:
                    bool changeRecorded = true;
                    while (changeRecorded)
                    {
                        changeRecorded = false;
                        for (int i = 0; (i < intRectangles.Count) && (polygon != null); i++)
                        {
                            Rectangle rect = intRectangles[i];
                            // Union du polygone courant et d'un rectangle
                            if (union(ref polygon, rect))
                            {
                                // Si le polygone a absorbé le rectangle, on supprime le rectangle
                                intRectangles.RemoveAt(i--);
                                changeRecorded = true;
                            }
                        }
                    }
                    if (polygon != null)
                    {
                        // Fermeture du polygone avant stockage:
                        closePolygon(ref polygon);
                        result.Add(polygon);
                    }
                }
                return result;
            }
     
            /// <summary>
            /// Convertit un rectangle en un polygone (non fermé)
            /// </summary>
            /// <param name="rect">Le rectangle à convertir</param>
            /// <returns>Un tableau de points correspondant au polygone</returns>
            private Point[] getPolygon(Rectangle rect)
            {
                Point[] result = new Point[4];
                result[0] = new Point(rect.Left, rect.Top);
                result[1] = new Point(rect.Right, rect.Top);
                result[2] = new Point(rect.Right, rect.Bottom);
                result[3] = new Point(rect.Left, rect.Bottom);
                return result;
            }
     
            /// <summary>
            /// Ferme un polygone
            /// </summary>
            /// <param name="polygon">Le polygone à fermer</param>
            private void closePolygon(ref Point[] polygon)
            {
                // Fermeture du polygone (si nécessaire)
                if ((polygon.Length > 0) && (polygon[polygon.Length - 1] != polygon[0]))
                {
                    Point[] result = new Point[polygon.Length + 1];
                    polygon.CopyTo(result, 0);
                    result[polygon.Length] = result[0];
                    polygon = result;
                }
            }
     
            /// <summary>
            /// Effectue l'union entre un polygone et un rectangle.
            /// Le polygone est modifié si besoin est (extension lors de l'absorption du rectangle).
            /// Si le polygone devient null, ça veut dire que le rectangle le contient entièrement.
            /// </summary>
            /// <param name="polygon">Le polygone</param>
            /// <param name="rect">Le rectangle à ajouter</param>
            /// <returns>true: le rectangle a été absorbé par le polygone, false sinon (intersection vide)</returns>
            private bool union(ref Point[] polygon, Rectangle rect)
            {
                // Recherche d'un point du polygone HORS du rectangle:
                int startPoint = -1;
                for (int i = 0; (i < polygon.Length) && (startPoint == -1); i++)
                {
                    if (!isInRectangle(polygon[i], rect))
                    {
                        startPoint = i;
                    }
                }
                if (startPoint == -1)
                {
                    // Si tout le polygone est contenu dans le rectangle,
                    // alors le polygone disparait mais le rectangle reste:
                    polygon = null;
                    return false;
                }
                else
                {
                    Point[] rectPolygon = getPolygon(rect);
     
                    // Verification de l'intersection entre le polygone et le rectangle
                    // S'il y a intersection: Modifier le polygone si besoin, puis retourner true
                    // Pas d'intersection : retourner false
                    List<Point> points = new List<Point>();
                    bool result = false;
                    bool pIntersectIsValid = false;
                    Point pIntersect = new Point();
     
                    int point = startPoint;
                    // Pour chaque point du polygone:
                    do
                    {
                        int rectIndex;
                        if (!pIntersectIsValid)
                        {
                            // Calcul de l'intersection entre le cote courant du polygone et le rectangle:
                            addPoint(points, polygon[point]);
                            rectIndex = intersect(polygon[point], polygon[(point + 1) % polygon.Length], rectPolygon, ref pIntersect);
                        }
                        else
                        {
                            // Calcul de l'intersection entre un tronçon du coté courant du polygone et le rectangle:
                            pIntersectIsValid = false;
                            rectIndex = intersect(pIntersect, polygon[(point + 1) % polygon.Length], rectPolygon, ref pIntersect);
                        }
                        if (rectIndex != -1)
                        {
                            // Cette arête du polygone croise le rectangle (le rectangle va être absorbé):
                            result = true;
                            addPoint(points, pIntersect);
                            pIntersectIsValid = true;
     
                            // Pour chaque arête du rectangle:
                            do
                            {
                                int polyIndex = pIntersectIsValid ?
                                    intersect(pIntersect, rectPolygon[(rectIndex + 1) % rectPolygon.Length], polygon, ref pIntersect) :
                                    intersect(rectPolygon[rectIndex], rectPolygon[(rectIndex + 1) % rectPolygon.Length], polygon, ref pIntersect);
                                rectIndex = (rectIndex + 1) % rectPolygon.Length;
                                if (polyIndex != -1)
                                {
                                    // L'arête du rectangle croise à nouveau le polygone:
                                    addPoint(points, pIntersect);
                                    point = polyIndex - 1;
                                    pIntersectIsValid = true;
                                }
                                else
                                {
                                    // Ajout du coin du rectangle dans le polygone résultant:
                                    addPoint(points, rectPolygon[rectIndex]);
                                    pIntersectIsValid = false;
                                }
                            }
                            while (!pIntersectIsValid);
                        }
                        point = (point + 1) % polygon.Length;
                    }
                    while (point != startPoint);
                    polygon = points.ToArray();
     
                    // Si le rectangle n'a pas d'intersection ET qu'il est entièrement contenu dans le polygone,
                    // alors le rectangle disparait
                    return (result | isInPolygon(rectPolygon, polygon));
                }
            }
     
            /// <summary>
            /// Ajoute un point à la liste de points de manière optimale.
            /// </summary>
            /// <param name="points">Liste de points</param>
            /// <param name="point">Point à ajouter</param>
            private void addPoint(List<Point> points, Point point)
            {
                if (points.Count > 1)
                {
                    Point prePrevious = points[points.Count - 2];
                    if ((prePrevious.X == point.X) || (prePrevious.Y == point.Y))
                    {
                        // Si le point à ajouter est dans l'alignement des 2 derniers,
                        // le nouveau point remplace directement le dernier point stocké:
                        points[points.Count - 1] = point;
                        return;
                    }
                }
                if ((points.Count == 0) || (points[points.Count - 1] != point))
                {
                    // Ajout du point que s'il n'est pas égal au dernier point stocké (doublon contigu):
                    points.Add(point);
                }
            }
     
            /// <summary>
            /// Indique si un point est à l'interieur d'un rectangle ou non.
            /// </summary>
            /// <param name="p">Point contenu (ou non)</param>
            /// <param name="polygon">Rectangle contenant (ou non)</param>
            /// <returns>true: Le point est à l'intérieur, false sinon</returns>
            private bool isInRectangle(Point p, Rectangle rect)
            {
                return (p.X >= rect.X && p.X <= rect.Right && p.Y >= rect.Y && p.Y <= rect.Bottom);
            }
     
            /// <summary>
            /// Indique si un polygone est entièrement contenu dans un polygone (convexe) ou non.
            /// </summary>
            /// <param name="polygon1">Polygone contenu (ou non)</param>
            /// <param name="polygon2">Polygone contenant (ou non)</param>
            /// <returns>true: Le polygone est entièrement à l'intérieur, false sinon</returns>
            private bool isInPolygon(Point[] polygon1, Point[] polygon2)
            {
                for (int i = 0; i < polygon1.Length; i++)
                {
                    if (!isInPolygon(polygon1[i], polygon2))
                    {
                        return false;
                    }
                }
                return true;
            }
     
            /// <summary>
            /// Indique si un point est à l'interieur d'un polygone ou non.
            /// </summary>
            /// <param name="p">Point contenu (ou non)</param>
            /// <param name="polygon">Polygone contenant (ou non)</param>
            /// <returns>true: Le point est à l'intérieur, false sinon</returns>
            private bool isInPolygon(Point p, Point[] polygon)
            {
                int count = 0;
                for (int i = 0; i < polygon.Length; i++)
                {
                    Point p2a = polygon[i];
                    Point p2b = polygon[(i + 1) % polygon.Length];
                    int minY = (p2a.Y < p2b.Y) ? p2a.Y : p2b.Y;
                    int maxY = (p2a.Y >= p2b.Y) ? p2a.Y : p2b.Y;
                    int maxX = (p2a.X >= p2b.X) ? p2a.X : p2b.X;
                    if ((p.Y > minY) && (p.Y < maxY) && (p.X <= maxX))
                    {
                        count++;
                    }
                }
                return ((count % 2) != 0);
            }
     
            /// <summary>
            /// Calcule l'intersection entre 1 segment et 1 polygone.
            /// </summary>
            /// <param name="p1a">1ere extrémité du segment</param>
            /// <param name="p1b">2eme extrémité du segment</param>
            /// <param name="polygon">Polygone</param>
            /// <param name="result">Point d'intersection si celui-ci a été trouvé</param>
            /// <returns>Index du point précédent le point d'intersection trouvé, -1 sinon</returns>
            private int intersect(Point pa, Point pb, Point[] polygon, ref Point result)
            {
                for (int i = 0; i < polygon.Length; i++)
                {
                    if ((intersect(pa, pb, polygon[i], polygon[(i + 1) % polygon.Length], ref result)) &&
                        (isOrtho(pa, pb, polygon[i], polygon[(i + 1) % polygon.Length])))
                    {
                        return i;
                    }
                }
                return -1;
            }
     
            /// <summary>
            /// Calcule l'intersection entre 2 segments (UNIQUEMENT verticaux ou horizontaux).
            /// </summary>
            /// <param name="p1a">1ere extrémité du 1er segment</param>
            /// <param name="p1b">2eme extrémité du 1er segment</param>
            /// <param name="p2a">1ere extrémité du 2eme segment</param>
            /// <param name="p2b">2eme extrémité du 2eme segment</param>
            /// <param name="result">Point d'intersection si celui-ci a été trouvé</param>
            /// <returns>true: un point d'intersection est trouvé, false sinon</returns>
            private bool intersect(Point p1a, Point p1b, Point p2a, Point p2b, ref Point result)
            {
                if (p1a.X == p1b.X)
                {
                    // p1 Vertical, p2 Horizontal:
                    Point p1Min = (p1a.Y < p1b.Y) ? p1a : p1b;
                    Point p1Max = (p1a.Y >= p1b.Y) ? p1a : p1b;
                    Point p2Min = (p2a.X < p2b.X) ? p2a : p2b;
                    Point p2Max = (p2a.X >= p2b.X) ? p2a : p2b;
                    if (((p1Min.X >= p2Min.X) && (p1Min.X <= p2Max.X)) &&
                        ((p1Min.Y <= p2Min.Y) && (p1Max.Y >= p2Min.Y)))
                    {
                        result = new Point(p1a.X, p2a.Y);
                        return true;
                    }
                }
                else
                {
                    // p1 Horizontal, p2 Vertical:
                    Point p1Min = (p1a.X < p1b.X) ? p1a : p1b;
                    Point p1Max = (p1a.X >= p1b.X) ? p1a : p1b;
                    Point p2Min = (p2a.Y < p2b.Y) ? p2a : p2b;
                    Point p2Max = (p2a.Y >= p2b.Y) ? p2a : p2b;
                    if ((p1Min.Y >= p2Min.Y) && (p1Min.Y <= p2Max.Y) &&
                        (p1Min.X <= p2Min.X) && (p1Max.X >= p2Min.X))
                    {
                        result = new Point(p2a.X, p1a.Y);
                        return true;
                    }
                }
                return false;
            }
     
            /// <summary>
            /// Verifie si 2 segments sont orthonormés.
            /// </summary>
            /// <param name="p1a">1ere extrémité du 1er segment</param>
            /// <param name="p1b">2eme extrémité du 1er segment</param>
            /// <param name="p2a">1ere extrémité du 2ème segment</param>
            /// <param name="p2b">2eme extrémité du 2ème segment</param>
            /// <returns>true: les 2 segments sont orthonormés, false sinon</returns>
            private bool isOrtho(Point p1a, Point p1b, Point p2a, Point p2b)
            {
                int u1 = p1b.X - p1a.X;
                int u2 = p1b.Y - p1a.Y;
                int v1 = p2b.X - p2a.X;
                int v2 = p2b.Y - p2a.Y;
     
                // Le produit vectoriel doit être < 0 (sens anti-horaire)
                return (u1 * v2 - u2 * v1) < 0;
            }

    @+

    François

  12. #12
    Expert éminent
    Avatar de Jedai
    Homme Profil pro
    Enseignant
    Inscrit en
    Avril 2003
    Messages
    6 245
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Côte d'Or (Bourgogne)

    Informations professionnelles :
    Activité : Enseignant

    Informations forums :
    Inscription : Avril 2003
    Messages : 6 245
    Points : 8 586
    Points
    8 586
    Par défaut
    falamargot, quand tu mets un code sur le forum, mets le entre balises CODE (bouton # de l'interface), sinon c'est parfaitement illisible (l'indentation est perdue, il n'y a pas de coloration...) et ça prend trop de place. D'ailleurs quand tu as un code source assez long, il peut être plus avisé de le mettre en pièce jointe.

    --
    Jedaï

  13. #13
    En attente de confirmation mail
    Inscrit en
    Novembre 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Merci Jedai, j'ignorais cette balise.
    C'est beaucoup mieux ainsi, effectivement !

    @+

    François

  14. #14
    Rédacteur
    Avatar de pseudocode
    Homme Profil pro
    Architecte système
    Inscrit en
    Décembre 2006
    Messages
    10 062
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 51
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Architecte système
    Secteur : Industrie

    Informations forums :
    Inscription : Décembre 2006
    Messages : 10 062
    Points : 16 081
    Points
    16 081
    Par défaut
    c'est dans des cas comme ca que je dis MERCI a la librairie standard de Java...

    Code java : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
     
    import java.awt.Rectangle;
    import java.awt.geom.Area;
    import java.awt.geom.PathIterator;
     
    public class TestPath {
    	public static void main(String[] args) {
     
    		Rectangle r1 = new Rectangle(0,0,10,10);
    		Rectangle r2 = new Rectangle(5,5,10,10);
    		Rectangle r3 = new Rectangle(10,10,10,10);
     
    		Area area = new Area();
    		area.add(new Area(r1));
    		area.add(new Area(r2));
    		area.add(new Area(r3));
     
    		if (!area.isSingular()) {
    			System.out.println("le resultat n'est pas un polygone");
    			return;
    		}
     
    		PathIterator pathit = area.getPathIterator(null);
    		while(!pathit.isDone()) {
    			double[] coords = new double[6];
    			pathit.currentSegment(coords);
    			System.out.println("("+coords[0]+","+coords[1]+")");
    			pathit.next();
    		}
    	};
    }

    Comment ca, c'est de la triche ?
    ALGORITHME (n.m.): Méthode complexe de résolution d'un problème simple.

  15. #15
    Membre régulier
    Profil pro
    Inscrit en
    Août 2005
    Messages
    346
    Détails du profil
    Informations personnelles :
    Âge : 41
    Localisation : France, Paris (Île de France)

    Informations forums :
    Inscription : Août 2005
    Messages : 346
    Points : 119
    Points
    119
    Par défaut
    Un grand merci à falamargot, c'est très précisément ce qu'il me fallait... je n'ai pas encore testé mais d'après ce que tu dis, c'est parfait pour moi.

  16. #16
    En attente de confirmation mail
    Inscrit en
    Novembre 2005
    Messages
    3
    Détails du profil
    Informations forums :
    Inscription : Novembre 2005
    Messages : 3
    Points : 3
    Points
    3
    Par défaut
    Il n'y a pas de quoi. Dis-moi si ça marche.
    Attention : j'ai mis à jour (correction d'un bug) la méthode isInPolygon(Point p, Point[] polygon)

    @+

    François

  17. #17
    Candidat au Club
    Profil pro
    Inscrit en
    Juin 2005
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2005
    Messages : 3
    Points : 2
    Points
    2
    Par défaut
    Ok, merci. Je n'ai pas encore essayé, je suis pris par autre chose de plus urgent ces jours ci.
    Quand je l'aurai fait fonctionner, je publierai mon code Perl, des fois que ça intéresse qqun d'autre.

    Bonne journée

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. Polygone au volume minimum
    Par Wizard50 dans le forum Algorithmes et structures de données
    Réponses: 3
    Dernier message: 02/01/2014, 13h59
  2. Comment detecter un polygon sous le curseur
    Par FreshVic dans le forum OpenGL
    Réponses: 2
    Dernier message: 04/07/2003, 10h48
  3. Triangulation de Polygones
    Par seb_lisha dans le forum DirectX
    Réponses: 1
    Dernier message: 01/07/2003, 12h40
  4. [Algo] Point à l'intérieur d'un polygone ?
    Par kebby dans le forum C++Builder
    Réponses: 5
    Dernier message: 23/05/2003, 13h22
  5. une ligne et un polygone convexe
    Par rekam dans le forum Algorithmes et structures de données
    Réponses: 10
    Dernier message: 20/12/2002, 10h39

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo