public VisualCurve Clone() { VisualCurve c = new VisualCurve((ICurve)(curve.Clone())); c.path = this.Path; return(c); }
bool pipeTest() { int extrudeModeTemp = extrudeMode; Path p = null; if (iCurvePipe is Path) { p = (iCurvePipe.Clone() as Path); } else { p = Path.Construct(); p.Set(new ICurve[] { iCurvePipe.Clone() }); } // p = CADability.GeoObject.Path.CreateFromModel(iCurvePipe, Frame.ActiveView.Model, Frame.ActiveView.Projection, true); //if (p == null) //{ // also nur Einzelelement // if (iCurvePipe is Path) // { // schon fertig // p = iCurvePipe.Clone() as Path; // } // else // { // Pfad aus Einzelobjekt machen: // p = Path.Construct(); // p.Set(new ICurve[] { iCurvePipe.Clone() }); // } //} //else //{ // CreateFromModel hat was zusammengesetzt p.Flatten(); //} if (p != null) { extrudeMode = 3; // merken, ob Extrudier-Vektor, Höhe oder Pfad optionalOrg(); pipePath = p; if (geoObjectInput.Fixed) { if (extrudeOrg()) { return(true); } } return(true); } extrudeMode = extrudeModeTemp; return(false); }
/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.Clone ()"/> /// </summary> /// <returns></returns> public override ISurface Clone() { SurfaceOfLinearExtrusion res = new SurfaceOfLinearExtrusion(basisCurve.Clone(), direction, curveStartParameter, curveEndParameter); res.usedArea = usedArea; return(res); }
internal static bool SameGeometry(ICurve curve1, ICurve curve2, double precision, out bool reverse) { // erstmal für nicht geschlossene Kurven double d1 = (curve1.StartPoint | curve2.StartPoint) + (curve1.EndPoint | curve2.EndPoint); double d2 = (curve1.EndPoint | curve2.StartPoint) + (curve1.StartPoint | curve2.EndPoint); if (curve1.IsClosed && curve2.IsClosed || (d1 < 2 * precision && d2 < 2 * precision)) { reverse = curve1.StartDirection * curve2.StartDirection < 0; } else { reverse = d1 > d2; if (d1 > 2 * precision && d2 > 2 * precision) { return(false); } } if (reverse) { curve2 = curve2.Clone(); curve2.Reverse(); return(curve1.SameGeometry(curve2, precision)); } else { return(curve1.SameGeometry(curve2, precision)); } }
double startParam, endParam; // fürs Trimmen, gibt auch die Richtung an, oder? public IntermediateCurve(ICurve firstCurve, ICurve secondCurve, double v, double startParam, double endParam) { this.firstCurve = firstCurve.Clone(); // die werden bei Modify verändert, also nicht die originale nehmen this.secondCurve = secondCurve.Clone(); this.v = v; this.startParam = startParam; this.endParam = endParam; }
private void Recalc() { // jeder zweite Abschnitt wird als selektiertes Feedbackobjekt dargestellt base.FeedBack.ClearAll(); ICurve toSplit = theCurve; double totlen = theCurve.Length; double sumlen = 0.0; for (int i = 0; i < number; ++i) { ICurve splitted = toSplit.Clone(); double start = theCurve.PositionAtLength(sumlen); sumlen += sections[i] * totlen; double end = theCurve.PositionAtLength(sumlen); splitted.Trim(start, end); if ((i & 1) == 0) { IGeoObject toAdd = splitted as IGeoObject; base.FeedBack.AddSelected(toAdd); } } // alter Text, ungleich aufgeteilt //if ((number & 1) != 0) //{ // base.FeedBack.AddSelected(toSplit as IGeoObject); //} //for (int i = 0; i < number; ++i) //{ // double sum = 0.0; // for (int j = i; j < number; ++j) // { // sum += sections[j]; // } // Positions[i] = sections[i] / sum; //} //for (int i = 0; i < number - 1; ++i) //{ // ICurve[] splitted = toSplit.Split(Positions[i]); // if (splitted.Length == 2 ) // { // if ((i & 1) == 0) // { // IGeoObject toAdd = splitted[0] as IGeoObject; // base.FeedBack.AddSelected(toAdd); // } // toSplit = splitted[1]; // } //} //if ((number & 1) != 0) //{ // base.FeedBack.AddSelected(toSplit as IGeoObject); //} }
public override void OnDone() { // zerstückeln, original entfernen und Stücke einfügen // TODO: noch auf 0.0 aufpassen! // TODO: Polyline geht nicht richtig, Ellipse auch nicht, da nicht linear auf dem Umfang IGeoObject go = theCurve as IGeoObject; if (go != null) { IGeoObjectOwner owner = go.Owner; if (owner != null) { using (Frame.Project.Undo.UndoFrame) { //if (go is Polyline) //{ // (go as Polyline).IsClosed = false; // aufbrechen //} // nicht aufbrechen, das ist jetzt in Split ordentlich geregelt owner.Remove(go); ICurve toSplit = theCurve; double totlen = theCurve.Length; double sumlen = 0.0; for (int i = 0; i < number; ++i) { ICurve splitted = toSplit.Clone(); double start = theCurve.PositionAtLength(sumlen); sumlen += sections[i] * totlen; double end = theCurve.PositionAtLength(sumlen); splitted.Trim(start, end); (splitted as IGeoObject).CopyAttributes(go); owner.Add(splitted as IGeoObject); } //double[] Positions = new double[number]; //for (int i = 0; i < number; ++i) //{ // double sum = 0.0; // for (int j = i; j < number; ++j) // { // sum += sections[j]; // } // Positions[i] = sections[i] / sum; //} //for (int i = 0; i < number-1; ++i) //{ // ICurve[] splitted = toSplit.Split(Positions[i]); // if (splitted.Length == 2) // { // IGeoObject toAdd = splitted[0] as IGeoObject; // toAdd.CopyAttributes(go); // owner.Add(toAdd); // toSplit = splitted[1]; // } //} //(toSplit as IGeoObject).CopyAttributes(go); //owner.Add(toSplit as IGeoObject); } } } base.OnDone(); }
//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.FeedBack.ClearSelected(); base.ActiveObject = null; double[] cutPlace = base.Frame.ActiveView.ProjectedModel.GetIntersectionParameters(iCurve, ProjectedModel.IntersectionMode.InsideAndSelfIntersection); owner = (iCurve as IGeoObject).Owner; // owner merken für löschen und Einfügen double pos = iCurve.PositionOf(objectPoint); // der Pickpunkt trimCurves = null; bool realCut; if (cutPlace.Length > 0) // es gibt mindestens einen Schnitt { realCut = false; for (int i = 0; i < cutPlace.Length; ++i) { if (!((Math.Abs(cutPlace[i]) < 1e-8) || (Math.Abs(cutPlace[i] - 1) < 1e-8))) { realCut = true; break; } } if (realCut) { int k = -1; for (int i = 0; i < cutPlace.Length; ++i) { if (cutPlace[i] > pos && cutPlace[i] > 0.0 && cutPlace[i] < 1.0) { // 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/Rechtecks { splitedCurves = iCurve.Split(cutPlace[k - 1], cutPlace[k]); if (splitedCurves.Length >= 2) { trimCurves = splitedCurves; // nur den einen nehmen, da eindeutig sortiert 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) { trimCurves = splitedCurves; // nur den einen nehmen, da eindeutig sortiert 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) { trimCurves = splitedCurves; // nur den einen nehmen, da eindeutig sortiert trimCurve = splitedCurves[1]; } } if (k == 0) { // Pickpunkt am unteren Ende splitedCurves = iCurve.Split(cutPlace[0]); if (splitedCurves.Length >= 2) { trimCurves = splitedCurves; // nur den einen nehmen, da eindeutig sortiert trimCurve = splitedCurves[0]; } } } else // trimmen mit mehreren Schnittpunkten, Pickpunkt mittendrinn { /* trimCurves = new ICurve[3]; * splitedCurves = iCurve.Split(cutPlace[k-1]); * trimCurves[0] = splitedCurves[0]; // untere Linie * splitedCurves = iCurve.Split(cutPlace[k]); * trimCurves[1] = splitedCurves[1]; // obere Linie * ICurve curveTmp = iCurve.Clone(); * curveTmp.Trim(cutPlace[k-1],cutPlace[k]); // mittlere Linie * trimCurves[2] = curveTmp; */ trimCurve = iCurve.Clone(); // zunächst Kopie der Kurve // tempräres Array zum Sammeln der Kurven ArrayList tmpArray = new ArrayList(); splitedCurves = iCurve.Split(cutPlace[k - 1]); // Schnittpunkt unterhalb if (splitedCurves.Length >= 2) { // den unteren Abschnitt sammeln tmpArray.Add(splitedCurves[0]); trimCurve = splitedCurves[1]; // Kurvenkopie unten abgeschnitten } // auf der (evtl) unten abgeschnittenen Kopie weitermachen splitedCurves = trimCurve.Split(trimCurve.PositionOf(iCurve.PointAt(cutPlace[k]))); // Schnittpunkt oberhalb if (splitedCurves.Length >= 2) { tmpArray.Add(splitedCurves[0]); tmpArray.Add(splitedCurves[1]); trimCurve = splitedCurves[0]; // Kurvenkopie auch noch oben abgeschnitten } else { tmpArray.Add(trimCurve); // kein echter Schnittpunkt, dann das Reststück zufügen } trimCurves = (ICurve[])tmpArray.ToArray(typeof(ICurve)); // reTyping nach Sammeln } } } } if (trimCurves != 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); }
public object Clone() { return(new MoveTo((ICurve)comp.Clone(), new_p)); }
public object Clone() { return(new Fragment((ICurve)comp.Clone(), t_start, t_finish)); }
private bool showRoundPathTestIntersection(ICurve iCurveTest) { // jetzt getestet, ob der Pfad sich selbst überschneidet: // owner = (iCurveTest as IGeoObject).Owner; // owner merken für löschen und Einfügen if (iCurveTest.GetPlanarState() == PlanarState.Planar) // also in einer Ebene { Plane pl = iCurveTest.GetPlane(); ICurve2D curve_2D = iCurveTest.GetProjectedCurve(pl); // die 2D-Kurve if (curve_2D is Path2D) { (curve_2D as Path2D).Flatten(); } ICurve2D curveTemp; if (iCurveTest is Polyline) { // GetSelfIntersections geht nur mit Pfaden! Path p = Path.Construct(); p.Set(new ICurve[] { iCurveTest.Clone() }); p.Flatten(); curveTemp = p.GetProjectedCurve(pl); } else { curveTemp = curve_2D; } double[] pathIntersectionPoints = curveTemp.GetSelfIntersections(); // die Schnittpunkte mit sich selbst if (pathIntersectionPoints.Length > 0) { double distS = double.MaxValue; // Entfernung des Pickpunkts zu den Schnittpunkten GeoPoint2D objectPoint2D = new GeoPoint2D(0.0, 0.0); int interSectIndex = 0; for (int i = 0; i < pathIntersectionPoints.Length; i += 2) // immer paarweise, jeweils am Anfang und Ende { // den nächsten Schnittpunkt bestimmen, einer pro Paar reicht dazu GeoPoint2D ps = curveTemp.PointAt(pathIntersectionPoints[i]); double distLoc = Geometry.Dist(ps, pl.Project(objectPoint)); if (distLoc < distS) { distS = distLoc; objectPoint2D = ps; // Pickpunkt merken interSectIndex = i; } } // jetzt hat er den nächsten Kreuzungspunkt bestimmt. Nun nachschauen, ob die Mouseposition evtl. noch näher an einem gewöhnlichen Pfadpunkt steht! Wenn ja: nichts machen, der Resr erfolgt dann weiter unten in showRound! for (int i = 0; i < (curveTemp as Path2D).SubCurvesCount; i++) { double distLoc = Geometry.Dist((curveTemp as Path2D).SubCurves[i].StartPoint, pl.Project(objectPoint)); if (distLoc < distS) { // ein Pfadpunkt liegt näher: das reicht! Raus hier! return(false); } } // Jetzt: die Kreuzungspunkte (einer von vorne, einer von hinten) in die Testkurve einfuegen! if (iCurveTest is Path) { (iCurveTest as Path).InsertPoint(pathIntersectionPoints[interSectIndex]); (iCurveTest as Path).InsertPoint(pathIntersectionPoints[interSectIndex + 1]); } if (iCurveTest is Polyline) { (iCurveTest as Polyline).InsertPoint(pathIntersectionPoints[interSectIndex]); (iCurveTest as Polyline).InsertPoint(pathIntersectionPoints[interSectIndex + 1]); } return(true); } } return(false); }
private bool showCutOff() { // nur wenn beide Kurven gültig sind if ((iCurve1 != null) && (iCurve2 != null) && (iCurve1 != iCurve2)) { Plane pl; // nur bei gemeisamer Ebene if (Curves.GetCommonPlane(iCurve1, iCurve2, out pl)) { // !!! // 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)) // runden 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 sythetisieren: * if (cutPoint.par1 <= 0.5) * { * newCurve.StartPoint = iCurve1.PointAt(cutPoint.par1); * parCut = (sideLength)/newCurve.Length; // der Parameter des Fasenpunktes * } * else * { * newCurve.EndPoint = iCurve1.PointAt(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; 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 line = Line.Construct(); 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 objectPoint = pl.ToGlobal(cutPoint.p); if (iCurve1.PositionOf(objectPoint) > 0.5) // am oberen Ende geklickt { iCurve1.Trim(0.0, iCurve1.PositionOf(line.StartPoint)); } else { iCurve1.Trim(iCurve1.PositionOf(line.StartPoint), 1.0); } if (iCurve2.PositionOf(objectPoint) > 0.5) // am oberen Ende geklickt { iCurve2.Trim(0.0, iCurve2.PositionOf(line.EndPoint)); objectPoint = iCurve2.StartPoint; } else { iCurve2.Trim(iCurve2.PositionOf(line.EndPoint), 1.0); objectPoint = iCurve2.EndPoint; } (line as IGeoObject).CopyAttributes(iCurve1 as IGeoObject); // objectPoint = pl.ToGlobal(cutPoint2.p); blk.Add(iCurve1 as IGeoObject); blk.Add(line); // base.FeedBack.AddSelected(iCurve1 as IGeoObject);// darstellen // base.FeedBack.AddSelected(line);// darstellen iCurve1 = iCurve2; // getrimmte Curve2 als Grundlage zur nächsten Berechnung return(true); } } } } } blk.Add(iCurve1 as IGeoObject); // unveränderte 1. Kurve zufügen, da kein Fasen möglich // base.FeedBack.AddSelected(iCurve1 as IGeoObject);// darstellen iCurve1 = iCurve2; // unveränderte Curve2 als Grundlage zur nächsten Berechnung } // base.ActiveObject = null; return(false); }
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); }
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); }
/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.Clone ()"/> /// </summary> /// <returns></returns> public override ISurface Clone() { return(new RuledSurface(firstCurve.Clone(), secondCurve.Clone())); // need to clone the curves, because the new surface might be modified }