10
votes

Comment puis-je dire si deux polygones se croisent?

Imaginez que j'ai la coordonnée de 4 points formant un polygone. Ces points sont représentés à l'aide de pointu en C #. Si j'ai 2 polygones (en utilisant 8 points), comment puis-je dire s'ils se croisent?

La classe Rectangle a une méthode appelée intersectswith mais je n'ai pas pu trouver quelque chose de similaire pour GraphicsPath ou région.

Tout conseil serait grandement apprécié.

mosh


0 commentaires

4 Réponses :


1
votes

Si vos polygones sont convexes, vous devriez pouvoir utiliser séparateur théorème d'axe . Une démo est disponible ici (c'est dans ActionScript mais le code doit être facile. au port à C #)

Ce n'est vraiment pas ma région mais j'espère que cela aide quand même.


0 commentaires

6
votes

Comme Charlie a déjà signalé que vous pouvez utiliser le théorème de l'axe de séparation. Découvrez Cet article pour une implémentation et exemple de la détection de collision polygone .

J'ai également répondu à cette question ici qui traite de la collision 2D en C #.


0 commentaires

4
votes

Strictement parler, les autres réponses suggérant un algorithme sont probablement votre meilleur choix. Mais de côté de côté, vous avez mentionné que vous ne pouviez trouver rien comme intersectswith pour GraphicsPath ou région. Cependant, il existe une méthode d'intersection qui met à jour une région pour être l'intersection de lui-même et une autre région ou une autre voie. Vous pouvez créer deux régions, Intersect ( ) Un avec l'autre, puis testez pour Région.Impty ().

Mais j'imagine que c'est probablement un moyen assez lent de le faire et entraînerait probablement beaucoup d'allocations si elles sont faites dans une boucle.


1 commentaires

Étonnamment, je ne remarque pas de ralentissement si les deux ne sont pas intersectés. Seulement lorsque les régions se croisent, il y a un ralentissement notable. (Les régions que les tests ne sont pas particulièrement compliquées, cependant.)



2
votes

C'est une ancienne question, mais je pensais que je partagerais ma solution aussi. Région.Impty () nécessite un contexte graphique et de ma compréhension n'est conçu que pour effectuer des tests de pixels de précision. Ce n'est pas idéal pour de nombreuses situations. Une solution bien meilleure consiste à utiliser la bibliothèque Clipper de Angus Johnson. D'après mon expérience, il s'agit d'une bibliothèque rapide bien testée. Vous pouvez fournir votre propre précision et gère des polygones extrêmement complexes.

http: //www.angusj .com / delphi / clipper.php p>

Il y a une implémentation C #. Ce que vous devriez faire, c'est effectuer une opération d'intersection, comme la méthode System.Drawing.Drawing.ReGion. Examinez ensuite le résultat de l'opération. S'il est vide, il n'y avait pas d'intersection. S'il contient des données, les données sont les points d'intersection. P>

http: // www.angusj.com/delphi/clipper/documentation/docs/units/clipperlib/types/cliptype.htm p>

Certaines méthodes que vous trouveriez utiles pour cela. P>

        public static GraphicsPath intersect(ref GraphicsPath p1, ref GraphicsPath p2)
    {
        List<List<IntPoint>> polygonB = ConvertToClipperPolygons(p1);
        List<List<IntPoint>> polygons = new List<List<IntPoint>>();
        List<List<IntPoint>> polygonA = ConvertToClipperPolygons(p2);

        Clipper c = new Clipper();
        c.AddPolygons(polygonB, PolyType.ptSubject);
        c.AddPolygons(polygonA, PolyType.ptClip);
        c.Execute(ClipType.ctIntersection, polygons, PolyFillType.pftEvenOdd, PolyFillType.pftEvenOdd);

        return ConvertClipperToGraphicsPath(polygons);
    }
        public static GraphicsPath ConvertClipperToGraphicsPath(List<List<IntPoint>> path)
    {
        GraphicsPath returnPath = new GraphicsPath();

        for (int i = 0; i < path.Count; i++)
        {
            returnPath.AddPolygon(ToPointList(path[i]).ToArray());
        }
        return returnPath;
    }
        private static List<PointF> ToPointList(List<IntPoint> pointList)
    {

        List<PointF> newList = new List<PointF>();
        foreach (IntPoint pt in pointList)
        {
            newList.Add(new PointF(((float)pt.X / (float)scale), ((float)pt.Y / (float)scale)));
        }

        return newList;
    }


0 commentaires