private bool Recalc() { if (theBaseCurve == null) { return(false); } Plane pln; if (theBaseCurve.GetPlanarState() == PlanarState.Planar) { pln = theBaseCurve.GetPlane(); } else { pln = base.ActiveDrawingPlane; } ICurve2D c2d = theBaseCurve.GetProjectedCurve(pln); ICurve2D app = c2d.Approximate(false, Frame.GetDoubleSetting("Approximate.Precision", 0.01)); Border bdr = new Border(app); Border[] res = bdr.GetParallel(theDistance, true, 0.0, theMinAngle); Block blk = Block.Construct(); for (int i = 0; i < res.Length; ++i) { IGeoObject go = res[i].AsPath().MakeGeoObject(pln); go.CopyAttributes(theBaseCurve as IGeoObject); (go as IColorDef).ColorDef = (theBaseCurve as IColorDef).ColorDef; blk.Add(go); } base.ActiveObject = blk; return(true); }
/// <summary> /// Calculates the intersection points of the two curves. /// </summary> /// <param name="curve1">First curve</param> /// <param name="curve2">Second curve</param> /// <param name="par1">Resulting parameters for the first curve</param> /// <param name="par2">Resulting parameters for the second curve</param> /// <param name="intersection">Three dimensional intersection points</param> /// <returns>Number of intersection points</returns> public static int Intersect(ICurve curve1, ICurve curve2, out double[] par1, out double[] par2, out GeoPoint[] intersection) { // wenn es eine gemeinsame Ebene gibt, dann in dieser Ebene schneiden if (GetCommonPlane(curve1, curve2, out Plane pln)) { ICurve2D c2d1 = curve1.GetProjectedCurve(pln); ICurve2D c2d2 = curve2.GetProjectedCurve(pln); GeoPoint2DWithParameter[] ips = c2d1.Intersect(c2d2); // geht die Parametrierung der projizierten Kurven analog zu den Originalen? // da wir ja nur in die Ebene Projizieren, in der sich duie Kurven ohnehin befinden, müsste das stimmen // das muss aber noch getestet werden par1 = new double[ips.Length]; par2 = new double[ips.Length]; intersection = new GeoPoint[ips.Length]; for (int i = 0; i < ips.Length; ++i) { par1[i] = ips[i].par1; par2[i] = ips[i].par2; intersection[i] = pln.ToGlobal(ips[i].p); } return(ips.Length); } // eine Linie und eine nichtebene Kurve noch gesondert prüfen if (curve1.GetPlanarState() == PlanarState.Planar) { double[] ips = curve2.GetPlaneIntersection(curve1.GetPlane()); List <double> lpar1 = new List <double>(); List <double> lpar2 = new List <double>(); List <GeoPoint> lip = new List <GeoPoint>(); for (int i = 0; i < ips.Length; ++i) { GeoPoint p = curve2.PointAt(ips[i]); double ppar1 = curve1.PositionOf(p); GeoPoint p1 = curve1.PointAt(ppar1); if (Precision.IsEqual(p, p1)) { lpar1.Add(ppar1); lpar2.Add(ips[i]); lip.Add(new GeoPoint(p, p1)); } } par1 = lpar1.ToArray(); par2 = lpar2.ToArray(); intersection = lip.ToArray(); return(par1.Length); } if (curve2.GetPlanarState() == PlanarState.Planar) { return(Intersect(curve2, curve1, out par2, out par1, out intersection)); } // Fehlt noch die Abfrage nach einer Linie, denn die ist ja nicht planar // allgemeiner Fall: zwei nicht ebene Kurven TetraederHull th1 = new TetraederHull(curve1); TetraederHull th2 = new TetraederHull(curve2); return(th1.Intersect(th2, out par1, out par2, out intersection)); }
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)); }
/// <summary> /// Determines the commomn plane of a point and a curve. Returns the common plane in the /// parameter and true if there is such a plane. Returns false, if the point lies not /// in the plane. <seealso cref="Precision"/> /// </summary> /// <param name="p">The point</param> /// <param name="c2">The curve</param> /// <param name="CommonPlane">The common plane</param> /// <returns>true, if there is a common plane, else false</returns> public static bool GetCommonPlane(GeoPoint p, ICurve c2, out Plane CommonPlane) { // kommt erstaunlicherweise ohne Zugriff auf die konkreten Kurven aus PlanarState ps2 = c2.GetPlanarState(); if (ps2 == PlanarState.NonPlanar) { CommonPlane = new Plane(Plane.StandardPlane.XYPlane, 0.0); // braucht leider ein Ergebnis return(false); } if (ps2 == PlanarState.Planar) { Plane p2 = c2.GetPlane(); if (Precision.IsPointOnPlane(p, p2)) { CommonPlane = p2; return(true); } } else { // UnderDetermined, also Linie oder so GeoVector v1 = p - c2.StartPoint; GeoVector v2 = c2.StartDirection; if (!Precision.SameDirection(v1, v2, false) && !Precision.IsNullVector(v1)) { Plane pl = new Plane(p, v1, v2); if (c2.IsInPlane(pl)) { CommonPlane = pl; return(true); } } } CommonPlane = new Plane(Plane.StandardPlane.XYPlane, 0.0); // braucht leider ein Ergebnis return(false); }
private bool SetFacesAndOffset(bool testOnly, object distanceFromHere, object distanceToHere) { if (distanceFromHere == null || distanceToHere == null) { return(true); // because this means, you can use the object } List <Face> fromHere = new List <Face>(); List <Face> toHere = new List <Face>(); Vertex vtx1 = distanceFromHere as Vertex; Vertex vtx2 = distanceToHere as Vertex; Edge edg1 = distanceFromHere as Edge; Edge edg2 = distanceToHere as Edge; Face fc1 = distanceFromHere as Face; Face fc2 = distanceToHere as Face; ICurve crv1 = distanceFromHere as ICurve; ICurve crv2 = distanceToHere as ICurve; originalOffset = GeoVector.NullVector; if (distanceToHere is GeoObject.Point pnt && vtx2 == null) { vtx2 = new Vertex(pnt.Location); } if (vtx1 != null && vtx2 != null) { originalOffset = vtx1.Position - vtx2.Position; } else if ((vtx1 != null && edg2 != null) || (vtx2 != null && edg1 != null)) { Vertex vtx; Edge edg; List <Face> lv, le; if (vtx1 != null) { vtx = vtx1; edg = edg2; lv = fromHere; le = toHere; } else { vtx = vtx2; edg = edg1; lv = toHere; le = fromHere; } double cpos = edg.Curve3D.PositionOf(vtx.Position); originalOffset = vtx.Position - edg.Curve3D.PointAt(cpos); if (vtx1 == null) { originalOffset.Reverse(); } } else if ((vtx1 != null && fc2 != null) || (vtx2 != null && fc1 != null)) { Vertex vtx; Face fc; List <Face> lv, le; if (vtx1 != null) { vtx = vtx1; fc = fc2; lv = fromHere; le = toHere; } else { vtx = vtx2; fc = fc1; lv = toHere; le = fromHere; } GeoPoint2D[] pfs = fc.Surface.PerpendicularFoot(vtx.Position); for (int i = 0; i < pfs.Length; i++) { if (fc.Contains(ref pfs[i], true)) { originalOffset = vtx.Position - fc.Surface.PointAt(pfs[i]); if (vtx1 == null) { originalOffset.Reverse(); } break; } } } else if ((edg1 != null || crv1 != null) && (edg2 != null || crv2 != null)) { double pos1 = 0.5, pos2 = 0.5; if (crv1 == null) { crv1 = edg1.Curve3D; } if (crv2 == null) { crv2 = edg2.Curve3D; } if (crv1 is Line l1 && crv2 is Line l2) { if (Precision.SameDirection(l1.StartDirection, l2.StartDirection, false)) { double u = crv1.PositionOf(crv2.StartPoint); originalOffset = crv2.StartPoint - crv1.PointAt(u); offsetStartPoint = crv1.PointAt(u); } else { Geometry.DistLL(l1.StartPoint, l1.StartDirection, l2.StartPoint, l2.StartDirection, out double par1, out double par2); originalOffset = l2.PointAt(par2) - l1.PointAt(par1); offsetStartPoint = l1.PointAt(par1); } } else if (crv1.GetPlanarState() == PlanarState.Planar && crv2.GetPlanarState() == PlanarState.Planar) { // probably parallel planes, so newton could find anything GeoPoint foot = crv1.GetPlane().ToLocal(crv2.StartPoint); originalOffset = crv2.StartPoint - foot; offsetStartPoint = foot; } else if (Curves.NewtonMinDist(crv1, ref pos1, crv2, ref pos2)) { originalOffset = crv2.PointAt(pos2) - crv1.PointAt(pos1); offsetStartPoint = crv1.PointAt(pos1); } // else no distance between two curves, maybe check some more cases, which make a usable offset }
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); }
/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.Intersect (ICurve, BoundingRect, out GeoPoint[], out GeoPoint2D[], out double[])"/> /// </summary> /// <param name="curve"></param> /// <param name="uvExtent"></param> /// <param name="ips"></param> /// <param name="uvOnFaces"></param> /// <param name="uOnCurve3Ds"></param> public override void Intersect(ICurve curve, BoundingRect uvExtent, out GeoPoint[] ips, out GeoPoint2D[] uvOnFaces, out double[] uOnCurve3Ds) { if (curve is Line) { GeoPoint ip; if (Plane.Intersect(curve.StartPoint, curve.StartDirection, out ip)) { ips = new GeoPoint[] { ip }; uvOnFaces = new GeoPoint2D[] { PositionOf(ip) }; uOnCurve3Ds = new double[] { curve.PositionOf(ip) }; } else { ips = new GeoPoint[0]; uvOnFaces = new GeoPoint2D[0]; uOnCurve3Ds = new double[0]; } #if DEBUG //GeoPoint[] ipsdbg; //GeoPoint2D[] uvOnFacesdbg; //double[] uOnCurve3Dsdbg; //base.Intersect(curve, out ipsdbg, out uvOnFacesdbg, out uOnCurve3Dsdbg); #endif return; } //else if (curve is IExplicitPCurve3D) //{ // ExplicitPCurve3D epc3d = (curve as IExplicitPCurve3D).GetExplicitPCurve3D(); // double [] res = epc3d.GetPlaneIntersection(Location, DirectionX, DirectionY); // for (int i = 0; i < res.Length; i++) // { // double d = Plane.Distance(epc3d.PointAt(res[i])); // if (i>0) d = Plane.Distance(epc3d.PointAt((res[i]+res[i-1])/2.0)); // } // double dd = Plane.Distance(epc3d.PointAt(epc3d.knots[epc3d.knots.Length - 1])); // for (int i = 0; i < res.Length; i++) // { // res[i] = (res[i] - epc3d.knots[0]) / (epc3d.knots[epc3d.knots.Length - 1] - epc3d.knots[0]); // } //} else { if (curve.GetPlanarState() == PlanarState.Planar) { GeoPoint loc; GeoVector dir; Plane pln = curve.GetPlane(); if (Plane.Intersect(curve.GetPlane(), out loc, out dir)) { ICurve2D c2d = curve.GetProjectedCurve(pln); BoundingRect ext = c2d.GetExtent(); ext.Inflate(ext.Height + ext.Width); // sonst entstehen null-Linien ICurve2D ll = new Line2D(pln.Project(loc), pln.Project(dir), ext); #if DEBUG DebuggerContainer dc = new DebuggerContainer(); dc.Add(c2d); dc.Add(ll); #endif GeoPoint2DWithParameter[] gpp = ll.Intersect(c2d); ips = new GeoPoint[gpp.Length]; uvOnFaces = new GeoPoint2D[gpp.Length]; uOnCurve3Ds = new double[gpp.Length]; for (int i = 0; i < gpp.Length; ++i) { ips[i] = pln.ToGlobal(gpp[i].p); uvOnFaces[i] = PositionOf(ips[i]); uOnCurve3Ds[i] = curve.PositionOf(ips[i]); } } else { ips = new GeoPoint[0]; uvOnFaces = new GeoPoint2D[0]; uOnCurve3Ds = new double[0]; } #if DEBUG //GeoPoint[] ipsdbg; //GeoPoint2D[] uvOnFacesdbg; //double[] uOnCurve3Dsdbg; //base.Intersect(curve, out ipsdbg, out uvOnFacesdbg, out uOnCurve3Dsdbg); #endif return; } } TetraederHull th = new TetraederHull(curve); // alle Kurven müssten eine gemeinsame basis habe, auf die man sich hier beziehen kann // damit die TetraederHull nicht mehrfach berechnet werden muss th.PlaneIntersection(this, out ips, out uvOnFaces, out uOnCurve3Ds); // base.Intersect(curve, out ips, out uvOnFaces, out uOnCurve3Ds); }
public HelicalSurface(ICurve basisCurve, GeoPoint axisLocation, GeoVector axisDirection, double pitch, double curveStartParameter, double curveEndParameter, GeoPoint?axisRefPoint = null) : base() { this.curveEndParameter = curveEndParameter; this.curveStartParameter = curveStartParameter; this.pitch = pitch; // curveStartParameter und curveEndParameter haben folgenden Sinn: // der Aufrufer werwartet ein bestimmtes u/v System. // in u ist es die Kreisbewegung, in v ist es die Kurve (andersrum als bei SurfaceOfLinearExtrusion) // curveStartParameter und curveEndParameter definieren die Lage von v, die Lage von u ist durch die Ebene // bestimmt // finden der Hauptebene, in der alles stattfindet. Die ist gegeben durch die Achse und die Kurve Plane pln; if (axisRefPoint.HasValue) { GeoPoint cnt = Geometry.DropPL(axisRefPoint.Value, axisLocation, axisDirection); pln = new Plane(axisLocation, axisRefPoint.Value - cnt, axisDirection); } else { double ds = Geometry.DistPL(basisCurve.StartPoint, axisLocation, axisDirection); double de = Geometry.DistPL(basisCurve.EndPoint, axisLocation, axisDirection); if (ds > de && ds > Precision.eps) { GeoPoint cnt = Geometry.DropPL(basisCurve.StartPoint, axisLocation, axisDirection); pln = new Plane(axisLocation, basisCurve.StartPoint - cnt, axisDirection); } else if (de >= ds && de > Precision.eps) { GeoPoint cnt = Geometry.DropPL(basisCurve.EndPoint, axisLocation, axisDirection); pln = new Plane(axisLocation, basisCurve.EndPoint - cnt, axisDirection); } else if (basisCurve.GetPlanarState() == PlanarState.Planar) { Plane ppln = basisCurve.GetPlane(); GeoVector dirx = ppln.Normal ^ axisDirection; // richtig rum? pln = new Plane(axisLocation, dirx, axisDirection); } else { // es könnte sein, dass die ganze Fläche singulär ist // dann kann man nichts machen, sollte aber nicht vorkommen throw new SurfaceOfRevolutionException("Surface is invalid"); } } // pln hat jetzt den Ursprung bei axisLocation, die y-Achse ist axisDirection und die x-Achse durch die // die Orientierung scheint mir noch fraglich, wierum wird gedreht, wierum läuft u // Kurve gegeben basisCurve2D = basisCurve.GetProjectedCurve(pln); // ACHTUNG "Parameterproblem": durch die Projektion der Kurve verschiebt sich bei Kreisen der Parameterraum // da 2D Kreise bzw. Bögen keine Achse haben und sich immer auf die X-Achse beziehen if (basisCurve2D is Arc2D) { curveParameterOffset = (basisCurve2D as Arc2D).StartParameter - this.curveStartParameter; } else if (basisCurve2D is BSpline2D) { // beim BSpline fängt der Parameter im 3D bei knots[0] an, welches gleich this.curveStartParameter ist // curveParameterOffset = this.curveStartParameter; // wenn man einen geschlossenen Spline um eine Achse rotieren lässt // dann entsteht mit obiger Zeile ein Problem, mit dieser jedoch nicht: curveParameterOffset = (basisCurve2D as BSpline2D).Knots[0]; } else { curveParameterOffset = 0.0; } toSurface = ModOp.Fit(new GeoPoint[] { GeoPoint.Origin, GeoPoint.Origin + GeoVector.XAxis, GeoPoint.Origin + GeoVector.YAxis }, new GeoPoint[] { axisLocation, axisLocation + pln.DirectionX, axisLocation + pln.DirectionY }, false); fromSurface = toSurface.GetInverse(); }
/// <summary> /// Determines the common plane of the two curves. If there is a common plane, /// the Parameter CommonPlane gets the result ant the function returns true. Otherwise /// the function returns false. /// </summary> /// <param name="c1">first curve</param> /// <param name="c2">second curve</param> /// <param name="CommonPlane">the resulting common plane</param> /// <returns></returns> public static bool GetCommonPlane(ICurve c1, ICurve c2, out Plane CommonPlane) { // kommt erstaunlicherweise ohne Zugriff auf die konkreten Kurven aus PlanarState ps1 = c1.GetPlanarState(); PlanarState ps2 = c2.GetPlanarState(); if (ps1 == PlanarState.NonPlanar || ps2 == PlanarState.NonPlanar) { CommonPlane = new Plane(Plane.StandardPlane.XYPlane, 0.0); // braucht leider ein Ergebnis return(false); } if (ps1 == PlanarState.Planar) { if (ps2 == PlanarState.Planar) { Plane p1 = c1.GetPlane(); Plane p2 = c2.GetPlane(); if (Precision.IsEqual(p1, p2)) { CommonPlane = p1; return(true); } } else { // ps2 ist UnderDetermined, also einen Punkt mit p1 testen Plane p1 = c1.GetPlane(); if (c2.IsInPlane(p1)) { CommonPlane = p1; return(true); } } } else { // ps1 ist UnderDetermined if (ps2 == PlanarState.Planar) { Plane p2 = c2.GetPlane(); if (c1.IsInPlane(p2)) { CommonPlane = p2; return(true); } } else { // ps1 und ps2 UnderDetermined. Das können nur zwei Linien sein (oder // polylines mit einem Segment oder ähnliches) GeoVector v1 = c1.StartDirection; GeoVector v2 = c2.StartDirection; if (Precision.SameDirection(v1, v2, false)) { // d.h. parallel GeoVector v3 = c2.StartPoint - c1.StartPoint; if (!Precision.SameDirection(v1, v3, false)) { try { CommonPlane = new Plane(c1.StartPoint, v1, v3); return(true); } catch (PlaneException) { CommonPlane = new Plane(Plane.StandardPlane.XYPlane, 0.0); // braucht leider ein Ergebnis return(false); } } // else: colinear, geht also nicht } else { try { Plane p = new Plane(c1.StartPoint, v1, v2); if (c2.IsInPlane(p)) { CommonPlane = p; return(true); } GeoPoint[] pnts = new GeoPoint[4]; pnts[0] = c1.StartPoint; pnts[1] = c1.EndPoint; pnts[2] = c2.StartPoint; pnts[3] = c2.EndPoint; p = Plane.FromPoints(pnts, out double maxDist, out bool isLinear); if (maxDist < Precision.eps) { CommonPlane = p; return(true); } } catch (PlaneException) { CommonPlane = new Plane(Plane.StandardPlane.XYPlane, 0.0); // braucht leider ein Ergebnis return(false); } } } } CommonPlane = new Plane(Plane.StandardPlane.XYPlane, 0.0); // braucht leider ein Ergebnis return(false); }
private void selectDir() { GeoVector dirCurveMod = new GeoVector(0.0, 1.0, 1.0); switch (dirPointSelect) { // Startpunkt|Automatik|Endpunkt|Mittelpunkt|freier Punkt default: dirCurveMod = dirCurve.StartDirection; break; case 0: // Startpunkt dirCurveMod = dirCurve.StartDirection; break; case 1: // Automatik if (dirCurve.PositionOf(objectPoint) > 0.66) { dirCurveMod = dirCurve.EndDirection; } else if (dirCurve.PositionOf(objectPoint) > 0.33) { dirCurveMod = dirCurve.DirectionAt(0.5); } else { dirCurveMod = dirCurve.StartDirection; } break; case 2: // Endpunkt dirCurveMod = dirCurve.EndDirection; break; case 3: // Mittelpunkt dirCurveMod = dirCurve.DirectionAt(0.5); break; case 4: // freier Punkt dirCurveMod = dirCurve.DirectionAt(dirCurve.PositionOf(objectPoint)); break; } Plane pl; if (dirCurve.GetPlanarState() == PlanarState.Planar) { pl = dirCurve.GetPlane(); } else { pl = base.ActiveDrawingPlane; } for (int i = 0; i < (dirOffsetSelect); ++i) { dirCurveMod = dirCurveMod ^ pl.Normal; } using (Frame.Project.Undo.ContextFrame(this)) { if (vectorProperty != null) { vectorProperty.SetGeoVector(dirCurveMod); } } actualVector = dirCurveMod; }
/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.GetPlaneIntersection (PlaneSurface, double, double, double, double, double)"/> /// </summary> /// <param name="pl"></param> /// <param name="umin"></param> /// <param name="umax"></param> /// <param name="vmin"></param> /// <param name="vmax"></param> /// <param name="precision"></param> /// <returns></returns> public override IDualSurfaceCurve[] GetPlaneIntersection(PlaneSurface pl, double umin, double umax, double vmin, double vmax, double precision) { if (firstCurve is Line && secondCurve is Line) { if (Precision.IsPerpendicular(firstCurve.StartDirection, pl.Normal, false) && Precision.IsPerpendicular(secondCurve.StartDirection, pl.Normal, false)) { // eine Ebene, die zu beiden Linien parallel ist GeoPoint sp1, ep1, sp2, ep2; sp1 = firstCurve.PointAt(umin); ep1 = secondCurve.PointAt(umin); sp2 = firstCurve.PointAt(umax); ep2 = secondCurve.PointAt(umax); GeoPoint2D[] ip1 = pl.GetLineIntersection(sp1, ep1 - sp1); GeoPoint2D[] ip2 = pl.GetLineIntersection(sp2, ep2 - sp2); if (ip1.Length == 1 && ip2.Length == 1) { GeoPoint sp = pl.PointAt(ip1[0]); GeoPoint ep = pl.PointAt(ip2[0]); double v = Geometry.LinePar(sp1, ep1, sp); Line line = Line.Construct(); line.SetTwoPoints(sp, ep); DualSurfaceCurve dsc = new DualSurfaceCurve(line, this, new Line2D(new GeoPoint2D(umin, v), new GeoPoint2D(umax, v)), pl, new Line2D(ip1[0], ip2[0])); return(new IDualSurfaceCurve[] { dsc }); } } } if (firstCurve is Ellipse && secondCurve is Ellipse) { Ellipse e1 = firstCurve as Ellipse; Ellipse e2 = secondCurve as Ellipse; if (Precision.SameDirection(pl.Normal, e1.Plane.Normal, false) && Precision.SameDirection(pl.Normal, e2.Plane.Normal, false)) { if (e1.IsCircle && e2.IsCircle) { GeoPoint sp1, ep1, sp2, ep2, spm, epm; sp1 = firstCurve.PointAt(umin); ep1 = secondCurve.PointAt(umin); sp2 = firstCurve.PointAt(umax); ep2 = secondCurve.PointAt(umax); spm = firstCurve.PointAt((umin + umax) / 2.0); epm = secondCurve.PointAt((umin + umax) / 2.0); GeoPoint2D[] ip1 = pl.GetLineIntersection(sp1, ep1 - sp1); GeoPoint2D[] ip2 = pl.GetLineIntersection(sp2, ep2 - sp2); GeoPoint2D[] ipm = pl.GetLineIntersection(spm, epm - spm); if (ip1.Length == 1 && ip2.Length == 1 && ipm.Length == 1) { Ellipse e3 = Ellipse.Construct(); e3.SetArc3Points(pl.PointAt(ip1[0]), pl.PointAt(ipm[0]), pl.PointAt(ip2[0]), pl.Plane); double v = Geometry.LinePar(sp1, ep1, pl.PointAt(ip1[0])); DualSurfaceCurve dsc = new DualSurfaceCurve(e3, this, new Line2D(new GeoPoint2D(umin, v), new GeoPoint2D(umax, v)), pl, e3.GetProjectedCurve(pl.Plane)); return(new IDualSurfaceCurve[] { dsc }); } } } } PlanarState ps1 = firstCurve.GetPlanarState(); PlanarState ps2 = secondCurve.GetPlanarState(); if ((ps1 == PlanarState.UnderDetermined || ps1 == PlanarState.Planar) && (ps2 == PlanarState.UnderDetermined || ps2 == PlanarState.Planar)) { if (Precision.IsPerpendicular(firstCurve.StartDirection, pl.Normal, false) && Precision.IsPerpendicular(secondCurve.StartDirection, pl.Normal, false)) { // beide Kurven sind eben und parallel zur Schnittebene, wir haben also ein festes v und somit eine Zwischenkurve GeoPoint ip = pl.Plane.Intersect(firstCurve.StartPoint, secondCurve.StartPoint - firstCurve.StartPoint); double v = Geometry.LinePar(firstCurve.StartPoint, secondCurve.StartPoint, ip); ICurve cv = FixedV(v, umin, umax); DualSurfaceCurve dsc = new DualSurfaceCurve(cv, this, new Line2D(new GeoPoint2D(umin, v), new GeoPoint2D(umax, v)), pl, cv.GetProjectedCurve(pl.Plane)); return(new IDualSurfaceCurve[] { dsc }); } } return(base.GetPlaneIntersection(pl, umin, umax, vmin, vmax, precision)); }