private bool showObject() { base.FeedBack.ClearSelected(); base.ActiveObject = null; double[] cutPlace; ICurve2D c2d = iCurve.GetProjectedCurve(CurrentMouseView.Projection.ProjectionPlane); GeoPoint2D op2d = CurrentMouseView.Projection.ProjectUnscaled(objectPoint); lowerEnd = (c2d.PositionOf(op2d) < 0.5); // im 2D überprüfen, in 3D ist objectPoint möglicherweise weit von iCurve entfernt // bool lowerEnd = (iCurve.PositionOf(objectPoint)< 0.5); ProjectedModel.IntersectionMode cutMode; bool realCut; if (lowerEnd) { cutMode = ProjectedModel.IntersectionMode.StartExtension; } else { cutMode = ProjectedModel.IntersectionMode.EndExtension; } // if (expandSourceObject.Fixed) ICurve[] targetCurves = null; if (sourceCurve != null) { cutPlace = Curves.Intersect(iCurve, sourceCurve, false); } else { cutPlace = base.Frame.ActiveView.ProjectedModel.GetIntersectionParameters(iCurve, cutMode, out targetCurves); } if (cutPlace.Length > 0) { realCut = false; for (int i = 0; i < cutPlace.Length; ++i) { if (distToCurve.Length == 0) { if (cutPlace[i] < -1e-8 || cutPlace[i] > 1 + 1e-8) // Endpunkte nicht mit berücksichtigen //if (!((Math.Abs(cutPlace[i]) < 1e-8) || (Math.Abs(cutPlace[i] - 1) < 1e-8))) { realCut = true; break; } } else { //if (cutPlace[i] < 1e-8 || cutPlace[i] > 1 - 1e-8) // Endpunkte mit berücksichtigen { realCut = true; break; } } } if (realCut) { int k = -1; if (lowerEnd) { param = double.MinValue; } else { param = double.MaxValue; } double eps; // wenn distToCurve gesetzt ist, dann bleibt ein exakt getrimmtes am Ende gültig, ansonsten wird die nächste Querkurve verwendet if (distToCurve.Length == 0) { eps = 1e-8; } else { if (sourceCurve != null && sourceCurve.Length > 0) // eine Zielkurve wurde angewählt. Schnitte dürfen jetzt vor dem Ende von iCurve sein //eps = -Math.Abs(distToCurve.Length) / sourceCurve.Length; { eps = -1.0; // egal, Hauptsache auf der Kurve } else { eps = -1e-8; } } for (int i = 0; i < cutPlace.Length; ++i) { if (lowerEnd) { // verlängern nach hinten, der größte Wert, der kleiner Null und ungleich quasi Null if ((cutPlace[i] > param) && (cutPlace[i] < 0.0 - eps)) { param = cutPlace[i]; k = i; } } else { // verlängern nach vorne, der kleinste Wert, der größer 1.0 und ungleich quasi 1.0 if ((cutPlace[i] < param) && (cutPlace[i] > 1.0 + eps)) { param = cutPlace[i]; k = i; } } } if (k >= 0) // was gefunden { newCurve = iCurve.Clone(); if (distToCurve.Length != 0.0) { // zusätzlich länger oder kürzer machen ICurve targetCurve = sourceCurve; if (targetCurves != null) { targetCurve = targetCurves[k]; } Plane pl; if (Curves.GetCommonPlane(iCurve, targetCurve, out pl)) { // muss der Fall sein ICurve2D targetCurve2d = targetCurve.GetProjectedCurve(pl); ICurve2D parl1 = targetCurve2d.Parallel(-distToCurve.Length, true, Precision.eps, 0.0); ICurve2D parl2 = targetCurve2d.Parallel(distToCurve.Length, true, Precision.eps, 0.0); ICurve2D newCurve2d = newCurve.GetProjectedCurve(pl); // im 2d verlängern if (lowerEnd) { newCurve2d.StartPoint = newCurve2d.PointAt(param); } else { newCurve2d.EndPoint = newCurve2d.PointAt(param); } if (lowerEnd) { // jetzt nur den Vorwärtsfall betrachten newCurve2d.Reverse(); } // betrachte beide Parallelen, wir kennen die Richtungen nicht GeoPoint2DWithParameter[] gp1 = newCurve2d.Intersect(parl1); GeoPoint2DWithParameter[] gp2 = newCurve2d.Intersect(parl2); double bestPar; if (distToCurve.Length > 0) { // Kurve muss kürzer werden bestPar = 0.0; for (int i = 0; i < gp1.Length; i++) { if (gp1[i].par2 >= 0 && gp1[i].par2 <= 1 && gp1[i].par1 <1 && gp1[i].par1> bestPar) { bestPar = gp1[i].par1; } } for (int i = 0; i < gp2.Length; i++) { if (gp2[i].par2 >= 0 && gp2[i].par2 <= 1 && gp2[i].par1 <1 && gp2[i].par1> bestPar) { bestPar = gp2[i].par1; } } } else { bestPar = double.MaxValue; for (int i = 0; i < gp1.Length; i++) { if (gp1[i].par2 >= 0 && gp1[i].par2 <= 1 && gp1[i].par1 > 1 && gp1[i].par1 < bestPar) { bestPar = gp1[i].par1; } } for (int i = 0; i < gp2.Length; i++) { if (gp2[i].par2 >= 0 && gp2[i].par2 <= 1 && gp2[i].par1 > 1 && gp2[i].par1 < bestPar) { bestPar = gp2[i].par1; } } } // den gefundenen Punkt auf die Kurve setzen if (bestPar > 0 && bestPar < double.MaxValue) { GeoPoint pp = pl.ToGlobal(newCurve2d.PointAt(bestPar)); param = iCurve.PositionOf(pp); // param ist das eigentliche Ergebnis, welches bei onDone verwendet wird if (lowerEnd) { newCurve.StartPoint = pp; } else { newCurve.EndPoint = pp; } } } } else { if (lowerEnd) { newCurve.StartPoint = iCurve.PointAt(param); } else { newCurve.EndPoint = iCurve.PointAt(param); } } (newCurve as IGeoObject).CopyAttributes(iCurve as IGeoObject); //Color backColor = base.Frame.GetColorSetting("Colors.Feedback", Color.DarkGray); //if (newCurve is IColorDef) // (newCurve as IColorDef).ColorDef = new ColorDef("", backColor); base.ActiveObject = (newCurve as IGeoObject); base.FeedBack.AddSelected(newCurve as IGeoObject);// letzte Linie einfügen return(true); } } } param = 0.0; return(false); }
//public override void AutoRepeated() //{ // sourceCurve = sourceCurveSave; // sourceCurve auf den Instanzübergreifenden Wert gesetzt //} private bool showObject() { double[] cutPlace; base.FeedBack.ClearSelected(); if ((iCurve2 != null) && !iCurve2.IsClosed && (iCurve1 != null) && !iCurve1.IsClosed && (iCurve1 != iCurve2)) { // Plane pl; // if (Curves.GetCommonPlane(iCurve1, iCurve2, out pl)) // { // ICurve2D curve1_2D = iCurve1.GetProjectedCurve(pl); // die 2D-Kurven // ICurve2D curve2_2D = iCurve2.GetProjectedCurve(pl); // if (curve1_2D is Path2D) (curve1_2D as Path2D).Flatten(); // if (curve2_2D is Path2D) (curve2_2D as Path2D).Flatten(); // // hier die Schnittpunkte bestimmen und den ObjectPoint auf den nächsten Schnittpunt setzen // GeoPoint2DWithParameter[] intersectPoints = curve1_2D.Intersect(curve2_2D); // GeoPoint position = new GeoPoint(objectPoint1, objectPoint2); // double distS = double.MaxValue; // Entfernung des Pickpunkts zu den Schnittpunkten // for (int i = 0; i < intersectPoints.Length; ++i) // { //// double distLoc = Geometry.Dist(intersectPoints[i].p, pl.Project(position)); // double distLoc = Geometry.Dist(intersectPoints[i].p, pl.Project(objectPoint2)); // if (distLoc < distS) // { // distS = distLoc; // param1 = intersectPoints[i].par1; // param2 = intersectPoints[i].par2; // } // } // } cutPlace = Curves.Intersect(iCurve1, iCurve2, false); GeoPoint position = new GeoPoint(objectPoint1, objectPoint2); if (cutPlace.Length > 0) { pos1 = iCurve1.PositionOf(position); // pos1 = iCurve1.PositionOf(objectPoint1); double dist = double.MaxValue; for (int i = 0; i < cutPlace.Length; ++i) { double distLoc = Geometry.Dist(position, iCurve1.PointAt(cutPlace[i])); // double distLoc = Geometry.Dist(objectPoint1, iCurve1.PointAt(cutPlace[i])); if (distLoc < dist) { // dist = Math.Abs(pos1 - cutPlace[i]); dist = distLoc; param1 = cutPlace[i]; // k1 = 2; } } } cutPlace = Curves.Intersect(iCurve2, iCurve1, false); if (cutPlace.Length > 0) { pos2 = iCurve2.PositionOf(position); // pos2 = iCurve2.PositionOf(objectPoint2); double dist = double.MaxValue; for (int i = 0; i < cutPlace.Length; ++i) { double distLoc = Geometry.Dist(position, iCurve2.PointAt(cutPlace[i])); // double distLoc = Geometry.Dist(objectPoint2, iCurve2.PointAt(cutPlace[i])); if (distLoc < dist) { dist = distLoc; param2 = cutPlace[i]; } } } if (!Precision.IsNull(param1) || !Precision.IsNull(param2))// was gefunden { base.FeedBack.ClearSelected(); bool connect = false; if ((param1 > (1 + 1e-8) || param1 < -1e-8)) { // also nur bei realer Verlängerung nach oben oder unten und offen newCurve = iCurve1.Clone(); if (param1 < 0.5) { newCurve.StartPoint = iCurve1.PointAt(param1); } else { newCurve.EndPoint = iCurve1.PointAt(param1); } (newCurve as IGeoObject).CopyAttributes(iCurve1 as IGeoObject); base.FeedBack.AddSelected(newCurve as IGeoObject);// erste Linie einfügen connect = true; } if ((param2 > (1 + 1e-8) || param2 < -1e-8)) { // also nur bei realer Verlängerung nach oben oder unten und offen newCurve = iCurve2.Clone(); if (param2 < 0.5) { newCurve.StartPoint = iCurve2.PointAt(param2); } else { newCurve.EndPoint = iCurve2.PointAt(param2); } (newCurve as IGeoObject).CopyAttributes(iCurve2 as IGeoObject); base.FeedBack.AddSelected(newCurve as IGeoObject);// letzte Linie einfügen connect = true; } if (connect) { return(true); } } } param1 = 0.0; param2 = 0.0; return(false); }
private bool showObject() { // jetzt werden die Schnittparameter bestimmt base.ActiveObject = null; base.FeedBack.ClearSelected(); double[] cutPlace; owner = (iCurve as IGeoObject).Owner; // owner merken für löschen und Einfügen trimCurve = null; param1 = 0.0; param2 = 1.0; // if (trimObject.Fixed) if (sourceCurve != null) { cutPlace = Curves.Intersect(iCurve, sourceCurve, true); Array.Sort(cutPlace); } else { cutPlace = base.Frame.ActiveView.ProjectedModel.GetIntersectionParameters(iCurve, ProjectedModel.IntersectionMode.InsideAndSelfIntersection); } // von Gerhard: cutPlace hat alle Schnittpositionen, aufsteigend sortiert // ein Problem taucht auf, wenn das Objekt an Anfangspunkt oder Endpunkt // genau einen Schnitt hat, dann enthält cutPlace 0.0 oder 1.0. Sind das dann die // einzigen Schnittpunkte, dann soll das Objekt gelöscht werden können: // ein Schnittpunkt sehr nahe bei Null oder sehr nahe bei eins deleteObject = true; for (int i = 0; i < cutPlace.Length; i++) { // also: nicht entweder fast Null oder fast eins if (!((Math.Abs(cutPlace[i]) < 1e-8) || (Math.Abs(cutPlace[i] - 1) < 1e-8))) { deleteObject = false; break; } } //if ((cutPlace.Length == 1) && ((Math.Abs(cutPlace[0])<1e-10) || (Math.Abs(cutPlace[0]-1) <1e-10)) // || // // oder 2 Schnittpunkte und erster sehr nahe bei Null und zweiter sehr nahe bei eins // ((cutPlace.Length == 2) && ((Math.Abs(cutPlace[0])<1e-10) && (Math.Abs(cutPlace[1]-1) <1e-10))) // || // ((cutPlace.Length == 0) && (sourceCurve == null))) // also: einzeln stehendes Element ohne Schnittpunkte if (deleteObject) { trimCurve = iCurve.Clone(); // deleteObject = true; } else { // von Gerhard: cutPlace hat alle Schnittpositionen, aufsteigend sortiert // ein Problem taucht auf, wenn das Objekt an Anfangspunkt oder Endpunkt // genau einen Schnitt hat, dann enthält cutPlace 0.0 oder 1.0. Das tritt oft // auf, z.B. wenn man eine Linie zweimal trimmt. Also alles was <=0.0 und =>1.0 ist // muss raus: if (iCurve.IsClosed) { // hier evtl. Schnittpunkte bei 0.0 auf 1.0 verdoppeln und umgekehrt, da man nicht weiss, welche Seite man wegtrimmen will // es funktioniert aber auch so, warum auch immer List <double> lst = new List <double>(cutPlace); if (cutPlace[cutPlace.Length - 1] >= 1 - 1e-10) { lst.Insert(0, 0.0); // wenn 1.0 ein Schnittpunkt ist, dann im geschlossenen Fall auch 0.0 } if (cutPlace[0] <= 1e-10) { lst.Add(1.0); } cutPlace = lst.ToArray(); } else { ArrayList tmp = new ArrayList(cutPlace.Length); for (int i = 0; i < cutPlace.Length; ++i) { if (cutPlace[i] > 1e-10 && cutPlace[i] < 1 - 1e-10) { tmp.Add(cutPlace[i]); } } cutPlace = (double[])tmp.ToArray(typeof(double)); } double pos = iCurve.PositionOf(objectPoint); if (cutPlace.Length > 0) // es gibt mindestens einen Schnittpunkt, Schnittpunkte sind sortiert!! { int k = -1; for (int i = 0; i < cutPlace.Length; ++i) { if (cutPlace[i] > pos && ((cutPlace[i] > 0.0 && cutPlace[i] < 1.0) || iCurve.IsClosed)) { // pos ist oft -0.01 oder 1.01, da am Anfang oder Ende gepickt k = i; // Schnittstelle "oberhalb" gefunden break; } } ICurve[] splitedCurves; if (iCurve.IsClosed) { if (k > 0) // zwei Schnittpunkte oberhalb von 0.0 = 0 Grad des Kreises { // dieser Split gilt nur für geschlossenes: splitedCurves = iCurve.Split(cutPlace[k - 1], cutPlace[k]); if (splitedCurves.Length >= 2) { param1 = cutPlace[k - 1]; // merken für onDone param2 = cutPlace[k]; // merken für onDone trimCurve = splitedCurves[0]; // nur den einen nehmen, da eindeutig sortiert } } else { if (cutPlace.Length > 1) // erster und letzter Schnittpunkt, 0 Grad ist eingeschlossen { splitedCurves = iCurve.Split(cutPlace[0], cutPlace[cutPlace.Length - 1]); if (splitedCurves.Length >= 2) { param1 = cutPlace[cutPlace.Length - 1]; // merken für onDone param2 = cutPlace[0]; // merken für onDone trimCurve = splitedCurves[1]; // nur den einen nehmen, da eindeutig sortiert } } } } else // jetzt die offenen Objekte: { if (k <= 0) // trimmen am Ende { if (k == -1) { // Pickpunkt am oberen Ende splitedCurves = iCurve.Split(cutPlace[cutPlace.Length - 1]); if (splitedCurves.Length >= 2) { param2 = cutPlace[cutPlace.Length - 1]; // trimm(0.0,param2) merken für onDone trimCurve = splitedCurves[1]; } } if (k == 0) { // Pickpunkt am unteren Ende splitedCurves = iCurve.Split(cutPlace[0]); if (splitedCurves.Length >= 2) { param1 = cutPlace[0]; // trimm(param1,1.0), merken für onDone trimCurve = splitedCurves[0]; } } } else // trimmen mit mehreren Schnittpunkten, Pickpunkt mittendrinn { trimCurve = iCurve.Clone(); // zunächst Kopie der Kurve splitedCurves = iCurve.Split(cutPlace[k - 1]); // Schnittpunkt unterhalb if (splitedCurves.Length >= 2) { param1 = cutPlace[k - 1]; // merken für onDone trimCurve = splitedCurves[1]; // Kurvenkopie unten abgeschnitten } else { param1 = cutPlace[k]; // merken für onDone } splitedCurves = trimCurve.Split(trimCurve.PositionOf(iCurve.PointAt(cutPlace[k]))); // Schnittpunkt oberhalb if (splitedCurves.Length >= 2) { param2 = cutPlace[k]; // merken für onDone trimCurve = splitedCurves[0]; // Kurvenkopie auch noch oben abgeschnitten } else { param2 = cutPlace[k - 1]; // merken für onDone } } } } } if (trimCurve != null) { (trimCurve as IGeoObject).CopyAttributes(iCurve as IGeoObject); Color backColor = base.Frame.GetColorSetting("Colors.Feedback", Color.DarkGray); if (trimCurve is IColorDef) { (trimCurve as IColorDef).ColorDef = new ColorDef("", backColor); } base.FeedBack.AddSelected(trimCurve as IGeoObject); // darstellen base.ActiveObject = trimCurve as IGeoObject; // merken return(true); } return(false); }