/// <summary>
            /// Minimise the stored distance function over a given interval
            /// </summary>
            /// <param name="eval"> Spline evaluator </param>
            /// <param name="interval"> Interval size </param>
            /// <param name="iterations"> Number of iterations </param>
            /// <returns> Point in interval that minimises stored distance function </returns>
            public float GetClosestPointInInterval( Evaluator eval, float interval, int iterations )
            {
                m_S[ 0 ] = eval.GlobalT;
                m_S[ 1 ] = eval.GlobalT + ( interval / 2 );
                m_S[ 2 ] = eval.GlobalT + interval;

                float minT = m_S[ 0 ];
                float maxT = m_S[ 2 ];

                m_Points[ 0 ] 		= eval.EvaluatePositionWithClampedGlobalT( m_S[ 0 ] );
                m_Points[ 1 ] 		= eval.EvaluatePositionWithClampedGlobalT( m_S[ 1 ] );
                m_Points[ 2 ] 		= eval.EvaluatePositionWithClampedGlobalT( m_S[ 2 ] );

                m_Distances[ 0 ] 	= m_Distance( m_Points[ 0 ] );
                m_Distances[ 1 ] 	= m_Distance( m_Points[ 1 ] );
                m_Distances[ 2 ] 	= m_Distance( m_Points[ 2 ] );

                int BestIndex = 0;
                float ClosestDistance = float.MaxValue;

                for ( int k = 0; k < iterations; ++k )
                {
                    m_S2[ 0 ] = m_S[ 0 ] * m_S[ 0 ];
                    m_S2[ 1 ] = m_S[ 1 ] * m_S[ 1 ];
                    m_S2[ 2 ] = m_S[ 2 ] * m_S[ 2 ];

                    float PolyEstimateNum	=	( ( m_S2[ 1 ] - m_S2[ 2 ] ) * m_Distances[ 0 ] ) +
                                                ( ( m_S2[ 2 ] - m_S2[ 0 ] ) * m_Distances[ 1 ] ) +
                                                ( ( m_S2[ 0 ] - m_S2[ 1 ] ) * m_Distances[ 2 ] );
                    float PolyEstimateDen	=	( (  m_S[ 1 ] -  m_S[ 2 ] ) * m_Distances[ 0 ] ) +
                                                ( (  m_S[ 2 ] -  m_S[ 0 ] ) * m_Distances[ 1 ] ) +
                                                ( (  m_S[ 0 ] -  m_S[ 1 ] ) * m_Distances[ 2 ] );

                    if ( Math.Abs( PolyEstimateDen ) < 0.0001f )
                    {
                        break;
                    }

                    m_S[ 3 ]			= Utils.Clamp( 0.5f * ( PolyEstimateNum / PolyEstimateDen ), minT, maxT );
                    m_Points[ 3 ]		= eval.EvaluatePositionWithClampedGlobalT( m_S[ 3 ] );
                    m_Distances[ 3 ]	= m_Distance( m_Points[ 3 ] );

                    m_PValues[ 0 ] 		= EvaluatePolynomial( m_S[ 0 ] );
                    m_PValues[ 1 ] 		= EvaluatePolynomial( m_S[ 1 ] );
                    m_PValues[ 2 ] 		= EvaluatePolynomial( m_S[ 2 ] );
                    m_PValues[ 3 ] 		= EvaluatePolynomial( m_S[ 3 ] );

                    //	Which estimate created the furthest distance?
                    int		FurthestIndex		= 0;
                    float	FurthestDistance	= -float.MaxValue;
                    for ( int Index = 0; Index < 4; ++Index )
                    {
                        if ( m_PValues[ Index ] > FurthestDistance )
                        {
                            FurthestDistance	= m_PValues[ Index ];
                            FurthestIndex		= Index;
                        }
                    }

                    //	Remake arrays m_S and m_Distances using the 3 closest estimates
                    int AddAt = 0;
                    ClosestDistance = float.MaxValue;
                    for ( int Index = 0; Index < 4; ++Index )
                    {
                        if ( Index != FurthestIndex )
                        {
                            m_S[ AddAt ]			= m_S[ Index ];
                            m_Distances[ AddAt ]	= m_Distances[ Index ];
                            m_Points[ AddAt ]		= m_Points[ Index ];
                            m_PValues[ AddAt ]		= m_PValues[ Index ];

                            if ( m_PValues[ AddAt ] < ClosestDistance )
                            {
                                BestIndex = AddAt;
                            }

                            ++AddAt;
                        }
                    }
                }

                if ( ClosestDistance < m_ClosestDistance )
                {
                    m_ClosestDistance	= ClosestDistance;
                    m_ClosestFraction	= m_S[ BestIndex ];
                }

                return m_ClosestFraction;
            }