Exemplo n.º 1
0
        /// <summary>
        /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.GetFused (ICurve2D, double)"/>
        /// </summary>
        /// <param name="toFuseWith"></param>
        /// <param name="precision"></param>
        /// <returns></returns>
        public override ICurve2D GetFused(ICurve2D toFuseWith, double precision)
        {
            if (toFuseWith is Ellipse2D && !(toFuseWith is EllipseArc2D))
            {
                return(toFuseWith.GetFused(this, precision));
            }
            if (toFuseWith is EllipseArc2D)
            {
                EllipseArc2D a2d = (toFuseWith as EllipseArc2D);
                // hier wird vorausgesetzt, dass majrad>minrad immer gilt. Stimmt das?
                if ((Center | a2d.Center) + Math.Abs(majrad - a2d.majrad) + Math.Abs(minrad - a2d.minrad) < precision)
                {   // alle zusammen kleiner als precision, vielleich beim Bogen zu streng
                    // weitere Bedingung: Achsen müssen übereinstimmen.
                    // dazu müsste man bei vertauschten Richtungen noch mehr Grips reinstecken...

                    EllipseArc2D a1, a2;
                    if (Math.Abs(this.sweepPar) > Math.Abs(a2d.sweepPar))
                    {
                        a1 = this;
                        a2 = a2d;
                    }
                    else
                    {
                        a1 = a2d;
                        a2 = this;
                    }
                    if (a1.sweepPar * a2.sweepPar < 0.0)
                    {
                        a2.Reverse();
                    }
                    // a1 ist länger als a2. Wenn es verschmelzen soll, dann muss der Start- oder der Endpunkt von a2
                    // innerhalb von a1 liegen

                    // Mittelpunkt und radius ist ja schon getestet
                    double pos1 = a1.PositionOf(a2.StartPoint); // vor dem Anfang oder auf dem Bogen
                    double pos2 = a1.PositionOf(a2.EndPoint);   // nach dem Ende oder auf dem Bogen
                    // System.Diagnostics.Trace.WriteLine("pos1, pos2: " + pos1.ToString() + ", " + pos2.ToString());
                    bool pos1ok = a1.IsParameterOnCurve(pos1);
                    bool pos2ok = a1.IsParameterOnCurve(pos2);
                    if (pos1ok && pos2ok)
                    {   // beide Punkte sind drauf
                        return(a1.Clone());
                    }
                    else if (pos1ok)
                    {
                        return(Create(a1.center, a1.majorAxis, a1.minorAxis, a1.startPoint, a2.endPoint, a1.sweepPar > 0.0));
                    }
                    else if (pos2ok)
                    {
                        return(Create(a1.center, a1.majorAxis, a1.minorAxis, a2.startPoint, a1.endPoint, a1.sweepPar > 0.0));
                    }
                }
            }
            return(null);
        }
Exemplo n.º 2
0
 /// <summary>
 /// Tries to combine two curves. crv1 and crv2 must be correct oriented and the endpoint of crv1 mut be the start-point of crv2
 /// </summary>
 /// <param name="crv1"></param>
 /// <param name="crv2"></param>
 /// <returns>the combined curve or null, if not possible</returns>
 public static ICurve Combine(ICurve crv1, ICurve crv2, double precision)
 {
     if (crv1 == null || crv2 == null)
     {
         return(null);
     }
     if ((crv1.EndPoint | crv2.StartPoint) > precision)
     {
         return(null);
     }
     if (crv1 is InterpolatedDualSurfaceCurve ip1 && crv2 is InterpolatedDualSurfaceCurve ip2)
     {
         if ((ip1.Surface1.SameGeometry(ip1.Domain1, ip2.Surface1, ip2.Domain1, precision, out _) && ip1.Surface2.SameGeometry(ip1.Domain2, ip2.Surface2, ip2.Domain2, precision, out _)) ||
             (ip1.Surface1.SameGeometry(ip1.Domain1, ip2.Surface2, ip2.Domain2, precision, out _) && ip1.Surface2.SameGeometry(ip1.Domain2, ip2.Surface1, ip2.Domain1, precision, out _)))
         {
             List <GeoPoint> basepoints = new List <GeoPoint>();
             basepoints.AddRange(ip1.BasePoints);
             basepoints.RemoveAt(basepoints.Count - 1);
             basepoints.AddRange(ip2.BasePoints);
             return(new InterpolatedDualSurfaceCurve(ip1.Surface1, ip1.Domain1, ip1.Surface2, ip1.Domain2, basepoints)); // the domains are too small, but this is not a problem
         }
     }
     if (GetCommonPlane(crv1, crv2, out Plane pln))
     {
         ICurve2D e2d1  = crv1.GetProjectedCurve(pln);
         ICurve2D e2d2  = crv2.GetProjectedCurve(pln);
         ICurve2D fused = e2d1.GetFused(e2d2, precision);
         if (fused != null)
         {
             return(fused.MakeGeoObject(pln) as ICurve);
         }
     }
     else if (crv1 is Line && crv2 is Line)
     {
         Line res = Line.Construct();
         res.SetTwoPoints(crv1.StartPoint, crv2.EndPoint);
         return(res);
     }
     // non planar BSplines should be implemented
     return(null);
 }
Exemplo n.º 3
0
        /// <summary>
        /// Overrides <see cref="CADability.Curve2D.GeneralCurve2D.GetFused (ICurve2D, double)"/>
        /// </summary>
        /// <param name="toFuseWith"></param>
        /// <param name="precision"></param>
        /// <returns></returns>
        public override ICurve2D GetFused(ICurve2D toFuseWith, double precision)
        {
            if (toFuseWith is Circle2D && !(toFuseWith is Arc2D))
            {
                return(toFuseWith.GetFused(this, precision));
            }
            if (toFuseWith is Arc2D)
            {
                Arc2D a2d = (toFuseWith as Arc2D);
                if ((Center | a2d.Center) + Math.Abs(Radius - a2d.Radius) < precision)
                {   // beides zusammen kleiner als precision, vielleich beim Bogen zu streng
                    Arc2D a1, a2;
                    if (this.Length > toFuseWith.Length)
                    {
                        a1 = this;
                        a2 = toFuseWith as Arc2D;
                    }
                    else
                    {
                        a1 = toFuseWith as Arc2D;
                        a2 = this;
                    }
                    if (a1.sweep * a2.sweep < 0.0)
                    {
                        a2 = (Arc2D)a2.CloneReverse(true); // war a2.Reverse();, man darf aber nicht eines der beteiligten Objekte ändern
                    }
                    // a1 ist länger als a2. Wenn es verschmelzen soll, dann muss der Start- oder der Endpunkt von a2
                    // innerhalb von a1 liegen

                    // Mittelpunkt und radius ist ja schon getestet
                    double pos1 = a1.PositionOf(a2.StartPoint, true); // vor dem Anfang oder auf dem Bogen
                    double pos2 = a1.PositionOf(a2.EndPoint, false);  // nach dem Ende oder auf dem Bogen
                    // System.Diagnostics.Trace.WriteLine("pos1, pos2: " + pos1.ToString() + ", " + pos2.ToString());
                    double eps = precision / a1.Length;
                    if (Math.Abs(pos1 - 1.0) < eps && Math.Abs(pos2) < eps)
                    {   // geht von Ende bis Anfang: Sonderfall: ergibt Vollkreis
                        double full;
                        if (a1.sweep > 0.0)
                        {
                            full = Math.PI * 2.0;
                        }
                        else
                        {
                            full = -Math.PI * 2.0;
                        }
                        Arc2D res = new Arc2D(Center / a2d.Center, (Radius + a2d.Radius) / 2.0, a1.start, full);
                        return(res);
                    }
                    else if (pos1 > -eps && pos1 < 1 + eps)
                    {   // also pos 2 geht evtl über diesen hinaus
                        GeoPoint2D sp  = a1.StartPoint;
                        GeoPoint2D ep  = a1.PointAt(Math.Max(pos2, 1.0));
                        Arc2D      res = new Arc2D(Center / a2d.Center, (Radius + a2d.Radius) / 2.0, sp, ep, a1.sweep > 0.0);
                        return(res);
                    }
                    else if (pos2 > -eps && pos2 < 1 + eps)
                    {
                        GeoPoint2D sp  = a1.PointAt(Math.Min(0.0, pos1));
                        GeoPoint2D ep  = a1.EndPoint;
                        Arc2D      res = new Arc2D(Center / a2d.Center, (Radius + a2d.Radius) / 2.0, sp, ep, a1.sweep > 0.0);
                        return(res);
                    }
                    else
                    {
                        return(null);
                    }
                }
            }
            return(null);
        }