Example #1
0
        /// <summary>
        /// Returns the parameters of the intersection points of curve1 with curve2.
        /// Parameters are with respect to curve1. The two curves must reside in a common plane.
        /// </summary>
        /// <param name="curve1">First curve for intersection</param>
        /// <param name="curve2">Second curve for intersection</param>
        /// <param name="onlyInside">if true, only intersction point that are actually on the curves are returned
        /// otherwise also intersection points on the extension of ther curves are returned</param>
        /// <returns>Parameters for the intersection points</returns>
        public static double[] Intersect(ICurve curve1, ICurve curve2, bool onlyInside)
        {
            ArrayList res = new ArrayList();

            if (GetCommonPlane(curve1, curve2, out Plane pl))
            {
                ICurve2D c12d = curve1.GetProjectedCurve(pl);
                ICurve2D c22d = curve2.GetProjectedCurve(pl);
                GeoPoint2DWithParameter[] pp = c12d.Intersect(c22d);
                for (int i = 0; i < pp.Length; ++i)
                {
                    if (!onlyInside || (c12d.IsParameterOnCurve(pp[i].par1) && c22d.IsParameterOnCurve(pp[i].par2)))
                    {
                        // double pos = curve1.PositionOf(pl.ToGlobal(c12d.PointAt(pp[i].par1)));
                        // geht z.Z. davon aus, dass die Parametrierung im 2d und 3d gleich läuft, ansonsten mit obiger Zeile
                        res.Add(pp[i].par1);
                    }
                }
            }
            return((double[])(res.ToArray(typeof(double))));
        }
Example #2
0
        private bool showCutOff()
        {       // nur wenn beide Kurven gültig sind
            base.ActiveObject = null;
            base.FeedBack.ClearSelected();
            if ((iCurve1 != null) && (iCurve2 != null) && (iCurve1 != iCurve2))
            {
                Plane pl; // nur bei gemeisamer Ebene
                if (Curves.GetCommonPlane(iCurve1, iCurve2, out pl))
                {
                    if (composedSplit)
                    {
                        if (iCurveComposedSplit != null)
                        {
                            owner = (iCurveComposedSplit as IGeoObject).Owner;                              // owner merken für löschen und Einfügen
                        }
                        else
                        {
                            owner = ownerCreated;
                        }
                    }
                    //                        owner = (iCurveComposedSplit as IGeoObject).Owner; // owner merken für löschen und Einfügen
                    else
                    {
                        owner = (iCurve1 as IGeoObject).Owner;          // owner merken für löschen und Einfügen
                    }
                    pl.Align(base.ActiveDrawingPlane, false);           // Winkel anpassen
                    ICurve2D curve1_2D = iCurve1.GetProjectedCurve(pl); // die 2D-Kurven
                    if (curve1_2D is Path2D)
                    {
                        (curve1_2D as Path2D).Flatten();
                    }
                    ICurve2D curve2_2D = iCurve2.GetProjectedCurve(pl);
                    if (curve2_2D is Path2D)
                    {
                        (curve2_2D as Path2D).Flatten();
                    }
                    ICurve newCurve = iCurve1.Clone();                                                                // neue Kurve bis zum Schnittpunkt
                                                                                                                      // hier die Schnittpunkte bestimmen und den cutPoint auf den nächsten Schnittpunt setzen
                    GeoPoint2DWithParameter cutPoint;
                    if (Curves2D.NearestPoint(curve1_2D.Intersect(curve2_2D), pl.Project(objectPoint), out cutPoint)) // fasen war möglich
                    {
                        GeoVector2D v1 = curve1_2D.DirectionAt(cutPoint.par1);                                        // die Richtung im Schnittpunkt
                        if (cutPoint.par1 > 0.5)
                        {
                            v1 = v1.Opposite();                      // evtl rumdrehen, falls am Ende
                        }
                        v1.Norm();
                        GeoVector2D v2 = curve2_2D.DirectionAt(cutPoint.par2); // die Richtung im Schnittpunkt
                        if (cutPoint.par2 > 0.5)
                        {
                            v2 = v2.Opposite();                      // evtl rumdrehen, falls am Ende
                        }
                        v2.Norm();
                        GeoVector2D v = (v1 + v2); // Winkelhalbierende
                        if (Precision.IsNullVector(pl.ToGlobal(v)))
                        {
                            return(false);
                        }
                        v.Norm();
                        v = cutOffLen * v;                                      // Winkelhalbierende mit Fas-Abstand
                        GeoPoint2D dirPoint = cutPoint.p + v;                   // wird unten auch als Auswahlpunkt für die Richtung genutzt
                        Line2D     line2D   = new Line2D(dirPoint, cutPoint.p); // Linie vorbesetzen, Punkte eigentlich egal
                        if ((methodSelect == 0) || (methodSelect == 1))
                        {                                                       // 0: Länge cutOffLen = Seitenlänge Kurve1   1: Länge cutOffLen = Fasenlänge
                            double sideLength;
                            if (methodSelect == 1)                              // Länge cutOffLen = Fasenlänge
                                                                                // Geometrie, Pythagoras, bekannt Seite=cutOffLen, Winkel 1 = cutOffAng, Winkel 2 = Winkel der Kurven im Schnittpunkt
                            {
                                sideLength = cutOffLen * (Math.Cos(cutOffAng.Radian) + (Math.Sin(cutOffAng.Radian) / Math.Tan(Math.Abs(new SweepAngle(v1, v2).Radian))));
                            }
                            else
                            {
                                sideLength = cutOffLen;
                            }
                            // neue Kurve bis zum Schnittpunkt synthetisieren, dazu: Schnittpunkt finden des Abschnitts mit der iCurve1

                            Ellipse arcTmp = Ellipse.Construct();
                            arcTmp.SetCirclePlaneCenterRadius(pl, pl.ToGlobal(cutPoint.p), sideLength);
                            ICurve2D curveArc_2D = (arcTmp as ICurve).GetProjectedCurve(pl); // die 2D-Kurve
                            GeoPoint2DWithParameter cutArc;
                            GeoPoint2D startPoint;
                            if (Curves2D.NearestPoint(curve1_2D.Intersect(curveArc_2D), dirPoint, out cutArc)) // war möglich
                            {
                                startPoint = cutArc.p;
                            }
                            else
                            {
                                return(false);
                            }

                            /*
                             *                          double parCut;
                             *
                             *                          // neue Kurve bis zum Schnittpunkt synthetisieren:
                             *                          if (cutPoint.par1 <= 0.5)
                             *                          {
                             *                              newCurve.Trim(cutPoint.par1,1.0);
                             *                              parCut = (sideLength)/newCurve.Length; // der Parameter des Fasenpunktes
                             *                          }
                             *                          else
                             *                          {
                             *                              newCurve.Trim(0.0,cutPoint.par1);
                             *                              parCut = (newCurve.Length-sideLength)/newCurve.Length; // der Parameter des Fasenpunktes
                             *                          }
                             *                          GeoPoint2D startPoint = pl.Project(newCurve.PointAt(parCut));
                             *                          GeoVector2D vc = curve1_2D.DirectionAt(parCut); // die Richtung im Schnittpunkt
                             */
                            GeoVector2D vc = curve1_2D.DirectionAt(curve1_2D.PositionOf(startPoint)); // die Richtung im Schnittpunkt
                            if (cutPoint.par1 <= 0.5)
                            {
                                vc = vc.Opposite();                            // evtl rumdrehen, falls am Ende
                            }
                            if (Geometry.OnLeftSide(dirPoint, startPoint, vc)) // Richtung festlegen für Winkeloffset
                            {
                                vc.Angle = vc.Angle + new SweepAngle(cutOffAng);
                            }
                            else
                            {
                                vc.Angle = vc.Angle - new SweepAngle(cutOffAng);
                            }
                            // Hilfslinie im Fasabstand, im Offsetwinkel
                            line2D = new Line2D(startPoint, startPoint + vc);
                        }
                        if (methodSelect == 2)                             // Länge cutOffLen = Winkelhalbierendenlänge
                        {
                            v.Angle = v.Angle + new SweepAngle(cutOffAng); // Winkelhalbierendenwinkel + Offset
                                                                           // Hilfslinie im Fasabstand, senkrecht auf der Winkelhalbierenden v
                            line2D = new Line2D(dirPoint, dirPoint + v.ToLeft());
                        }

                        GeoPoint2DWithParameter cutPoint1;
                        GeoPoint2DWithParameter cutPoint2;
                        // schnittpunkte der Hilfslinie mit den beiden Kurven
                        if (Curves2D.NearestPoint(curve1_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint1))
                        {
                            if (Curves2D.NearestPoint(curve2_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint2))
                            {   // da isse, die Fas-Linie, nur, wenn die Punkte echt auf der Kurve bis zum Schnittpunkt  liegen:
                                bool onCurve1, onCurve2;
                                // Berechnung, ob die Kurven realen Schnittpunkt haben
                                //								if ((cutPoint.par1 <= 1.0001) & (cutPoint.par1 >= -0.0001) & (cutPoint.par2 <= 1.0001) & (cutPoint.par2 >= -0.0001))
                                if (curve1_2D.IsParameterOnCurve(cutPoint.par1) & curve2_2D.IsParameterOnCurve(cutPoint.par2))
                                {
                                    onCurve1 = (cutPoint1.par1 > 0.0) & (cutPoint1.par1 < 1.0);
                                    onCurve2 = (cutPoint2.par1 > 0.0) & (cutPoint2.par1 < 1.0);
                                }
                                else
                                {
                                    if (cutPoint.par1 > 0.5)
                                    {
                                        onCurve1 = (cutPoint1.par1 > 0.0) & (cutPoint1.par1 < 100);
                                    }
                                    // im Quasi-Parallelfall stehen in par1 riesige Werte
                                    else
                                    {
                                        onCurve1 = (cutPoint1.par1 < 1.0) & (cutPoint1.par1 > -100);
                                    }
                                    if (cutPoint.par2 > 0.5)
                                    {
                                        onCurve2 = (cutPoint2.par1 > 0.0) & (cutPoint2.par1 < 100);
                                    }
                                    else
                                    {
                                        onCurve2 = (cutPoint2.par1 < 1.0) & (cutPoint2.par1 > -100);
                                    }
                                }
                                if (onCurve1 && onCurve2)
                                {
                                    line.SetTwoPoints(pl.ToGlobal(cutPoint1.p), pl.ToGlobal(cutPoint2.p));
                                    // Fasenlänge vorgegeben, aber mit obiger Berechnung falsch, da dort Linien vorausgesetzt werden
                                    if ((methodSelect == 1) && (Math.Abs(line.Length - cutOffLen) > Precision.eps))
                                    {   // jetzt mit Iteration annähern
                                        double parInd      = 0.5;
                                        double parIndDelta = 0.25;
                                        for (int i = 0; i < 49; ++i) // 48 Schritte müssen reichen, par kann zwischen 0 und 1 liegen
                                        {
                                            GeoPoint2D  startPoint = pl.Project(newCurve.PointAt(parInd));
                                            GeoVector2D vc         = curve1_2D.DirectionAt(parInd); // die Richtung im Schnittpunkt
                                            if (cutPoint.par1 <= 0.5)
                                            {
                                                vc = vc.Opposite();                            // evtl rumdrehen, falls am Ende
                                            }
                                            if (Geometry.OnLeftSide(dirPoint, startPoint, vc)) // Richtung festlegen für Winkeloffset
                                            {
                                                vc.Angle = vc.Angle + new SweepAngle(cutOffAng);
                                            }
                                            else
                                            {
                                                vc.Angle = vc.Angle - new SweepAngle(cutOffAng);
                                            }
                                            // Hilfslinie im Fasabstand, im Offsetwinkel
                                            line2D = new Line2D(startPoint, startPoint + vc);
                                            if (Curves2D.NearestPoint(curve1_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint1))
                                            {
                                                if (Curves2D.NearestPoint(curve2_2D.Intersect(line2D as ICurve2D), cutPoint.p + v, out cutPoint2))
                                                {   // da isse, die Fas-Linie, nur, wenn die Punkte echt auf der Kurvr liegen:
                                                    if (cutPoint.par1 > 0.5)
                                                    {
                                                        onCurve1 = (cutPoint1.par1 > 0.0) & (cutPoint1.par1 < 100);
                                                    }
                                                    // im Quasi-Parallelfall stehen in par1 riesige Werte
                                                    else
                                                    {
                                                        onCurve1 = (cutPoint1.par1 < 1.0) & (cutPoint1.par1 > -100);
                                                    }
                                                    if (cutPoint.par2 > 0.5)
                                                    {
                                                        onCurve2 = (cutPoint2.par1 > 0.0) & (cutPoint2.par1 < 100);
                                                    }
                                                    else
                                                    {
                                                        onCurve2 = (cutPoint2.par1 < 1.0) & (cutPoint2.par1 > -100);
                                                    }
                                                    if (onCurve1 && onCurve2)
                                                    {
                                                        line.SetTwoPoints(pl.ToGlobal(cutPoint1.p), pl.ToGlobal(cutPoint2.p));
                                                        if ((Math.Abs(line.Length - cutOffLen) < Precision.eps)) // gefunden und raus
                                                        {
                                                            break;
                                                        }
                                                        else
                                                        {
                                                            if (line.Length < cutOffLen)
                                                            {                                    // Fase ist zu klein: Parameter parInd vergrößern
                                                                parInd      = parInd + parIndDelta;
                                                                parIndDelta = parIndDelta / 2.0; // delta halbieren (Bisection!!)
                                                                continue;                        // nächster Schritt in der For-Schleife
                                                            }
                                                        }
                                                    }
                                                }
                                            }
                                            // alle anderen Fälle: // Fase ist zu gross: Parameter parInd verkleinern
                                            parInd      = parInd - parIndDelta;
                                            parIndDelta = parIndDelta / 2.0; // delta halbieren (Bisection!!)
                                        } // for schleife Iteration
                                    } // Ende Iteration
                                    line.CopyAttributes(iCurve1 as IGeoObject);
                                    base.ActiveObject = line;        // merken
                                    base.FeedBack.AddSelected(line); // darstellen
                                    return(true);
                                }
                            }
                        }
                    }
                }
            }
            return(false);
        }