/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.UDirection (GeoPoint2D)"/> /// </summary> /// <param name="uv"></param> /// <returns></returns> public override GeoVector UDirection(GeoPoint2D uv) { GeoVector v1 = firstCurve.DirectionAt(uv.x); GeoVector v2 = secondCurve.DirectionAt(uv.x); return((1.0 - uv.y) * v1 + uv.y * v2); }
/// <summary> /// Overrides <see cref="CADability.GeoObject.ISurfaceImpl.UDirection (GeoPoint2D)"/> /// </summary> /// <param name="uv"></param> /// <returns></returns> public override GeoVector UDirection(GeoPoint2D uv) { double pos = (uv.x - curveStartParameter) / (curveEndParameter - curveStartParameter); // ausgehend davon, dass DirectionAt den Vektor gemäß änderung um 1 liefert // das ist oft nicht der Fall. Man muss also PointAtParam und DirectionAtParam implementieren return((curveEndParameter - curveStartParameter) * basisCurve.DirectionAt(pos)); }
public override GeoVector DirectionAt(double Position) { double p = startParam + (endParam - startParam) * Position; GeoVector d1 = firstCurve.DirectionAt(p); GeoVector d2 = secondCurve.DirectionAt(p); return((endParam - startParam) * ((1.0 - v) * d1 + v * d2)); }
internal static bool NewtonMinDist(ICurve curve1, ref double par1, ICurve curve2, ref double par2) { // find the points on both curves where the connecting line of the two curves is perpendicular on both int numoutside = 0; while (numoutside < 3) { GeoPoint s1 = curve1.PointAt(par1); GeoVector d1 = curve1.DirectionAt(par1); GeoPoint s2 = curve2.PointAt(par2); GeoVector d2 = curve2.DirectionAt(par2); double d = Geometry.DistLL(s1, d1, s2, d2, out double pp1, out double pp2); par1 += pp1; par2 += pp2; if (curve1.IsClosed) { if (par1 < 0) { par1 += 1; } if (par1 > 1) { par1 -= 1; } } if (curve2.IsClosed) { if (par2 < 0) { par2 += 1; } if (par2 > 1) { par2 -= 1; } } if (par1 < -1e-6 || par1 > 1 + 1e-6 || par2 < -1e-6 || par2 > 1 + 1e-6) { ++numoutside; } if (Math.Abs(pp1) < 1e-6 && Math.Abs(pp2) < 1e-6) { return(true); } } return(false); }
/// <summary> /// Returns true if curve1 and curve2 are overlapping curves. The overlapping intervalls for both curves are /// returned in <paramref name="from1"/>, <paramref name="to1"/>, <paramref name="from2"/> and <paramref name="to2"/>. /// </summary> /// <param name="curve1">First curve</param> /// <param name="curve2">Second curve</param> /// <param name="precision">Required precision</param> /// <param name="from1">Starting parameter for first curve</param> /// <param name="to1">Ending parameter for first curve</param> /// <param name="from2">Starting parameter for second curve</param> /// <param name="to2">Ending parameter for second curve</param> /// <returns></returns> public static bool Overlapping(ICurve curve1, ICurve curve2, double precision, out double from1, out double to1, out double from2, out double to2) { from1 = to1 = from2 = to2 = 0.0; // für den fals Fall List <double> c1 = new List <double>(); List <double> c2 = new List <double>(); double u = curve1.PositionOf(curve2.StartPoint); GeoPoint p = curve1.PointAt(u); if (u >= 0.0 && u <= 1.0 && (p | curve2.StartPoint) < precision) { c1.Add(u); c2.Add(0.0); } u = curve1.PositionOf(curve2.EndPoint); p = curve1.PointAt(u); if (u >= 0.0 && u <= 1.0 && (p | curve2.EndPoint) < precision) { c1.Add(u); c2.Add(1.0); } u = curve2.PositionOf(curve1.StartPoint); p = curve2.PointAt(u); if (u >= 0.0 && u <= 1.0 && (p | curve1.StartPoint) < precision) { c2.Add(u); c1.Add(0.0); } u = curve2.PositionOf(curve1.EndPoint); p = curve2.PointAt(u); if (u >= 0.0 && u <= 1.0 && (p | curve1.EndPoint) < precision) { c2.Add(u); c1.Add(1.0); } if (c1.Count < 2) { return(false); } if (c1.Count > 2) { // eine Kurve liegt ganz in der anderen und Start oder Endpunkt sind gleich (oder identische Kurven) if (c1.Count == 4) { // nichts tun, die ersten beiden sind schon OK } else { // also 3 Punkte, einer davon ist doppelt if (c1[1] == 0.0 && c1[2] == 1.0) { // die beiden letzten Abfragen haben gegriffen, den 1. Punkt wegwerfen c1.RemoveAt(0); c2.RemoveAt(0); } // ansonsten haben die beiden ersten Abfragen geegriffen, der 3. Punkt wird nicht verwednet } } // Dir Richtungen müssen gleich sein, jedoch ist das schwer mit precision in Einklang zu bringen // Hier jetzt die notwendigen Zwischenpunkte betrachten // bool intermediatePointChecked = false; double[] sp = curve1.GetSavePositions(); double umin = Math.Min(c1[0], c1[1]); double umax = Math.Max(c1[0], c1[1]); for (int i = 0; i < sp.Length; i++) { if (sp[i] > umin && sp[i] < umax) { GeoPoint p1 = curve1.PointAt(sp[i]); GeoPoint p2 = curve2.PointAt(curve2.PositionOf(p1)); if ((p1 | p2) > precision) { return(false); } //intermediatePointChecked = true; } } if (umax - umin < 1e-6) { // Sonderfall: nur Start/Endpunkte sind identisch. Es sollte nur dann true geliefert werden // wenn die Kurven dort tangential sind if (!Precision.SameDirection(curve1.DirectionAt(c1[0]), curve2.DirectionAt(c2[0]), false)) { return(false); } if (!Precision.SameDirection(curve1.DirectionAt(c1[1]), curve2.DirectionAt(c2[1]), false)) { return(false); } } sp = curve2.GetSavePositions(); umin = Math.Min(c2[0], c2[1]); umax = Math.Max(c2[0], c2[1]); for (int i = 0; i < sp.Length; i++) { if (sp[i] > umin && sp[i] < umax) { GeoPoint p1 = curve2.PointAt(sp[i]); GeoPoint p2 = curve1.PointAt(curve1.PositionOf(p1)); if ((p1 | p2) > precision) { return(false); } //intermediatePointChecked = true; } } { // die mittelpunkte im Parameterbereich müssen auch im anderen Parameterbereich liegen GeoPoint p1 = curve1.PointAt((c1[0] + c1[1]) / 2.0); double pos = curve2.PositionOf(p1); if (pos < 0.0 || pos > 1.0) { return(false); // eigentlich sollte die strengere Bedingung gelten: im Intervall c2[0]..c2[1]. } GeoPoint p2 = curve2.PointAt((c2[0] + c2[1]) / 2.0); pos = curve1.PositionOf(p2); if (pos < 0.0 || pos > 1.0) { return(false); // eigentlich sollte die strengere Bedingung gelten: im Intervall c2[0]..c2[1]. } // if ((p1 | p2) > precision) return false; } from1 = c1[0]; to1 = c1[1]; from2 = c2[0]; to2 = c2[1]; return(true); }
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; }
public override GeoVector DirectionAt(double Position) { return(fixedCurve.DirectionAt(Position)); // Das stimt nicht, mit Maxima berechnen, braucht sicherlich 2. Ableitung der Fläche }