private static void RandomPointsComparer(IPointDComparer comparer)
        {
            RectD bounds = new RectD(-100, -100, 200, 200);

            PointD[] points = GeoAlgorithms.RandomPoints(100, bounds, comparer, 2);

            for (int i = 0; i < points.Length; i++)
            {
                PointD p = points[i];
                Assert.IsTrue(bounds.Contains(p));
                if (i > 0)
                {
                    Assert.AreEqual(+1, comparer.Compare(p, points[i - 1]));
                }
                if (i < points.Length - 1)
                {
                    Assert.AreEqual(-1, comparer.Compare(p, points[i + 1]));
                }

                for (int j = 0; j < points.Length; j++)
                {
                    if (i == j)
                    {
                        continue;
                    }
                    double distance = p.Subtract(points[j]).LengthSquared;
                    Assert.GreaterOrEqual(distance, 4);
                }
            }
        }
        /// <summary>
        /// Creates an <see cref="Array"/> of random <see cref="PointD"/> coordinates within the
        /// specified area, ensuring a specified pairwise minimum distance.</summary>
        /// <param name="count">
        /// The number of <see cref="PointD"/> coordinates to create.</param>
        /// <param name="bounds">
        /// The coordinates of the area containing all <see cref="PointD"/> coordinates.</param>
        /// <param name="comparer">
        /// The <see cref="IPointDComparer"/> instance used to sort and search the collection of
        /// <see cref="PointD"/> coordinates.</param>
        /// <param name="distance">
        /// The smallest Euclidean distance between any two <see cref="PointD"/> coordinates.
        /// </param>
        /// <returns>
        /// An <see cref="Array"/> containing <paramref name="count"/> randomly created <see
        /// cref="PointD"/> coordinates whose pairwise distance is equal to or greater than
        /// <paramref name="distance"/>.</returns>
        /// <exception cref="ArgumentNullException">
        /// <paramref name="comparer"/> is a null reference.</exception>
        /// <exception cref="ArgumentOutOfRangeException"><para>
        /// <paramref name="count"/> is less than zero.
        /// </para><para>-or-</para><para>
        /// <paramref name="bounds"/> contains a <see cref="RectD.Width"/> or <see
        /// cref="RectD.Height"/> that is equal to or less than zero.
        /// </para><para>-or-</para><para>
        /// <paramref name="distance"/> is equal to or less than zero.</para></exception>
        /// <remarks><para>
        /// The returned <see cref="Array"/> is sorted using the specified <paramref
        /// name="comparer"/>, and never contains duplicate <see cref="PointD"/> coordinates.
        /// </para><note type="caution">
        /// <b>RandomPoints</b> may enter an endless loop if <paramref name="distance"/> is too
        /// great relative to <paramref name="count"/> and <paramref name="bounds"/>.
        /// </note></remarks>

        public static PointD[] RandomPoints(int count,
                                            RectD bounds, IPointDComparer comparer, double distance)
        {
            if (count < 0)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(
                    "count", count, Strings.ArgumentNegative);
            }
            if (bounds.Width <= 0 || bounds.Height <= 0)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(
                    "bounds", bounds, Strings.ArgumentCoordinatesInvalid);
            }

            if (comparer == null)
            {
                ThrowHelper.ThrowArgumentNullException("comparer");
            }
            if (distance <= 0)
            {
                ThrowHelper.ThrowArgumentOutOfRangeException(
                    "distance", distance, Strings.ArgumentNotPositive);
            }

            distance *= distance;
            List <PointD> points = new List <PointD>(count);

            for (int i = 0; i < count; i++)
            {
createPoint:
                PointD point = new PointD(
                    bounds.X + MersenneTwister.Default.NextDouble() * bounds.Width,
                    bounds.Y + MersenneTwister.Default.NextDouble() * bounds.Height);

                if (points.Count > 0)
                {
                    int index = comparer.FindNearest(points, point);
                    if (point.Subtract(points[index]).LengthSquared < distance)
                    {
                        goto createPoint;
                    }
                }

                points.Add(point);
                points.Sort(comparer);
            }

            return(points.ToArray());
        }