public override GeoPoint2D[] GetLineIntersection(GeoPoint startPoint, GeoVector direction) { if (firstCurve is Line && secondCurve is Line) { if (Precision.SameDirection(firstCurve.StartDirection, secondCurve.StartDirection, false)) { // a simple plane PlaneSurface pls = new PlaneSurface(firstCurve.StartPoint, firstCurve.EndPoint, secondCurve.StartPoint); return(pls.GetLineIntersection(startPoint, direction)); } else { // a standard hyperbolic paraboloid with the form z = x*y as the affine transformation of this paraboloid if (toUnit.IsNull) { lock (this) { if (toUnit.IsNull) { toUnit = ModOp.Fit(new GeoPoint[] { firstCurve.StartPoint, firstCurve.EndPoint, secondCurve.StartPoint, secondCurve.EndPoint }, new GeoPoint[] { new GeoPoint(0, 0, 0), new GeoPoint(1, 0, 0), new GeoPoint(0, 1, 0), new GeoPoint(1, 1, 1) }, true); } } } // ModOp fromUnit = toUnit.GetInverse(); // Polynom hyperbolic = new Polynom(1, "xy", -1, "z"); //Polynom hyperbolic = new Polynom(2, 3); //hyperbolic.Set(1.0, new int[] { 1, 1, 0 }); //hyperbolic.Set(-1.0, new int[] { 0, 0, 1 }); // this is x*y-z==0 //ImplicitPSurface implicitHyperbolic = new ImplicitPSurface(hyperbolic); ExplicitPCurve3D explicitCurve = ExplicitPCurve3D.MakeLine(toUnit * startPoint, toUnit * direction); GeoPoint[] hypLineIsp = implicitUnitHyperbolic.Intersect(explicitCurve, out double[] uc); List <GeoPoint2D> luv = new List <GeoPoint2D>(); for (int i = 0; i < hypLineIsp.Length; i++) { double u = uc[i]; //= explicitCurve.PositionOf(hypLineIsp[i], out double dist); if (u >= -1e-6 && u <= 1 + 1e-6) { GeoPoint2D uv = new GeoPoint2D(hypLineIsp[i].x, hypLineIsp[i].y); if (BoundingRect.UnitBoundingRect.ContainsEps(uv, -0.001)) { luv.Add(uv); } } } #if DEBUG ++hitcount; if (luv.Count == 0) { } #endif return(luv.ToArray()); } } return(base.GetLineIntersection(startPoint, direction)); }
/// <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)); }