예제 #1
0
        /***************************************************/
        /****          Split curve at points            ****/
        /***************************************************/

        public static List <Arc> SplitAtPoints(this Arc arc, List <Point> points, double tolerance = Tolerance.Distance)
        {
            if (!points.Any())
            {
                return new List <Arc> {
                           arc.DeepClone()
                }
            }
            ;

            List <Arc>   result = new List <Arc>();
            List <Point> cPts   = new List <Point>();
            Vector       normal = arc.Normal();

            foreach (Point point in points)
            {
                if (point.IsOnCurve(arc, tolerance))
                {
                    cPts.Add(point);
                }
            }

            cPts.Add(arc.StartPoint());
            cPts.Add(arc.EndPoint());
            cPts = cPts.CullDuplicates(tolerance);
            cPts = cPts.SortAlongCurve(arc, tolerance);

            if (arc.EndAngle - 2 * Math.PI < tolerance && arc.EndAngle - 2 * Math.PI > -tolerance)
            {
                cPts.Add(arc.EndPoint());
            }

            if (cPts.Count > 2)
            {
                Double startAng = arc.StartAngle;
                Double endAng   = arc.EndAngle;
                Double tmpAng   = 0;
                Arc    tmpArc;

                for (int i = 1; i < cPts.Count; i++)
                {
                    tmpArc = arc.DeepClone();

                    tmpArc.StartAngle = startAng;
                    tmpAng            = (2 * Math.PI + (cPts[i - 1] - arc.Centre()).SignedAngle(cPts[i] - arc.Centre(), normal)) % (2 * Math.PI);
                    endAng            = startAng + tmpAng;
                    tmpArc.EndAngle   = endAng;
                    result.Add(tmpArc);
                    startAng = endAng;
                }
            }
            else
            {
                result.Add(arc.DeepClone());
            }
            return(result);
        }
예제 #2
0
        /***************************************************/
        /**** Public Methods - Curves                   ****/
        /***************************************************/

        public static Point ClosestPoint(this Arc curve, Point point, double tolerance = Tolerance.Distance)
        {
            if (point.SquareDistance(curve.Centre()) <= tolerance * tolerance)
            {
                return(curve.StartPoint());
            }

            Point center   = curve.Centre();
            Point midPoint = curve.PointAtParameter(0.5);
            Plane p        = curve.FitPlane();

            Point  onCircle = center + (point.Project(p) - center).Normalise() * curve.Radius;
            double sqrd     = midPoint.SquareDistance(curve.StartPoint());

            return(midPoint.SquareDistance(onCircle) <= sqrd ? onCircle : onCircle.ClosestPoint(new List <Point> {
                curve.StartPoint(), curve.EndPoint()
            }));
        }
예제 #3
0
        /***************************************************/
        /**** Public Methods - Curve / curve            ****/
        /***************************************************/

        public static bool IsContaining(this Arc curve1, ICurve curve2, bool acceptOnEdge = true, double tolerance = Tolerance.Distance)
        {
            if (!curve1.IsClosed(tolerance))
            {
                return(false);
            }
            Circle circle = new Circle {
                Centre = curve1.Centre(), Radius = curve1.Radius(), Normal = curve1.FitPlane().Normal
            };

            return(circle.IsContaining(curve2));
        }
예제 #4
0
        /***************************************************/
        /**** Public Methods - Curve / points           ****/
        /***************************************************/

        public static bool IsContaining(this Arc curve, List <Point> points, bool acceptOnEdge = true, double tolerance = Tolerance.Distance)
        {
            if (!curve.IsClosed(tolerance))
            {
                return(false);
            }
            Circle circle = new Circle {
                Centre = curve.Centre(), Radius = curve.Radius(), Normal = curve.FitPlane().Normal
            };

            return(circle.IsContaining(points, acceptOnEdge, tolerance));
        }
예제 #5
0
        /***************************************************/
        /**** Public Methods - Curves                   ****/
        /***************************************************/

        public static Point ClosestPoint(this Arc arc, Point point)
        {
            Point center   = arc.Centre();
            Point midPoint = arc.PointAtParameter(0.5);
            Plane p        = arc.FitPlane();

            Point  onCircle = center + (point.Project(p) - center).Normalise() * arc.Radius;
            double sqrd     = midPoint.SquareDistance(arc.StartPoint());

            return(midPoint.SquareDistance(onCircle) <= sqrd ? onCircle : onCircle.ClosestPoint(new List <Point> {
                arc.StartPoint(), arc.EndPoint()
            }));
        }
예제 #6
0
        /***************************************************/

        public static List <Point> LineIntersections(this Arc arc, Line line, bool useInfiniteLine = false, double tolerance = Tolerance.Distance)
        {
            Line l = line.DeepClone();

            l.Infinite = useInfiniteLine ? true : l.Infinite;

            List <Point> iPts     = new List <Point>();
            Point        midPoint = arc.PointAtParameter(0.5);

            Point center = arc.Centre();

            //Check if curves are coplanar
            if (Math.Abs(arc.CoordinateSystem.Z.DotProduct(l.Direction())) > Tolerance.Angle)
            {
                //Curves not coplanar
                Point pt = l.PlaneIntersection((Plane)arc.CoordinateSystem);
                if (pt != null && Math.Abs(pt.Distance(center) - arc.Radius) <= tolerance)
                {
                    iPts.Add(pt);
                }
            }
            else
            {
                //Curves coplanar
                Circle c = new Circle {
                    Centre = center, Normal = arc.CoordinateSystem.Z, Radius = arc.Radius
                };
                iPts = c.LineIntersections(l);
            }

            List <Point> output = new List <Point>();

            double halfAngle = arc.Angle() / 2;
            double tolAngle  = tolerance / arc.Radius;
            double sqrd      = 2 * Math.Pow(arc.Radius, 2) * (1 - Math.Cos(Math.Abs(halfAngle + tolAngle))); // Cosine rule

            {
                foreach (Point pt in iPts)
                {
                    if ((l.Infinite || pt.Distance(l) <= tolerance) && midPoint.SquareDistance(pt) <= sqrd)
                    {
                        output.Add(pt);
                    }
                }
            }

            return(output);
        }
예제 #7
0
        /***************************************************/
        /**** Public  Methods - Curves                  ****/
        /***************************************************/

        public static NurbsCurve ToNurbsCurve(this Arc arc)
        {
            {
                double angle  = arc.EndAngle - arc.StartAngle;
                Point  centre = arc.Centre();
                int    nbPts  = 1 + 2 * (int)Math.Ceiling(2 * angle / Math.PI);
                double factor = Math.Cos(angle / (nbPts - 1));

                // Create the points
                List <Point> points = new List <Point>();
                for (int i = 0; i < nbPts; i++)
                {
                    double t  = i * 1.0 / (nbPts - 1);
                    Point  pt = arc.PointAtParameter(t);
                    if (i % 2 == 1)
                    {
                        pt = centre + (pt - centre) / factor;
                    }
                    points.Add(pt);
                }

                // Create the knots
                double        knotStep = 2.0 / (nbPts - 1);
                List <double> knots    = new List <double>();
                for (int i = 0; i < (nbPts + 1) / 2; i++)
                {
                    knots.Add(i * knotStep);
                    knots.Add(i * knotStep);
                }

                // Create the weights
                List <double> weights = new List <double>();
                for (int i = 0; i < nbPts; i++)
                {
                    double w = (i % 2 == 0) ? 1.0 : factor;
                    weights.Add(w);
                }

                return(new NurbsCurve {
                    ControlPoints = points, Knots = knots, Weights = weights
                });
            }
        }
예제 #8
0
        /***************************************************/

        public static Output <Point, Point> CurveProximity(this Arc curve1, Circle curve2, double tolerance = Tolerance.Distance)
        {
            List <Point> cIntersections = curve1.CurveIntersections(curve2);

            if (cIntersections.Count > 0)
            {
                return new Output <Point, Point> {
                           Item1 = cIntersections[0], Item2 = cIntersections[0]
                }
            }
            ;

            Output <Point, Point> result = new Output <Point, Point>();
            Plane        ftPln1          = curve1.FitPlane();
            Plane        ftPln2          = curve2.FitPlane();
            List <Point> intPts          = new List <Point>();
            Point        tmp             = null;

            if ((intPts = curve1.PlaneIntersections(ftPln2)).Count != 0)
            {
                if (intPts.Count == 1)
                {
                    tmp = intPts[0];
                }
                else
                {
                    if (intPts[0].Distance(curve2) < intPts[1].Distance(curve2))
                    {
                        tmp = intPts[0];
                    }
                    else
                    {
                        tmp = intPts[1];
                    }
                }
            }
            else if ((intPts = curve2.PlaneIntersections(ftPln1)).Count != 0)
            {
                if (intPts.Count == 1)
                {
                    if (tmp == null)
                    {
                        tmp = intPts[0];
                    }
                    else if (tmp.Distance(curve2) > intPts[0].Distance(curve1))
                    {
                        tmp = intPts[0];
                    }
                }
                else
                {
                    if (intPts[0].Distance(curve1) < intPts[1].Distance(curve1))
                    {
                        if (tmp == null)
                        {
                            tmp = intPts[0];
                        }
                        else if (tmp.Distance(curve2) > intPts[0].Distance(curve1))
                        {
                            tmp = intPts[0];
                        }
                    }
                    else
                    {
                        if (tmp == null)
                        {
                            tmp = intPts[1];
                        }
                        else if (tmp.Distance(curve2) > intPts[1].Distance(curve1))
                        {
                            tmp = intPts[1];
                        }
                    }
                }
            }

            Output <Point, Point> oldresult  = new Output <Point, Point>();
            Output <Point, Point> oldresult2 = new Output <Point, Point>();
            Output <Point, Point> result2    = new Output <Point, Point>();

            if (tmp != null)
            {
                if (tmp.IsOnCurve(curve1))
                {
                    result.Item1 = tmp;
                    result.Item2 = curve2.ClosestPoint(result.Item1);
                }
                else
                {
                    result.Item2 = tmp;
                    result.Item1 = curve1.ClosestPoint(result.Item2);
                }

                do
                {
                    oldresult.Item1 = result.Item1;
                    oldresult.Item2 = result.Item2;
                    result.Item1    = curve2.ClosestPoint(result.Item2);
                    result.Item2    = curve1.ClosestPoint(result.Item1);
                }while (oldresult.Item2.Distance(result.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result.Item1) > tolerance * tolerance);
            }
            else
            {
                Line intersect = new Line {
                    Start = curve1.Centre(), End = curve2.Centre
                };
                Point tmp1 = intersect.CurveProximity(curve1).Item1;
                Point tmp2 = intersect.CurveProximity(curve2).Item1;
                if (tmp == null)
                {
                    tmp = tmp1;
                }

                if (tmp1.Distance(curve2) < tmp.Distance(curve1) || tmp1.Distance(curve2) < tmp.Distance(curve2))
                {
                    tmp = tmp1;
                }

                if (tmp2.Distance(curve1) < tmp.Distance(curve1) || tmp2.Distance(curve1) < tmp.Distance(curve2))
                {
                    tmp = tmp2;
                }

                if (tmp.IsOnCurve(curve1))
                {
                    result.Item1 = tmp;
                    result.Item2 = curve2.ClosestPoint(tmp);
                }
                else
                {
                    result.Item2 = tmp;
                    result.Item1 = curve1.ClosestPoint(tmp);
                }

                do
                {
                    oldresult.Item1 = result.Item1;
                    oldresult.Item2 = result.Item2;
                    result.Item1    = curve2.ClosestPoint(result.Item2);
                    result.Item2    = curve1.ClosestPoint(result.Item1);
                }while (oldresult.Item2.Distance(result.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result.Item1) > tolerance * tolerance);
            }

            if (curve1.EndPoint().Distance(curve2.ClosestPoint(curve1.EndPoint())) < result.Item1.Distance(result.Item2))
            {
                result.Item1 = curve1.EndPoint();
                result.Item2 = curve2.ClosestPoint(result.Item1);
            }

            if (curve1.StartPoint().Distance(curve2.ClosestPoint(curve1.StartPoint())) < result.Item1.Distance(result.Item2))
            {
                result.Item1 = curve1.StartPoint();
                result.Item2 = curve2.ClosestPoint(result.Item1);
            }

            tmp           = curve1.PointAtParameter((curve1.ParameterAtPoint(result.Item1) + 0.6) % 1);
            result2.Item1 = tmp;
            result2.Item2 = curve2.ClosestPoint(tmp);

            do
            {
                oldresult2.Item1 = result2.Item1;
                oldresult2.Item2 = result2.Item2;
                result2.Item1    = curve2.ClosestPoint(result2.Item2);
                result2.Item2    = curve1.ClosestPoint(result2.Item1);
            }while (oldresult2.Item2.Distance(result2.Item2) > tolerance * tolerance && oldresult2.Item1.Distance(result2.Item1) > tolerance * tolerance);

            if (result.Item1.Distance(result.Item2) > result2.Item1.Distance(result2.Item2))
            {
                result = result2;
            }

            return(result);
        }
예제 #9
0
        /***************************************************/

        public static Output <Point, Point> CurveProximity(this Arc curve1, Arc curve2, double tolerance = Tolerance.Distance)
        {
            List <Point> cIntersections = curve1.CurveIntersections(curve2);

            if (cIntersections.Count > 0)
            {
                return new Output <Point, Point> {
                           Item1 = cIntersections[0], Item2 = cIntersections[0]
                }
            }
            ;

            Output <Point, Point> result    = new Output <Point, Point>();
            Output <Point, Point> oldresult = new Output <Point, Point>();
            Output <Point, Point> result2   = new Output <Point, Point>();
            Output <Point, Point> result3   = new Output <Point, Point>();
            Output <Point, Point> result4   = new Output <Point, Point>();
            Output <Point, Point> result5   = new Output <Point, Point>();
            Output <Point, Point> result6   = new Output <Point, Point>();
            Plane        ftPln1             = curve1.FitPlane();
            Plane        ftPln2             = curve2.FitPlane();
            List <Point> fitPoints          = new List <Point>();
            bool         check = false;

            if ((fitPoints = curve1.PlaneIntersections(ftPln2)).Count > 0)
            {
                if (fitPoints.Count == 1)
                {
                    result.Item1 = fitPoints[0];
                    result.Item2 = curve2.ClosestPoint(fitPoints[0]);
                    check        = true;
                }
                else if (fitPoints.Count > 1)
                {
                    if (fitPoints[0].Distance(curve2) < fitPoints[1].Distance(curve2))
                    {
                        result.Item1 = fitPoints[0];
                        result.Item2 = curve2.ClosestPoint(fitPoints[0]);
                        check        = true;
                    }
                    else
                    {
                        result.Item1 = fitPoints[1];
                        result.Item2 = curve2.ClosestPoint(fitPoints[1]);
                        check        = true;
                    }
                }
            }

            if ((fitPoints = curve2.PlaneIntersections(ftPln1)).Count > 0)
            {
                if (check)
                {
                    if (fitPoints.Count == 1 && (fitPoints[0].Distance(curve1) < result.Item1.Distance(curve2)))
                    {
                        result.Item2 = fitPoints[0];
                        result.Item1 = curve1.ClosestPoint(fitPoints[0]);
                    }
                    else if (fitPoints.Count > 1)
                    {
                        if (fitPoints[0].Distance(curve1) < fitPoints[1].Distance(curve1))
                        {
                            if (fitPoints[0].Distance(curve1) < result.Item1.Distance(curve2))
                            {
                                result.Item2 = fitPoints[0];
                                result.Item1 = curve1.ClosestPoint(fitPoints[0]);
                            }
                        }
                        else
                        {
                            if (fitPoints[1].Distance(curve1) < result.Item1.Distance(curve2))
                            {
                                result.Item2 = fitPoints[1];
                                result.Item1 = curve1.ClosestPoint(fitPoints[1]);
                            }
                        }
                    }
                }
                else if (fitPoints.Count == 1)
                {
                    result.Item2 = fitPoints[0];
                    result.Item1 = curve1.ClosestPoint(fitPoints[0]);
                    check        = true;
                }
                else if (fitPoints.Count > 1)
                {
                    if (fitPoints[0].Distance(curve1) < fitPoints[1].Distance(curve1))
                    {
                        result.Item2 = fitPoints[0];
                        result.Item1 = curve1.ClosestPoint(fitPoints[0]);
                        check        = true;
                    }
                    else
                    {
                        result.Item2 = fitPoints[1];
                        result.Item1 = curve1.ClosestPoint(fitPoints[1]);
                        check        = true;
                    }
                }
            }

            if (check)
            {
                do
                {
                    oldresult.Item1 = result.Item1;
                    oldresult.Item2 = result.Item2;
                    result.Item1    = curve2.ClosestPoint(result.Item2);
                    result.Item2    = curve1.ClosestPoint(result.Item1);
                }while (oldresult.Item2.Distance(result.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result.Item1) > tolerance * tolerance);
            }

            check = false;
            Line intersect = new Line {
                Start = curve1.Centre(), End = curve2.Centre()
            };
            Point tmp1 = intersect.CurveProximity(curve1).Item2;
            Point tmp2 = intersect.CurveProximity(curve2).Item2;

            if (tmp1.Distance(curve2) < tmp2.Distance(curve1))
            {
                result2.Item1 = tmp1;
                result2.Item2 = curve2.ClosestPoint(tmp1);
            }
            else
            {
                result2.Item2 = tmp2;
                result2.Item1 = curve1.ClosestPoint(tmp2);
            }

            do
            {
                oldresult.Item1 = result2.Item1;
                oldresult.Item2 = result2.Item2;
                result2.Item1   = curve2.ClosestPoint(result2.Item2);
                result2.Item2   = curve1.ClosestPoint(result2.Item1);
            }while (oldresult.Item2.Distance(result2.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result2.Item1) > tolerance * tolerance);

            if (curve1.EndPoint().Distance(curve2.ClosestPoint(curve1.EndPoint())) < curve1.StartPoint().Distance(curve2.ClosestPoint(curve1.StartPoint())))
            {
                result3.Item1 = curve1.EndPoint();
                result3.Item2 = curve2.ClosestPoint(result3.Item1);
            }
            else
            {
                result3.Item1 = curve1.StartPoint();
                result3.Item2 = curve2.ClosestPoint(result3.Item1);
            }

            if (curve2.EndPoint().Distance(curve1.ClosestPoint(curve2.EndPoint())) < curve2.StartPoint().Distance(curve1.ClosestPoint(curve2.StartPoint())))
            {
                result4.Item2 = curve2.EndPoint();
                result4.Item1 = curve1.ClosestPoint(result4.Item2);
            }
            else
            {
                result4.Item2 = curve2.StartPoint();
                result4.Item1 = curve1.ClosestPoint(result4.Item2);
            }

            do
            {
                oldresult.Item1 = result3.Item1;
                oldresult.Item2 = result3.Item2;
                result3.Item1   = curve2.ClosestPoint(result3.Item2);
                result3.Item2   = curve1.ClosestPoint(result3.Item1);
            }while (oldresult.Item2.Distance(result3.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result3.Item1) > tolerance * tolerance);

            do
            {
                oldresult.Item1 = result4.Item1;
                oldresult.Item2 = result4.Item2;
                result4.Item1   = curve2.ClosestPoint(result4.Item2);
                result4.Item2   = curve1.ClosestPoint(result4.Item1);
            }while (oldresult.Item2.Distance(result4.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result4.Item1) > tolerance * tolerance);

            result5.Item2 = curve2.PointAtParameter(0.5);
            result5.Item1 = curve1.ClosestPoint(result5.Item2);
            result6.Item1 = curve1.PointAtParameter(0.5);
            result6.Item2 = curve2.ClosestPoint(result6.Item1);

            do
            {
                oldresult.Item1 = result5.Item1;
                oldresult.Item2 = result5.Item2;
                result5.Item1   = curve2.ClosestPoint(result5.Item2);
                result5.Item2   = curve1.ClosestPoint(result5.Item1);
            }while (oldresult.Item2.Distance(result5.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result5.Item1) > tolerance * tolerance);

            do
            {
                oldresult.Item1 = result6.Item1;
                oldresult.Item2 = result6.Item2;
                result6.Item1   = curve2.ClosestPoint(result6.Item2);
                result6.Item2   = curve1.ClosestPoint(result6.Item1);
            }while (oldresult.Item2.Distance(result6.Item2) > tolerance * tolerance && oldresult.Item1.Distance(result6.Item1) > tolerance * tolerance);

            if (result.Item1 == null || result.Item2 == null)
            {
                result = result2;
            }

            if (result2.Item2.Distance(result2.Item1) < result.Item1.Distance(result.Item2))
            {
                result = result2;
            }

            if (result3.Item2.Distance(result3.Item1) < result.Item1.Distance(result.Item2))
            {
                result = result3;
            }

            if (result4.Item2.Distance(result4.Item1) < result.Item1.Distance(result.Item2))
            {
                result = result4;
            }

            if (result5.Item2.Distance(result5.Item1) < result.Item1.Distance(result.Item2))
            {
                result = result5;
            }

            if (result6.Item2.Distance(result6.Item1) < result.Item1.Distance(result.Item2))
            {
                result = result6;
            }

            return(result);
        }
예제 #10
0
        /***************************************************/

        public static Output <Point, Point> CurveProximity(this Line curve1, Arc curve2, double tolerance = Tolerance.Distance)
        {
            List <Point> cIntersections = curve1.CurveIntersections(curve2);

            if (cIntersections.Count > 0)
            {
                return new Output <Point, Point> {
                           Item1 = cIntersections[0], Item2 = cIntersections[0]
                }
            }
            ;

            List <Point> plnPts = new List <Point>();

            plnPts.Add(curve1.Start);
            plnPts.Add(curve1.End);
            plnPts.Add(curve2.Centre());
            Point tmp;
            Plane ftPln = plnPts.FitPlane();

            if (ftPln != null)
            {
                List <Point> intersecting = curve2.PlaneIntersections(ftPln);

                if (intersecting.Count > 1)
                {
                    if (intersecting[0].Distance(curve1) < intersecting[1].Distance(curve1))
                    {
                        tmp = intersecting[0];
                    }
                    else
                    {
                        tmp = intersecting[1];
                    }
                }
                else if (intersecting.Count == 1)
                {
                    tmp = intersecting[0];
                }
                else
                {
                    tmp = curve2.StartPoint();
                }
            }
            else
            {
                tmp = curve2.StartPoint();
            }

            if (curve2.StartPoint().Distance(curve1) < tmp.Distance(curve1))
            {
                tmp = curve2.StartPoint();
            }

            if (curve2.EndPoint().Distance(curve1) < tmp.Distance(curve1))
            {
                tmp = curve2.EndPoint();
            }

            Line         prLn  = curve1.Project(curve2.FitPlane());
            List <Point> lnInt = prLn.CurveIntersections(curve2);

            if (lnInt.Count > 0)
            {
                if (lnInt.Count > 1)
                {
                    if (lnInt[0].Distance(curve1) > lnInt[0].Distance(curve1))
                    {
                        lnInt[0] = lnInt[1];
                    }
                }

                if (lnInt[0].Distance(curve1) < tmp.Distance(curve1))
                {
                    tmp = lnInt[0];
                }
            }

            Output <Point, Point> result = new Output <Point, Point>();

            result.Item1 = curve1.ClosestPoint(tmp);
            result.Item2 = curve2.ClosestPoint(result.Item1);
            result.Item1 = curve1.ClosestPoint(result.Item2);
            Output <Point, Point> oldfinal = new Output <Point, Point>();
            Output <Point, Point> result2  = new Output <Point, Point>();

            if (curve1.Start.Distance(curve2) < curve1.End.Distance(curve2))
            {
                result2.Item1 = curve1.Start;
            }
            else
            {
                result2.Item1 = curve1.End;
            }

            result2.Item2 = curve2.ClosestPoint(result2.Item1);
            result2.Item1 = curve1.ClosestPoint(result2.Item2);
            Output <Point, Point> final = new Output <Point, Point>();

            if (result.Item1.Distance(result.Item2) < result2.Item1.Distance(result2.Item2))
            {
                final = result;
            }
            else
            {
                final = result2;
            }

            do
            {
                oldfinal.Item1 = final.Item1;
                oldfinal.Item2 = final.Item2;
                final.Item2    = curve2.ClosestPoint(final.Item1);
                final.Item1    = curve1.ClosestPoint(final.Item2);
            }while (Math.Abs(oldfinal.Item1.Distance(oldfinal.Item2) - final.Item1.Distance(final.Item2)) > tolerance * tolerance);

            return(final);
        }