Beispiel #1
0
        /// <summary>
        /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.Intersect (ICurve2D)"/>
        /// </summary>
        /// <param name="IntersectWith"></param>
        /// <returns></returns>
        public override GeoPoint2DWithParameter[] Intersect(ICurve2D IntersectWith)
        {   // gesucht sind alle Schnittpunkte, also auch in der Verlängerung!
            Line2D l2d = IntersectWith as Line2D;

            if (l2d != null)
            {
                GeoPoint2D ip;
                if (Geometry.IntersectLL(startPoint, endPoint, l2d.StartPoint, l2d.EndPoint, out ip))
                {
                    double pos1 = this.PositionOf(ip);
                    double pos2 = l2d.PositionOf(ip);
                    GeoPoint2DWithParameter pwp = new GeoPoint2DWithParameter();
                    pwp.p    = ip;
                    pwp.par1 = pos1;
                    pwp.par2 = pos2;
                    return(new GeoPoint2DWithParameter[] { pwp });
                }
                else
                {
                    return(new GeoPoint2DWithParameter[0]);
                }
            }
            Circle2D c2d = IntersectWith as Circle2D;

            if (c2d != null)
            {
                GeoPoint2D[] isp = Geometry.IntersectLC(startPoint, endPoint, c2d.Center, c2d.Radius);
                GeoPoint2DWithParameter[] res = new GeoPoint2DWithParameter[isp.Length];
                for (int i = 0; i < isp.Length; ++i)
                {
                    res[i].p    = isp[i];
                    res[i].par1 = this.PositionOf(isp[i]);
                    res[i].par2 = c2d.PositionOf(isp[i]);
                }
                return(res);
            }
            Ellipse2D e2d = IntersectWith as Ellipse2D;

            if (e2d != null)
            {
                GeoPoint2D[] isp = Geometry.IntersectEL(e2d.center, e2d.majorAxis.Length, e2d.minorAxis.Length, e2d.majorAxis.Angle, startPoint, endPoint);
                GeoPoint2DWithParameter[] res = new GeoPoint2DWithParameter[isp.Length];
                for (int i = 0; i < isp.Length; ++i)
                {
                    res[i].p    = isp[i];
                    res[i].par1 = this.PositionOf(isp[i]);
                    res[i].par2 = e2d.PositionOf(isp[i]);
                }
                return(res);
            }
            Polyline2D p2d = IntersectWith as Polyline2D;

            if (p2d != null)
            {
                GeoPoint2DWithParameter[] res = p2d.Intersect(this); // sorum geht es
                for (int i = 0; i < res.Length; ++i)
                {
                    double t = res[i].par1;
                    res[i].par1 = res[i].par2;
                    res[i].par2 = t;
                }
                return(res);
            }
            Path2D pa2d = IntersectWith as Path2D;

            if (pa2d != null)
            {
                GeoPoint2DWithParameter[] res = pa2d.Intersect(this); // sorum geht es
                for (int i = 0; i < res.Length; ++i)
                {
                    double t = res[i].par1;
                    res[i].par1 = res[i].par2;
                    res[i].par2 = t;
                }
                return(res);
            }
            BSpline2D b2d = IntersectWith as BSpline2D;

            if (b2d != null)
            {
                GeoPoint2DWithParameter[] res = b2d.Intersect(this); // sorum geht es
                for (int i = 0; i < res.Length; ++i)
                {
                    double t = res[i].par1;
                    res[i].par1 = res[i].par2;
                    res[i].par2 = t;
                }
                return(res);
            }
            return(base.Intersect(IntersectWith));
        }
Beispiel #2
0
 /// <summary>
 /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.MinDistance (ICurve2D)"/>
 /// </summary>
 /// <param name="Other"></param>
 /// <returns></returns>
 public override double MinDistance(ICurve2D Other)
 {
     if (Other is Line2D)
     {
         return(Other.MinDistance(this)); // bei der Linie ist es definiert
     }
     else if (Other is Circle2D)
     {
         double minDist = Curves2D.SimpleMinimumDistance(this, Other); // dort werden die Schnitt- Start- Endpunkte miteinander verrechnet
         // jetzt nur noch gucken, ob sich die beiden Kreise oder Bögen annähern
         Circle2D c     = Other as Circle2D;
         double   cdist = Geometry.Dist(c.center, center);
         if (cdist < Precision.eps)
         {
             return(minDist);                       // mit gleichen Mittelpunkten funktioniert
         }
         // das folgende nicht, aber der Abstand ist schon von SimpleMinimumDistance bestimmt
         // da dort auch die Fußpunkte verwendung finden
         if (cdist > c.radius + radius)
         {                                        // Annäherung zweier nicht schneidenden Kreise
             GeoVector2D dir = c.center - center; // von hier zum anderen
             dir.Norm();
             GeoPoint2D p1   = center + radius * dir;
             GeoPoint2D p2   = c.center + c.radius * dir.Opposite();
             double     pos1 = this.PositionOf(p1);
             double     pos2 = c.PositionOf(p2);
             if (pos1 >= 0.0 && pos1 <= 1.0 && pos2 >= 0.0 && pos2 <= 1.0)
             {
                 minDist = Math.Min(minDist, cdist - c.radius - radius);
             }
         }
         else if (radius - c.radius > cdist)
         {                                        // Kreis c liegt innerhalb von diesem Kreis
             GeoVector2D dir = c.center - center; // von hier zum anderen
             dir.Norm();
             GeoPoint2D p1   = center + radius * dir;
             GeoPoint2D p2   = c.center + c.radius * dir;
             double     pos1 = this.PositionOf(p1);
             double     pos2 = c.PositionOf(p2);
             if (pos1 >= 0.0 && pos1 <= 1.0 && pos2 >= 0.0 && pos2 <= 1.0)
             {
                 minDist = Math.Min(minDist, Geometry.Dist(p1, p2));
             }
         }
         else if (c.radius - radius > cdist)
         {       // dieser Kreis liegt innerhalb von c
             GeoVector2D dir = center - c.center;
             dir.Norm();
             GeoPoint2D p1   = c.center + c.radius * dir;
             GeoPoint2D p2   = center + radius * dir;
             double     pos1 = c.PositionOf(p1);
             double     pos2 = PositionOf(p2);
             if (pos1 >= 0.0 && pos1 <= 1.0 && pos2 >= 0.0 && pos2 <= 1.0)
             {
                 minDist = Math.Min(minDist, Geometry.Dist(p1, p2));
             }
         }
         return(minDist);
     }
     else
     {
         return(base.MinDistance(Other));
     }
 }
Beispiel #3
0
 /// <summary>
 /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.MinDistance (ICurve2D)"/>
 /// </summary>
 /// <param name="Other"></param>
 /// <returns></returns>
 public override double MinDistance(ICurve2D Other)
 {
     if (Other is Line2D)
     {
         Line2D l = Other as Line2D;
         // schneller Vorabtest auf Schnitt: (noch nicht getestet)
         double f1 = (startPoint.x - endPoint.x) * (l.endPoint.y - endPoint.y) - (startPoint.y - endPoint.y) * (l.endPoint.x - endPoint.x);
         double f2 = (startPoint.x - endPoint.x) * (l.startPoint.y - endPoint.y) - (startPoint.y - endPoint.y) * (l.startPoint.x - endPoint.x);
         if (f1 * f2 < 0.0)
         {   // verschiedenes Vorzeichen
             double f3 = (l.startPoint.x - l.endPoint.x) * (endPoint.y - l.endPoint.y) - (l.startPoint.y - l.endPoint.y) * (endPoint.x - l.endPoint.x);
             double f4 = (l.startPoint.x - l.endPoint.x) * (startPoint.y - l.endPoint.y) - (l.startPoint.y - l.endPoint.y) * (startPoint.x - l.endPoint.x);
             if (f3 * f4 < 0.0)
             {
                 return(0.0);               // echter Schnittpunkt
             }
         }
         double minDist = double.MaxValue;
         double dx1     = endPoint.x - startPoint.x;
         double dy1     = endPoint.y - startPoint.y;
         bool   DoDx1   = Math.Abs(dx1) > Math.Abs(dy1);
         double dx2     = l.endPoint.x - l.startPoint.x;
         double dy2     = l.endPoint.y - l.startPoint.y;
         bool   DoDx2   = Math.Abs(dx2) > Math.Abs(dy2);
         double d;
         // Berechnung der Fußpunktabstände, wenn sie auf die andere Linie treffen
         GeoPoint2D p = Geometry.DropPL(l.startPoint, startPoint, endPoint);
         if (DoDx1)
         {
             d = (p.x - startPoint.x) / dx1;
         }
         else
         {
             d = (p.y - startPoint.y) / dy1;
         }
         if (d >= 0.0 && d <= 1.0)
         {
             minDist = Math.Min(minDist, Geometry.Dist(p, l.startPoint));
         }
         p = Geometry.DropPL(l.endPoint, startPoint, endPoint);
         if (DoDx1)
         {
             d = (p.x - startPoint.x) / dx1;
         }
         else
         {
             d = (p.y - startPoint.y) / dy1;
         }
         if (d >= 0.0 && d <= 1.0)
         {
             minDist = Math.Min(minDist, Geometry.Dist(p, l.endPoint));
         }
         p = Geometry.DropPL(startPoint, l.startPoint, l.endPoint);
         if (DoDx2)
         {
             d = (p.x - l.startPoint.x) / dx2;
         }
         else
         {
             d = (p.y - l.startPoint.y) / dy2;
         }
         if (d >= 0.0 && d <= 1.0)
         {
             minDist = Math.Min(minDist, Geometry.Dist(p, startPoint));
         }
         p = Geometry.DropPL(endPoint, l.startPoint, l.endPoint);
         if (DoDx2)
         {
             d = (p.x - l.startPoint.x) / dx2;
         }
         else
         {
             d = (p.y - l.startPoint.y) / dy2;
         }
         if (d >= 0.0 && d <= 1.0)
         {
             minDist = Math.Min(minDist, Geometry.Dist(p, endPoint));
         }
         if (minDist == double.MaxValue)
         {   // kein Fußpunkt auf der anderen Linie: die gegenseitigen Start/Endpunkt
             // Abstände verwenden
             minDist = Math.Min(minDist, Geometry.Dist(l.startPoint, endPoint));
             minDist = Math.Min(minDist, Geometry.Dist(l.endPoint, endPoint));
             minDist = Math.Min(minDist, Geometry.Dist(l.startPoint, startPoint));
             minDist = Math.Min(minDist, Geometry.Dist(l.endPoint, startPoint));
         }
         return(minDist);
     }
     else if (Other is Arc2D)
     {
         double       minDist = Curves2D.SimpleMinimumDistance(this, Other);
         Arc2D        a       = Other as Arc2D;
         GeoPoint2D[] fp      = PerpendicularFoot(a.Center);
         for (int i = 0; i < fp.Length; ++i)
         {
             GeoPoint2D p   = fp[i];
             double     pos = PositionOf(p);
             if (pos >= 0.0 && pos <= 1.0)
             {
                 pos = a.PositionOf(p);
                 if (pos >= 0.0 && pos <= 1.0)
                 {
                     double d = Geometry.Dist(p, a.Center);
                     if (d > a.Radius)
                     {
                         minDist = Math.Min(minDist, d - a.Radius);
                     }
                 }
             }
         }
         return(minDist);
     }
     else if (Other is Circle2D)
     {
         double       minDist = Curves2D.SimpleMinimumDistance(this, Other);
         Circle2D     c       = Other as Circle2D;
         GeoPoint2D[] fp      = PerpendicularFoot(c.Center);
         for (int i = 0; i < fp.Length; ++i)
         {
             GeoPoint2D p   = fp[i];
             double     pos = PositionOf(p);
             if (pos >= 0.0 && pos <= 1.0)
             {
                 double d = Geometry.Dist(p, c.Center);
                 if (d > c.Radius)
                 {
                     minDist = Math.Min(minDist, d - c.Radius);
                 }
             }
         }
         return(minDist);
     }
     else
     {
         return(base.MinDistance(Other));
     }
 }