/// <summary> /// Remove kinks if possible. /// Works only for 3d curves. /// </summary> /// <param name="curve">3d curve</param> /// <param name="kinks">kinks provided by a method '_FindKinksAtEnds'</param> /// <param name="failReason">if a method failed - this string will have fail reason</param> /// <returns></returns> private static Curve _Kinks_TryRemove_Smooth(Curve curve, List <CurveKinkData> kinks, int DIVBY_FIX, int DIVBY_MIN, out string failReason) { failReason = ""; Percent cutPercents = 1.0 / DIVBY_FIX; var crv = new CurveNormalized(curve); // // Cut curve at kink ends // var crvCutted = new CurveNormalized(curve); var cutPointAtStart = Point3d.Origin; var cutPointAtEnd = Point3d.Origin; foreach (var kink in kinks) { switch (kink.CrvEnd) { case CurveEnd.Start: cutPointAtStart = crv.PointAt(0 + cutPercents); // cut 5% from start crvCutted = crvCutted.Trim(0 + cutPercents, 1, out failReason); // remove outside interval if (crvCutted == null) { return(null); } break; case CurveEnd.End: cutPointAtEnd = crv.PointAt(1 - cutPercents); // cut 5% from start crvCutted = crvCutted.Trim(0, 1 - cutPercents, out failReason); // remove outside interval if (crvCutted == null) { return(null); } break; } } //if(DEBUG) Layers.Debug.AddCurve(crvCutted); // // Extend cutted crv // var crvExtended = crvCutted.Crv; foreach (var kink in kinks) { switch (kink.CrvEnd) { case CurveEnd.Start: crvExtended = crvExtended._ExtendToPoint(CurveEnd.Start, curve.PointAtStart); if (crvExtended == null) { failReason = "failed to extend crv"; return(null); } break; case CurveEnd.End: crvExtended = crvExtended._ExtendToPoint(CurveEnd.End, curve.PointAtEnd); if (crvExtended == null) { failReason = "failed to extend crv"; return(null); } break; } } //if (DEBUG) Layers.Debug.AddCurve(crvExtended); // // Move ends of extended curve // var divby = crvExtended._GetDivBy(null, 0.01, DIVBY_MIN); Point3d[] pointsExtended; double[] tsExtended; if (!crvExtended._TryDivideByCount(divby, out pointsExtended, out tsExtended, out failReason)) { return(null); } foreach (var kink in kinks) { var end = kink.CrvEnd; var extendToPoint = curve._P(end); var direction = extendToPoint - crvExtended._P(end); var iStart = (end == CurveEnd.Start) // will be more close to middle of curve ? -Math.Abs(Array.BinarySearch(tsExtended, crvExtended._T(cutPointAtStart))) // negative value, like '-5' : Math.Abs(Array.BinarySearch(tsExtended, crvExtended._T(cutPointAtEnd))); var iEnd = (end == CurveEnd.Start) ? 0 : pointsExtended.Length - 1; // will be at ends of curve for (int ii = iStart; ii <= iEnd; ii++) { double shiftByPercent = (ii - iStart) / (double)(iEnd - iStart); // from 0 to 1 var i = Math.Abs(ii); if (DEBUG) { Layers.Debug.AddPoint(pointsExtended[i]); } pointsExtended[i] = pointsExtended[i] + direction * shiftByPercent; if (DEBUG) { Layers.Debug.AddPoint(pointsExtended[i]); } } } // // Construct new curve // var newCuve = Curve.CreateControlPointCurve(pointsExtended, 3); if (newCuve == null) { failReason = "failed to create curve from 3d points"; return(null); } if (DEBUG) { Layers.Debug.AddCurve(newCuve, "Smooth"); } newCuve = newCuve._Simplify(); //simplify crv after constructing if from many points return(newCuve); }
/// <summary> /// Remove kinks if possible. /// Works only for 3d curves. /// </summary> /// <param name="curve">3d curve</param> /// <param name="kinks">kinks provided by a method '_FindKinksAtEnds'</param> /// <param name="failReason">if a method failed - this string will have fail reason</param> /// <returns></returns> private static Curve _Kinks_TryRemove_Smooth_Iternal(Curve curve, List <CurveKinkData> kinks, int DIVBY_FIX, int DIVBY_MIN, out string failReason) { failReason = ""; Percent cutPercents = 1.0 / DIVBY_FIX; // // Cut curve at kink ends // var crvCutted = new CurveNormalized(curve); foreach (var kink in kinks) { switch (kink.CrvEnd) { case CurveEnd.Start: crvCutted = crvCutted.Trim(0 + cutPercents, 1, out failReason); // remove outside interval if (crvCutted == null) { return(null); } break; case CurveEnd.End: crvCutted = crvCutted.Trim(0, 1 - cutPercents, out failReason); // remove outside interval if (crvCutted == null) { return(null); } break; } } //if(DEBUG) Layers.Debug.AddCurve(crvCutted); // // Extend cutted crv // var crvExtended = crvCutted.Crv; foreach (var kink in kinks) { switch (kink.CrvEnd) { case CurveEnd.Start: crvExtended = crvExtended.Extend(CurveEnd.Start, CurveExtensionStyle.Arc, curve.PointAtStart); if (crvExtended == null) { failReason = "failed to extend crv"; return(null); } break; case CurveEnd.End: crvExtended = crvExtended.Extend(CurveEnd.End, CurveExtensionStyle.Arc, curve.PointAtEnd); if (crvExtended == null) { failReason = "failed to extend crv"; return(null); } break; } } if (DEBUG) { Layers.Debug.AddCurve(crvExtended, "Smooth_Iternal", Color.Bisque); } return(crvExtended); }