public override GeoVector DirectionAt(double pos) { GeoPoint2D p = curve2D.PointAt(pos); GeoVector2D dir = curve2D.DirectionAt(pos); surface.DerivationAt(p, out GeoPoint location, out GeoVector diru, out GeoVector dirv); return(dir.x * diru + dir.y * dirv); }
/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.PointAt (GeoPoint2D)"/> /// </summary> /// <param name="uv"></param> /// <returns></returns> public override GeoPoint PointAt(GeoPoint2D uv) { double pos = GetPos(uv.y); GeoPoint2D p2d = basisCurve2D.PointAt(pos); ModOp rot = ModOp.Rotate(1, (SweepAngle)uv.x); ModOp movePitch = ModOp.Translate(0, pitch * uv.x / (Math.PI * 2.0), 0); return(toSurface * movePitch * rot * p2d); }
/// <summary> /// Liefert die 3D Kurve zu diesem Objekt, wenn die Surface stimmt. Bestimmt bei geklippten Objekten /// die Start- und Endpunkte im 3D. Ansonsten ist es identisch mit der 3D Kurve /// </summary> /// <param name="onThisSurface"></param> /// <returns></returns> public ICurve Get3DCurve(ISurface onThisSurface) { if (onThisSurface != theSurface) { return(null); } if (!clipped) { return(dualSurfaceCurve.Curve3D); } // bei interpolatedDualSurfaceCurve ist schon geklippt, und hier wird nochmal // mit position of parameter gesucht und nochmal geklippt, das ist schlecht!! double startParam = dualSurfaceCurve.Curve3D.PositionOf(startPoint); double endParam = dualSurfaceCurve.Curve3D.PositionOf(endPoint); if (endParam < startParam) { double tmp = endParam; endParam = startParam; startParam = tmp; } if (dualSurfaceCurve.Curve3D.IsClosed) { ICurve[] splitted = dualSurfaceCurve.Curve3D.Split(startParam, endParam); if (splitted.Length == 2) // müsste wohl immer so eine { double pos1 = splitted[0].PositionOf(theSurface.PointAt(clippedCurve.PointAt(0.5))); double pos2 = splitted[1].PositionOf(theSurface.PointAt(clippedCurve.PointAt(0.5))); if (Math.Abs(pos1 - 0.5) < Math.Abs(pos2 - 0.5)) { return(splitted[0]); } else { return(splitted[1]); } } else if (splitted.Length > 0) { // sollte nicht vorkommen return(splitted[0]); } else { // sollte nicht vorkommen return(null); } } else { ICurve res = dualSurfaceCurve.Curve3D.Clone(); res.Trim(startParam, endParam); return(res); } }
GeoPoint2D ICurveTransformation2D.TransformPoint(ICurve2D curve, double par) { // gesucht: Punkt der Kurve im nichtperiodischen System GeoPoint2D uv = curve.PointAt(par); double r = uv.y - vmin; return(new GeoPoint2D(r * Math.Cos(uv.x), r * Math.Sin(uv.x))); }
GeoVector2D ICurveTransformation2D.TransformDeriv1(ICurve2D curve, double par) { // gesucht: Richtung im nicht periodischen System GeoPoint2D uv = curve.PointAt(par); GeoVector2D dir = curve.DirectionAt(par); return(new GeoVector2D(Math.Cos(uv.x) * (dir.y) - Math.Sin(uv.x) * (dir.x) * (uv.y - vmin), Math.Cos(uv.x) * (dir.x) * (uv.y - vmin) + Math.Sin(uv.x) * (dir.y))); }
ModOp IMovement.GetPosition(double u) { GeoVector du, dv; GeoPoint loc; surface.DerivationAt(c2d.PointAt(u), out loc, out du, out dv); GeoVector2D dir2d = c2d.DirectionAt(u); GeoVector ux = dir2d.x * du + dir2d.y * dv; GeoVector uz = du ^ dv; GeoVector uy = ux ^ uz; ModOp res = ModOp.Translate(loc - GeoPoint.Origin) * ModOp.Fit(new GeoVector[] { startX.Normalized, startY.Normalized, startZ.Normalized }, new GeoVector[] { ux.Normalized, uy.Normalized, uz.Normalized }) * ModOp.Translate(GeoPoint.Origin - startPos); return(res); //return new ModOp(toUnit * ux, toUnit * uy, toUnit * uz, toUnit * loc); }
private bool showLine() { ArrayList usableCurves = new ArrayList(); // lokales Array, das die gültigen Kurven sammelt double mindist = double.MaxValue; for (int i = 0; i < perpCurves.Length; ++i) { Plane pl; if (Curves.GetCommonPlane(startPoint, perpCurves[i], out pl)) { ICurve2D l2D = perpCurves[i].GetProjectedCurve(pl); if (l2D is Path2D) { (l2D as Path2D).Flatten(); } GeoPoint2D[] perpPoints = l2D.PerpendicularFoot(pl.Project(startPoint)); if (perpPoints.Length > 0) { // eine gültige Kurve ist gefunden usableCurves.Add(perpCurves[i]); for (int j = 0; j < perpPoints.Length; ++j) { // double dist = Geometry.Dist(perpPoints[j],pl.Project(startPoint)); double dist = Geometry.Dist(perpPoints[j], pl.Project(objectPoint)); if (dist < mindist) { mindist = dist; selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist endPoint = perpPoints[j]; } } } else { // beim Kreis oder Bogen vom Mittelpunkt aus gilt jeder Punkt if (l2D is Circle2D) { if (Precision.IsEqual((l2D as Circle2D).Center, pl.Project(startPoint))) { GeoPoint2D pp = l2D.PointAt(l2D.PositionOf(pl.Project(objectPoint))); double dist = Geometry.Dist(pp, pl.Project(objectPoint)); if (dist < mindist) { mindist = dist; selected = usableCurves.Count - 1; // merken, welche Kurve die aktuell benutzte ist endPoint = pp; } } } } } if (mindist < double.MaxValue) { line.SetTwoPoints(startPoint, pl.ToGlobal(endPoint)); perpCurves = (ICurve[])usableCurves.ToArray(typeof(ICurve)); // perpCurves wird mit den gültigen überschrieben und unten zur Anzeige zurückgegeben an den Sender base.ShowActiveObject = true; return(true); } } line.SetTwoPoints(startPoint, objectPoint); base.ShowActiveObject = true; return(false); }
// private Border FindNextBorder() // { // // Alle Cluster enthalten zwei Punkte. Suche einen Joint, dessen angeschlossener // // ICurve2D länger als maxGap ist (warum eigentlich?) // // Gehe solange durch die Cluster, bis wieder der erste Punkt erreicht ist // Joint StartWith = null; // foreach (Cluster cl in clusterSet) // { // foreach (Joint lp in cl.Points) // { // if (lp.curve.Length>maxGap) // { // StartWith = lp; // RemoveJoint(lp,cl); // break; // } // } // if (StartWith!=null) break; // } // if (StartWith==null) return null; // keinen Anfang gefunden // Joint LastPoint = StartWith; // Cluster goon = null; // BorderBuilder makeBorder = new BorderBuilder(); // makeBorder.Precision = clusterSize; // while ((goon = ExtractCurve(LastPoint.curve,!LastPoint.isStartPoint))!=null) // { // makeBorder.AddSegment(LastPoint.curve.CloneReverse(!LastPoint.isStartPoint)); // if (goon.Points.Count==0) break; // auf den letzten und ersten Punkt gestoßen // LastPoint = (Joint)goon.Points[0]; // es sollte ja nur diesen einen geben // RemoveJoint(LastPoint,goon); // damit müsste dieser Cluster verschwinden // } // return makeBorder.BuildBorder(); // } // private bool FindSimpleBorder(Set clusterSet, ArrayList AllBorders, Set UsedJoints, ICurve2D startWith, bool forward) // { // Set tmpUsedJoints = new Set(); // tmpUsedJoints.Add(new UsedJoint(startWith,forward)); // // Anfangskante gefunden, wie gehts weiter // BorderBuilder bb = new BorderBuilder(); // bb.Precision = clusterSize; // if (forward) bb.AddSegment(startWith.Clone()); // else bb.AddSegment(startWith.CloneReverse(true)); // // while (!bb.IsClosed) // { // Cluster cl = FindCluster(startWith, bb.EndPoint, false); // if (cl==null) return false; // eine angefangene Border geht nicht weiter, sollte nicht passieren, da keine Sackgassen // int ind = -1; // double sa = -1.0; // for (int i=0; i<cl.Points.Count; ++i) // { // Joint j = cl.Points[i] as Joint; // if (j.curve==startWith) continue; // nicht auf der Stelle rückwärts weiter // UsedJoint uj = new UsedJoint(j.curve,j.isStartPoint); // if (!UsedJoints.Contains(uj) && !tmpUsedJoints.Contains(uj)) // { // SweepAngle d; // if (j.isStartPoint) d = new SweepAngle(bb.EndDirection,j.curve.StartDirection); // else d = new SweepAngle(bb.EndDirection,j.curve.EndDirection.Opposite()); // // d zwischen -PI und +PI // if (d+Math.PI > sa) // { // je mehr nach links umso größer is d // sa = d+Math.PI; // ind = i; // } // } // } // if (ind>=0) // { // Joint j = cl.Points[ind] as Joint; // if (j.isStartPoint) bb.AddSegment(j.curve.Clone()); // else bb.AddSegment(j.curve.CloneReverse(true)); // tmpUsedJoints.Add(new UsedJoint(j.curve,j.isStartPoint)); // startWith = j.curve; // } // else // { // return false; // kein weitergehen möglich // } // } // if (bb.IsOriented) // { // Border bdr = bb.BuildBorder(); // AllBorders.Add(bdr); // foreach (UsedJoint uj in tmpUsedJoints) // { // if (!UsedJoints.Contains(uj)) // { // UsedJoints.Add(uj); // } // else // { // int dbg = 0; // } // } // return true; // } // return false; // } // private bool FindSimpleBorder(Set clusterSet, ArrayList AllBorders, Set UsedJoints) // { // // es wird eine minimale Border gesucht: von irgend einem Cluster ausgehend immer // // linksrum bis man wieder am Anfang ist. // // UsedJoints enthält UsedJoint objekte, damit man feststellen kann, ob eine Kante bereits // // benutzt ist oder nicht // ICurve2D startWith = null; // bool forward = false; // foreach (Cluster cl in clusterSet) // { // for (int i=0; i<cl.Points.Count; ++i) // { // UsedJoint uj = new UsedJoint(); // Joint j = cl.Points[i] as Joint; // uj.curve = j.curve; // uj.forward = true; // if (!UsedJoints.Contains(uj)) // { // forward = j.isStartPoint; // startWith = j.curve; // if (FindSimpleBorder(clusterSet,AllBorders,UsedJoints,startWith,forward)) // return true; // } // uj.forward = false; // if (!UsedJoints.Contains(uj)) // { // forward = !j.isStartPoint; // startWith = j.curve; // if (FindSimpleBorder(clusterSet,AllBorders,UsedJoints,startWith,forward)) // return true; // } // } // } // return false; // } private Joint[] SortCluster() { // sortiert die Kanten (Joints) in einem Cluster im Gegenuhrzeigersinn // liefert alle Kanten // Verwerfen von identischen Kanten: // Zwei Kanten in einem Cluster, die das selbe "Gegencluster" haben // stehen im Verdacht identisch zu sein. Ihre Mittelpunkte werden auf // identität überprüft und die Kanten werden ggf. entfernt. foreach (Cluster cl in clusterSet) { for (int i = 0; i < cl.Joints.Count - 1; ++i) { int duplicate = -1; for (int j = i + 1; j < cl.Joints.Count; ++j) { Cluster cl1; Cluster cl2; Joint j1 = cl.Joints[i] as Joint; Joint j2 = cl.Joints[j] as Joint; if (j1.StartCluster == cl) { cl1 = j1.EndCluster; } else { cl1 = j1.StartCluster; } if (j2.StartCluster == cl) { cl2 = j2.EndCluster; } else { cl2 = j2.StartCluster; } if (cl1 == cl2) { // zwei Kanten verbinden dieselben Cluster. Sie könnten identisch sein ICurve2D curve1 = j1.curve.CloneReverse(j1.StartCluster != cl); ICurve2D curve2 = j2.curve.CloneReverse(j2.StartCluster != cl); // curve1 und curve2 haben jetzt die selbe Richtung GeoPoint2D p1 = curve1.PointAt(0.5); GeoPoint2D p2 = curve2.PointAt(0.5); if (Geometry.Dist(p1, p2) < clusterSize) { duplicate = j; break; } } } if (duplicate > 0) { cl.Joints.RemoveAt(duplicate); } } } // zu kurze Joints werden entfern foreach (Cluster cl in clusterSet) { for (int i = cl.Joints.Count - 1; i >= 0; --i) { Joint j1 = cl.Joints[i] as Joint; if (j1.curve.Length < this.clusterSize) { cl.Joints.RemoveAt(i); } } } UntypedSet allJoints = new UntypedSet(); foreach (Cluster cl in clusterSet) { if (cl.Joints.Count < 3) { foreach (Joint j in cl.Joints) { if (!allJoints.Contains(j)) { allJoints.Add(j); } } continue; } // zwei Punkte im cluster muss man nicht sortieren double minDist = double.MaxValue; foreach (Joint j in cl.Joints) { if (!allJoints.Contains(j)) { allJoints.Add(j); } GeoPoint2D p; if (j.StartCluster == cl) { p = j.EndCluster.center; } else { if (j.EndCluster != cl) { throw new CurveGraphException("SortCluster"); } p = j.StartCluster.center; } double d = Geometry.Dist(cl.center, p); if (d == 0.0) { if (j.StartCluster == j.EndCluster) { continue; } throw new CurveGraphException("SortCluster"); } if (d < minDist) { minDist = d; } } // Kreis um cl mit halber Entfernung zum nächsten Knoten als Radius Circle2D c2d = new Circle2D(cl.center, minDist / 2.0); foreach (Joint j in cl.Joints) { GeoPoint2DWithParameter[] ip = c2d.Intersect(j.curve); if (ip.Length > 0) { for (int i = 0; i < ip.Length; ++i) { if (j.curve.IsParameterOnCurve(ip[i].par2)) { Angle a = new Angle(ip[i].p, cl.center); j.tmpAngle = a.Radian; break; } } } else { // darf nicht vorkommen, eine Kante schneidet nicht den Kreis um // den Knoten mit halbem Radius zum nächsten knoten // der Sortierwert bleibt halt 0.0, aber man sollte solche Kanten // entfernen ... // kommt vor, das Problem liegt bei regle4!!! if (j.StartCluster == cl) { // curve startet hier j.tmpAngle = j.curve.StartDirection.Angle; } else { j.tmpAngle = j.curve.EndDirection.Opposite().Angle; } } } cl.Joints.Sort(); // es wird nach tmpAngle sortiert } Joint[] res = new Joint[allJoints.Count]; int ii = 0; foreach (Joint j in allJoints) { // die Kurve exakt ausrichten try { j.curve.StartPoint = j.StartCluster.center; j.curve.EndPoint = j.EndCluster.center; } catch (Curve2DException) { } // z.B. Kreise endpunkt setzen res[ii] = j; ++ii; } return(res); }
static public CurveGraph CrackCurves(GeoObjectList l, Plane plane, double maxGap) { // alle Kurven in l werden in die Ebene plane projiziert. Das ist mal ein erster Ansatz // Man könnte auch gemeinsame Ebenen finden u.s.w. ArrayList curves = new ArrayList(); BoundingRect ext = BoundingRect.EmptyBoundingRect; foreach (IGeoObject go in l) { ICurve cv = go as ICurve; if (cv != null) { ICurve2D cv2 = cv.GetProjectedCurve(plane); if (cv2 != null) { // "3d" wird nur verwendet um hinterher aus den Originalkurven die Ebene zu bestimmen // in die alles zurücktranformiert wird. Besser würde man vermutlich mit "plane" arbeiten // so wie es hier reinkommt. if (cv2 is Path2D && (cv2 as Path2D).GetSelfIntersections().Length > 0) { // ein sich selbst überschneidender Pfad muss aufgelöst werden ICurve2D[] sub = (cv2 as Path2D).SubCurves; curves.AddRange(sub); for (int i = 0; i < sub.Length; ++i) { sub[i].UserData.Add("3d", cv); } ext.MinMax(cv2.GetExtent()); } else { cv2.UserData.Add("3d", cv); curves.Add(cv2); ext.MinMax(cv2.GetExtent()); } } } } if (curves.Count == 0) { return(null); } QuadTree qt = new QuadTree(ext); qt.MaxDeepth = 8; qt.MaxListLen = 3; for (int i = 0; i < curves.Count; ++i) { qt.AddObject(curves[i] as ICurve2D); } // jetzt alle mit allen schneiden und die Schnipsel in eine weitere Liste stecken ArrayList snippet = new ArrayList(); for (int i = 0; i < curves.Count; ++i) { ICurve2D cv1 = curves[i] as ICurve2D; ArrayList intersectionPoints = new ArrayList(); // double ICollection closecurves = qt.GetObjectsCloseTo(cv1); foreach (ICurve2D cv2 in closecurves) { if (cv2 != cv1) { //if ((cv1 is Line2D && (cv1 as Line2D).Length > 10 && (cv1 as Line2D).Length < 15) || // (cv2 is Line2D && (cv2 as Line2D).Length > 10 && (cv2 as Line2D).Length < 15)) //{ //} GeoPoint2DWithParameter[] isp = cv1.Intersect(cv2); for (int k = 0; k < isp.Length; ++k) { if (cv2.IsParameterOnCurve(isp[k].par2) && 0.0 < isp[k].par1 && isp[k].par1 < 1.0) { intersectionPoints.Add(isp[k].par1); } } } } if (intersectionPoints.Count == 0) { snippet.Add(cv1); } else { intersectionPoints.Add(0.0); intersectionPoints.Add(1.0); // damit sinds mindesten 3 double[] pps = (double[])intersectionPoints.ToArray(typeof(double)); Array.Sort(pps); for (int ii = 1; ii < pps.Length; ++ii) { if (pps[ii - 1] < pps[ii]) { ICurve2D cv3 = cv1.Trim(pps[ii - 1], pps[ii]); if (cv3 != null) { #if DEBUG GeoPoint2D dbg1 = cv1.PointAt(pps[ii - 1]); GeoPoint2D dbg2 = cv1.PointAt(pps[ii]); GeoPoint2D dbg3 = cv3.StartPoint; GeoPoint2D dbg4 = cv3.EndPoint; double d1 = dbg1 | dbg3; double d2 = dbg2 | dbg4; #endif cv3.UserData.Add("3d", cv1.UserData.GetData("3d")); snippet.Add(cv3); } } } } } // snippet ist jetzt die Liste aller Schnipsel return(new CurveGraph((ICurve2D[])snippet.ToArray(typeof(ICurve2D)), maxGap)); }
private void InsertCurve(int ind) { ICurve toInsert = closedBorder.Curve(ind); Face fromFace = vertexToFace[ind]; int ind1 = ind + 1; if (ind1 >= vertexToFace.Length) { ind1 = 0; } Face toFace = vertexToFace[ind1]; ICurve2D c2d = fromFace.Surface.GetProjectedCurve(toInsert, precision); double[] clp = fromFace.Area.Clip(c2d, true); if (clp == null || clp.Length < 2) { throw new SplitShellWithCurvesException("curve outside of face"); } if (clp.Length == 2 && clp[0] == 0.0 && clp[1] == 1.0) { if (fromFace == toFace) { List <ICurve2D> lc2d; if (!all2DCurves.TryGetValue(fromFace, out lc2d)) { lc2d = new List <ICurve2D>(); all2DCurves[fromFace] = lc2d; } lc2d.Add(c2d); } else { throw new SplitShellWithCurvesException("endpoint on wrong face"); } } else { // die Kurve geht in ein anderes Face Face face1 = fromFace; ICurve2D curveOnFace1 = c2d; double startOnFace1 = clp[0]; // sollte immer 0.0 sein, oder? double endOnFace1 = clp[1]; Face face2 = null; ICurve2D curveOnFace2 = null; double startOnFace2 = 0.0, endOnFace2 = 0.0; bool success; do { success = false; GeoPoint onEdge = face1.Surface.PointAt(curveOnFace1.PointAt(endOnFace1)); Edge[] close = FindCloseEdges(face1, onEdge); if (close.Length == 0) { throw new SplitShellWithCurvesException("no connecting edge found"); } for (int i = 0; i < close.Length; i++) { face2 = close[i].OtherFace(face1); success = SplitAndInsertCurve(toInsert, face1, face2, curveOnFace1, startOnFace1, out curveOnFace2, out startOnFace2, out endOnFace2); if (success) { face1 = face2; startOnFace1 = startOnFace2; endOnFace1 = endOnFace2; curveOnFace1 = curveOnFace2; break; } } if (success && face1 == toFace && endOnFace2 == 1.0) { ICurve2D clipped2 = curveOnFace2.Trim(startOnFace2, endOnFace2); List <ICurve2D> lc2d; if (!all2DCurves.TryGetValue(face2, out lc2d)) { lc2d = new List <ICurve2D>(); all2DCurves[face2] = lc2d; } lc2d.Add(clipped2); break; } } while (success); } }
private bool SplitAndInsertCurve(ICurve toInsert, Face face1, Face face2, ICurve2D curveOnFace1, double startOnFace1, out ICurve2D curveOnFace2, out double startOnFace2, out double endOnFace2) { curveOnFace2 = null; startOnFace2 = -1.0; endOnFace2 = -1.0; double[] clp1 = face1.Area.Clip(curveOnFace1, true); double endOnFace1 = 0.0; for (int i = 0; i < clp1.Length; i += 2) { if (clp1[i] == startOnFace1) { endOnFace1 = clp1[i + 1]; } } if (endOnFace1 == 0.0) { return(false); // sollte nicht vorkommen } GeoPoint leaveFace1 = face1.Surface.PointAt(curveOnFace1.PointAt(endOnFace1)); Edge[] close = FindCloseEdges(face1, leaveFace1); Edge commonEdge = null; for (int i = 0; i < close.Length; i++) { if (close[i].OtherFace(face1) == face2) { commonEdge = close[i]; break; } } if (commonEdge == null) { return(false); } curveOnFace2 = face2.Surface.GetProjectedCurve(toInsert, precision); AdjustPeriodic(face2, curveOnFace2, leaveFace1); double[] clp2 = face2.Area.Clip(curveOnFace2, true); for (int i = 0; i < clp2.Length; i += 2) { GeoPoint enterFace2 = face2.Surface.PointAt(curveOnFace2.PointAt(clp2[i])); if (commonEdge.Curve3D.DistanceTo(enterFace2) < precision) { // a good common edge which both 2d curves connect double pos = (commonEdge.Curve3D.PositionOf(enterFace2) + commonEdge.Curve3D.PositionOf(leaveFace1)) / 2.0; List <double> edgePositions; if (!splitedEdges.TryGetValue(commonEdge, out edgePositions)) { splitedEdges[commonEdge] = new List <double>(); edgePositions = splitedEdges[commonEdge]; } edgePositions.Add(pos); ICurve2D clipped1 = curveOnFace1.Trim(startOnFace1, endOnFace1); GeoPoint2D uv1 = face1.Surface.PositionOf(commonEdge.Curve3D.PointAt(pos)); clipped1.EndPoint = uv1; List <ICurve2D> lc2d; if (!all2DCurves.TryGetValue(face1, out lc2d)) { lc2d = new List <ICurve2D>(); all2DCurves[face1] = lc2d; } lc2d.Add(clipped1); startOnFace2 = clp2[i]; endOnFace2 = clp2[i + 1]; return(true); } } 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); }