private bool showLine() { // Linie ist nicht senkrecht auf der ActiveDrawingPlane: if (!Precision.SameDirection(base.ActiveDrawingPlane.Normal, iCurve.StartDirection, false)) { // Ebene senkrecht auf ActiveDrawingPlane und Linie base.MultiSolutionCount = 2; Plane pl = new Plane(iCurve.StartPoint, iCurve.StartDirection, (base.ActiveDrawingPlane.Normal ^ iCurve.StartDirection)); ICurve2D l2D = iCurve.GetProjectedCurve(pl); if (l2D is Path2D) { (l2D as Path2D).Flatten(); } ICurve2D l2DP; if (nextSol) { l2DP = l2D.Parallel(parallelDist, false, 0.0, 0.0); } else { l2DP = l2D.Parallel(-parallelDist, false, 0.0, 0.0); } line.SetTwoPoints(pl.ToGlobal(l2DP.StartPoint), pl.ToGlobal(l2DP.EndPoint)); // Ebene senkrecht auf der Parallelen-Ebene Plane plDist = new Plane(iCurve.StartPoint, pl.Normal, iCurve.StartDirection); lengthInput.SetDistanceFromPlane(plDist); base.ShowActiveObject = true; return(true); } base.MultiSolutionCount = 0; base.ShowActiveObject = false; return(false); }
private bool showLine() { Plane pl; if (Curves.GetCommonPlane(throughPoint, iCurve, out pl)) { ICurve2D l2D = iCurve.GetProjectedCurve(pl); if (l2D is Path2D) { (l2D as Path2D).Flatten(); } double dist = l2D.Distance(pl.Project(throughPoint)); // System.Diagnostics.Trace.WriteLine(dist.ToString()); ICurve2D l2DP = l2D.Parallel(-dist, false, 0.0, 0.0); line.SetTwoPoints(pl.ToGlobal(l2DP.StartPoint), pl.ToGlobal(l2DP.EndPoint)); base.ShowActiveObject = true; return(true); } base.ShowActiveObject = false; return(false); }
public override ISurface GetOffsetSurface(double offset) { if (basisCurve.GetPlanarState() != PlanarState.NonPlanar) { Plane pln = Plane.XYPlane; if (basisCurve.GetPlanarState() == PlanarState.Planar) { pln = basisCurve.GetPlane(); } else if (basisCurve.GetPlanarState() == PlanarState.UnderDetermined) { pln = new Plane(basisCurve.StartPoint, basisCurve.StartDirection, basisCurve.StartDirection ^ direction); } ICurve2D c2d = basisCurve.GetProjectedCurve(pln); ICurve2D c2dp = c2d.Parallel(offset, false, Precision.eps, Math.PI); if (c2dp != null) { return(new SurfaceOfLinearExtrusion(c2dp.MakeGeoObject(pln) as ICurve, direction, curveStartParameter, curveEndParameter)); } } return(new OffsetSurface(this, offset)); }
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 showRound() { // jetzt werden die Rundparameter bestimmt Plane pl; try { if (Curves.GetCommonPlane(iCurve1, iCurve2, out pl)) { bool rndPos = false; // Runden möglich GeoPoint2D arcP1 = new GeoPoint2D(0.0, 0.0); GeoPoint2D arcP2 = new GeoPoint2D(0.0, 0.0); GeoPoint2D arcP1Loc = new GeoPoint2D(0.0, 0.0); GeoPoint2D arcP2Loc = new GeoPoint2D(0.0, 0.0); GeoPoint2D arcCenter = new GeoPoint2D(0.0, 0.0); 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(); } // ist beim menrfachrunden nicht nötig!! // hier die Schnittpunkte bestimmen und den ObjectPoint auf den nächsten Schnittpunt setzen // GeoPoint2DWithParameter[] intersectPoints = curve1_2D.Intersect(curve2_2D); // GeoPoint2D objectPoint2D = new GeoPoint2D(0.0,0.0); // double distS = double.MaxValue; // Entfernung des Pickpunkts zu den Schnittpunkten // for (int i=0; i< intersectPoints.Length; ++i) // macht hier wenig Sinn, schadet aber auch nicht // { // macht hier wenig Sinn, schadet aber auch nicht, Kompatibilität zum einfachrunden // double distLoc = Geometry.dist(intersectPoints[i].p,pl.Project(objectPoint)); // if (distLoc < distS) // { // distS = distLoc; // objectPoint2D = intersectPoints[i].p; // Pickpunkt merken // } // } // statt der Berechnung oben: Auswahlpunkt ist der gemeinsame Punkt der beiden Kurven!! GeoPoint2D objectPoint2D = curve1_2D.EndPoint; double locmin1, locmin2; // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt locmin1 = 0.0; // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt locmin2 = 0.0; // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt double locmax1, locmax2; // Parametergrenzen vorbesetzen für den Fall: Realer Schnittpunkt locmax1 = 1.0; locmax2 = 1.0; // bei mehfachrunden nicht nötig, da alle aneinanderhängen, also nur reale Schnittpunkte! // double locPar; // für den Fall: virtueller Schnittpunkt die Parametergrenzen anpassen // locPar = curve1_2D.PositionOf(objectPoint2D); // position des Schnittpunktes auf der Kurve1 // if ( locPar > 1.0) locmax1 = locPar; // if ( locPar < 0.0) locmin1 = locPar; // locPar = curve2_2D.PositionOf(objectPoint2D); // position des Schnittpunktes auf der Kurve2 // if ( locPar > 1.0) locmax2 = locPar; // if ( locPar < 0.0) locmin2 = locPar; // die Parallelen links und rechts der 2 Kurven ICurve2D P1L1 = curve1_2D.Parallel(roundRad, false, 0.0, 0.0); ICurve2D P1L2 = curve1_2D.Parallel(-roundRad, false, 0.0, 0.0); ICurve2D P2L1 = curve2_2D.Parallel(roundRad, false, 0.0, 0.0); ICurve2D P2L2 = curve2_2D.Parallel(-roundRad, false, 0.0, 0.0); // nun alle mit allen schneiden und Schnittpunkte (=evtl. Mittelpunkte des Bogens) merken ArrayList centers = new ArrayList(); centers.AddRange(P1L1.Intersect(P2L1)); centers.AddRange(P1L1.Intersect(P2L2)); centers.AddRange(P1L2.Intersect(P2L1)); centers.AddRange(P1L2.Intersect(P2L2)); GeoPoint2DWithParameter[] centerPoints = (GeoPoint2DWithParameter[])centers.ToArray(typeof(GeoPoint2DWithParameter)); GeoPoint2D[] perpP; // Lotfusspunkte double loc; // location des schnittpunktes der parallelen auf der Kurve double distCP; // Entfernung von der Ecke für Fusspunkte double distCS = double.MaxValue; // Entfernung von der Ecke für Schnittpunkte bool ok1, ok2; // der gesuchte Schnittpunkt hat einen realen Lotfusspunkt auf beiden Kurven und den Abstand roundRad von diesen for (int i = 0; i < centerPoints.Length; ++i) // Schleife über alle Schnittpunkte { ok1 = false; ok2 = false; perpP = curve1_2D.PerpendicularFoot(centerPoints[i].p); // Lotpunkt(e) Kurve 1 distCP = double.MaxValue; for (int j = 0; j < perpP.Length; ++j) // Schleife über alle Lotpunkte Kurve 1 { loc = curve1_2D.PositionOf(perpP[j]); // der Parameter des j. Lotpunktes auf Kurve1 // der Parameter muss innerhalb der Kurve sein und der Abstand = roundRad if ((loc >= locmin1) & (loc <= locmax1) & (Math.Abs(Geometry.Dist(perpP[j], centerPoints[i].p) - roundRad) < Precision.eps)) { double distLoc = Geometry.Dist(perpP[j], objectPoint2D); if (distLoc < distCP) { distCP = distLoc; arcP1Loc = perpP[j]; // Lotpunkt schonmal merken } ok1 = true; } } if (ok1) // also was gefunden oben, jetzt dasselbe mit Kurve 2 { perpP = curve2_2D.PerpendicularFoot(centerPoints[i].p); // Lotpunkt(e) Kurve 2 distCP = double.MaxValue; for (int j = 0; j < perpP.Length; ++j) // Schleife über alle Lotpunkte Kurve 2 { loc = curve2_2D.PositionOf(perpP[j]); // der Parameter des j. Lotpunktes auf Kurve2 // der Parameter muss innerhalb der Kurve sein und der Abstand = roundRad if ((loc >= locmin2) & (loc <= locmax2) & (Math.Abs(Geometry.Dist(perpP[j], centerPoints[i].p) - roundRad) < Precision.eps)) { double distLoc = Geometry.Dist(perpP[j], objectPoint2D); if (distLoc < distCP) { distCP = distLoc; arcP2Loc = perpP[j]; // Lotpunkt schonmal merken } ok2 = true; } } } if (ok2) { // falls mehrere Schnittpunkte alle Bedingungen erfüllen: Den nächsten nehmen! double distLoc = Geometry.Dist(centerPoints[i].p, objectPoint2D); if (distLoc < distCS) { distCS = distLoc; // jetzt merken arcCenter = centerPoints[i].p; arcP1 = arcP1Loc; arcP2 = arcP2Loc; rndPos = true; } } } if (rndPos && !Precision.IsEqual(arcP1, arcP2)) // runden war möglich { // Mittelwert zwischen dem Kurven // roundRadCalc = (Math.Abs(curve1_2D.Distance(pl.Project(radiusPoint))) + Math.Abs(curve2_2D.Distance(pl.Project(radiusPoint)))) / 2.0; objectPoint = pl.ToGlobal(objectPoint2D); // merken als Entscheidungskriterium, ist hier immer der Schnittpunkt Ellipse arc = Ellipse.Construct(); Ellipse arc1 = Ellipse.Construct(); arc.SetArcPlaneCenterStartEndPoint(base.ActiveDrawingPlane, arcCenter, arcP1, arcP2, pl, false); arc1.SetArcPlaneCenterStartEndPoint(base.ActiveDrawingPlane, arcCenter, arcP1, arcP2, pl, true); if (Math.Abs(arc.SweepParameter) > Math.Abs(arc1.SweepParameter)) // es ist immer der kleinere Bogen! { arc = arc1; } arc.CopyAttributes(iCurve1 as IGeoObject); if (iCurve1.PositionOf(objectPoint) > 0.5) { iCurve1.Trim(0.0, iCurve1.PositionOf(arc.StartPoint)); } else { iCurve1.Trim(iCurve1.PositionOf(arc.StartPoint), 1.0); } if (iCurve2.PositionOf(objectPoint) > 0.5) { iCurve2.Trim(0.0, iCurve2.PositionOf(arc.EndPoint)); } else { iCurve2.Trim(iCurve2.PositionOf(arc.EndPoint), 1.0); } if (iCurve1.Length > Precision.eps) { blk.Add(iCurve1 as IGeoObject); // base.FeedBack.AddSelected(iCurve1 as IGeoObject); // darstellen } blk.Add(arc); // base.FeedBack.AddSelected(arc); // darstellen iCurve1 = iCurve2; // getrimmte Curve2 als Grundlage zur nächsten Berechnung return(true); } } } catch (ApplicationException e) { return(false); } blk.Add(iCurve1 as IGeoObject); // unveränderte 1. Kurve zufügen, da kein Runden möglich // base.FeedBack.AddSelected(iCurve1 as IGeoObject); // darstellen iCurve1 = iCurve2; // unveränderte Curve2 als Grundlage zur nächsten Berechnung return(false); }