Aller au contenu

Superposition de polylignes


coyotte

Messages recommandés

Salut,

 

Tu peux essayer ces méthodes d'extensions.

pline1.IsOverlapedTo(pline2) renvoie true si pline1 est entièrement superposée à pline2 (les points de départ et de fin de pline1 peuvent être à l'intériaue de pline2).

 

    static class Extension
   {
       /// <summary>
       /// Evalue si le point se situe sur la courbe en utilisant la tolérance globale.
       /// </summary>
       /// <param name="curve">Courbe à laquelle s'applique la méthode.</param>
       /// <param name="point">point à évaluer.</param>
       /// <returns>true, si le point est sur la courbe ; false, sinon.</returns>
       public static bool IsPointOn(this Curve curve, Point3d point) =>
           curve.GetClosestPointTo(point, false).IsEqualTo(point);

       /// <summary>
       /// Evalue si le point se situe sur la courbe en utilisant la tolérance spécifiée.
       /// </summary>
       /// <param name="curve">Courbe à laquelle s'applique la méthode.</param>
       /// <param name="point">point à évaluer.</param>
       /// <param name="tolerance">Tolérance à appliquer.</param>
       /// <returns>true, si le point est sur la courbe ; false, sinon.</returns>
       public static bool IsPointOn(this Curve curve, Point3d point, Tolerance tolerance) =>
           curve.GetClosestPointTo(point, false).IsEqualTo(point, tolerance);

       /// <summary>
       /// Evalue si la polyligne est entièrement superposée à la polyligne spécifiée en utilisant la tolérance globale. 
       /// </summary>
       /// <param name="pline1">Polyligne à laquelle s'applique la méthode.</param>
       /// <param name="pline2">Polyligne de base.</param>
       /// <returns>true, si la polyligne est superposée ; false, sinon.</returns>
       public static bool IsOverlapedTo(this Polyline pline1, Polyline pline2)
       {
           int nbSegments = pline1.NumberOfVertices - 1;
           if (pline1.Closed)
               nbSegments++;
           for (int i = 0; i < nbSegments; i++)
           {
               if (!pline2.IsPointOn(pline1.GetPoint3dAt(i)))
                   return false;
               if (!pline2.IsPointOn(pline1.GetPointAtParameter(i + 0.5)))
                   return false;
           }
           if (pline1.Closed &&
               !pline2.IsPointOn(pline1.GetPointAtParameter(nbSegments)))
               return false;
           return true;
       }

       /// <summary>
       /// Evalue si la polyligne est entièrement superposée à la polyligne spécifiée en utilisant la tolérance spécifiée. 
       /// </summary>
       /// <param name="pline1">Polyligne à laquelle s'applique la méthode.</param>
       /// <param name="pline2">Polyligne de base.</param>
       /// <param name="tolerance">Tolérance à appliquer.</param>
       /// <returns>true, si la polyligne est superposée ; false, sinon.</returns>
       public static bool IsOverlapedTo(this Polyline pline1, Polyline pline2, Tolerance tolerance)
       {
           int nbSegments = pline1.NumberOfVertices - 1;
           if (pline1.Closed)
               nbSegments++;
           for (int i = 0; i < nbSegments; i++)
           {
               if (!pline2.IsPointOn(pline1.GetPoint3dAt(i), tolerance))
                   return false;
               if (!pline2.IsPointOn(pline1.GetPointAtParameter(i + 0.5), tolerance))
                   return false;
           }
           if (pline1.Closed &&
               !pline2.IsPointOn(pline1.GetPointAtParameter(nbSegments), tolerance))
               return false;
           return true;
       }
   }

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

J'ai essayé de faire quelque chose de plus robuste en utilisant les objets géométriques dérivés de Curve2d pour comparer les segments plutôt que les sommets.

 

Quelques méthodes d'extension dont certaines pourraient s'avérer utiles par ailleurs.

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;

using System.Collections.Generic;
using System.Linq;

namespace OverlapedPolylines
{
   public static class ExtensionMethods
   {
       /// <summary>
       /// Obtient le point au milieu d'un arc.
       /// </summary>
       public static Point2d MidPoint(this CircularArc2d arc) =>
            arc.EvaluatePoint((arc.GetParameterOf(arc.StartPoint) + arc.GetParameterOf(arc.EndPoint)) / 2.0);

       /// <summary>
       /// Evalue si l'arc courant est entièrement superposé à celui passé en argument.
       /// </summary>
       public static bool IsOverlapedTo(this CircularArc2d arc1, CircularArc2d arc2) =>
           arc2.IsOn(arc1.StartPoint) && arc2.IsOn(arc1.EndPoint) && arc2.IsOn(arc1.MidPoint());

       /// <summary>
       /// Evalue si l'arc courant est entièrement superposé à une des courbes de la collection passée en argument.
       /// </summary>
       public static bool IsOverlapedTo(this CircularArc2d arc, IEnumerable<Curve2d> curves) =>
           curves.OfType<CircularArc2d>().Any(c => arc.IsOverlapedTo(c));

       /// <summary>
       /// Evalue si le segment linéaire courant est entièrement superposé à celui passé en argument.
       /// </summary>
       public static bool IsOverlapedTo(this LineSegment2d line1, LineSegment2d line2) =>
           line2.IsOn(line1.StartPoint) && line2.IsOn(line1.EndPoint);

       /// <summary>
       /// Evalue si le segment linéaire est entièrement superposé à une des courbes de la collection passée en argument.
       /// </summary>
       public static bool IsOverlapedTo(this LineSegment2d line, IEnumerable<Curve2d> curves) =>
           curves.OfType<LineSegment2d>().Any(c => line.IsOverlapedTo(c));

       /// <summary>
       /// Evalue si la polyligne courante est entièrement superposée à celle passée en argument.
       /// </summary>
       public static bool IsOverlapedTo(this Polyline pline1, Polyline pline2) =>
           new PlineCurve2d(pline1).IsOverlapedTo(new PlineCurve2d(pline2));
   }
}

 

Une petite classe qui pourrait être étendues pour fournir d'autres fonctionnalités concernant la géométrie des segments de polyligne.

using Autodesk.AutoCAD.DatabaseServices;
using Autodesk.AutoCAD.Geometry;

using System.Collections.Generic;
using System.Linq;

namespace OverlapedPolylines
{
   /// <summary>
   /// Décrit les segments 2d d'une polyligne.
   /// </summary>
   class PlineCurve2d
   {
       private IEnumerable<Curve2d> curves;

       /// <summary>
       /// Crée une nouvelle instance à partir d'une polyligne.
       /// </summary>
       public PlineCurve2d(Polyline pline)
       {
           curves = GetCurves(pline);
       }

       /// <summary>
       /// Evalue si l'instance courante est entièrement superposé à celle passée en argument.
       /// </summary>
       public bool IsOverlapedTo(PlineCurve2d plineCurve2d)
       {
           var composite = plineCurve2d.GetSimplified();
           return
               curves.OfType<LineSegment2d>().All(l => l.IsOverlapedTo(composite)) &&
               curves.OfType<CircularArc2d>().All(a => a.IsOverlapedTo(composite));
       }

       /// <summary>
       /// Obtient la collection des segments de la polyligne.
       /// </summary>
       private IEnumerable<Curve2d> GetCurves(Polyline pline)
       {
           for (int i = 0; i < pline.NumberOfVertices; i++)
           {
               switch (pline.GetSegmentType(i))
               {
                   case SegmentType.Line:
                       yield return pline.GetLineSegment2dAt(i);
                       break;
                   case SegmentType.Arc:
                       yield return pline.GetArcSegment2dAt(i);
                       break;
                   case SegmentType.Coincident:
                   case SegmentType.Point:
                   case SegmentType.Empty:
                   default:
                       break;
               }
           }
       }

       /// <summary>
       /// Obtient la collection des segments après fusion des segments colinéaires contigus.
       /// </summary>
       private IEnumerable<Curve2d> GetSimplified()
       {
           var input = curves.ToList();
           while (input.Count > 0)
           {
               if (input.Count == 1)
               {
                   yield return input[0];
                   break;
               }
               if (input[0] is LineSegment2d line1)
               {
                   if (input[1] is LineSegment2d line2 &&
                       line1.IsColinearTo(line2))
                   {
                       input.RemoveAt(0);
                       input[0] = new LineSegment2d(line1.StartPoint, line2.EndPoint);
                   }
                   else
                   {
                       input.RemoveAt(0);
                       yield return line1;
                   }
               }
               else if (input[0] is CircularArc2d arc1)
               {
                   if (input[1] is CircularArc2d arc2 &&
                       arc1.Center.IsEqualTo(arc2.Center) &&
                       arc1.IsClockWise == arc2.IsClockWise)
                   {
                       input.RemoveAt(0);
                       input[0] = new CircularArc2d(arc1.StartPoint, arc1.EndPoint, arc2.EndPoint);
                   }
                   else
                   {

                       input.RemoveAt(0);
                       yield return arc1;
                   }
               }
           }
       }
   }
}

Gilles Chanteau - gileCAD - GitHub
Développements sur mesure pour AutoCAD

Lien vers le commentaire
Partager sur d’autres sites

Créer un compte ou se connecter pour commenter

Vous devez être membre afin de pouvoir déposer un commentaire

Créer un compte

Créez un compte sur notre communauté. C’est facile !

Créer un nouveau compte

Se connecter

Vous avez déjà un compte ? Connectez-vous ici.

Connectez-vous maintenant
×
×
  • Créer...

Information importante

Nous avons placé des cookies sur votre appareil pour aider à améliorer ce site. Vous pouvez choisir d’ajuster vos paramètres de cookie, sinon nous supposerons que vous êtes d’accord pour continuer. Politique de confidentialité