Example #1
0
        /// <summary>
        /// Returns true if the given coordinate is contained in this ring.
        ///
        /// See: http://geomalgorithms.com/a03-_inclusion.html
        /// </summary>
        /// <param name="coordinate"></param>
        /// <returns></returns>
        public bool Contains(GeoCoordinate coordinate)
        {
            int number = 0;

            if (this.Coordinates[0] == coordinate)
            { // the given point is one of the corners.
                return(true);
            }
            // loop over all edges and calculate if they possibly intersect.
            for (int idx = 0; idx < this.Coordinates.Count - 1; idx++)
            {
                if (this.Coordinates[idx + 1] == coordinate)
                { // the given point is one of the corners.
                    return(true);
                }
                bool idxRight  = this.Coordinates[idx].Longitude > coordinate.Longitude;
                bool idx1Right = this.Coordinates[idx + 1].Longitude > coordinate.Longitude;
                if (idxRight || idx1Right)
                { // at least on of the coordinates is to the right of the point to calculate for.
                    if ((this.Coordinates[idx].Latitude <= coordinate.Latitude &&
                         this.Coordinates[idx + 1].Latitude >= coordinate.Latitude) &&
                        !(this.Coordinates[idx].Latitude == coordinate.Latitude &&
                          this.Coordinates[idx + 1].Latitude == coordinate.Latitude))
                    {     // idx is lower than idx+1
                        if (idxRight && idx1Right)
                        { // no need for the left/right algorithm the result is already known.
                            number++;
                        }
                        else
                        { // one of the coordinates is not to the 'right' now we need the left/right algorithm.
                            LineF2D localLine = new LineF2D(this.Coordinates[idx], this.Coordinates[idx + 1]);
                            if (localLine.PositionOfPoint(coordinate) == LinePointPosition.Left)
                            {
                                number++;
                            }
                        }
                    }
                    else if ((this.Coordinates[idx].Latitude >= coordinate.Latitude &&
                              this.Coordinates[idx + 1].Latitude <= coordinate.Latitude) &&
                             !(this.Coordinates[idx].Latitude == coordinate.Latitude &&
                               this.Coordinates[idx + 1].Latitude == coordinate.Latitude))
                    {     // idx is higher than idx+1
                        if (idxRight && idx1Right)
                        { // no need for the left/right algorithm the result is already known.
                            number--;
                        }
                        else
                        { // one of the coordinates is not to the 'right' now we need the left/right algorithm.
                            LineF2D localLine = new LineF2D(this.Coordinates[idx], this.Coordinates[idx + 1]);
                            if (localLine.PositionOfPoint(coordinate) == LinePointPosition.Right)
                            {
                                number--;
                            }
                        }
                    }
                }
            }
            return(number != 0);
        }
Example #2
0
        public void LineDistance2DTest()
        {
            double delta = 0.000000000000001;

            // create the line to test.
            PointF2D a    = new PointF2D(0, 0);
            PointF2D b    = new PointF2D(1, 1);
            LineF2D  line = new LineF2D(a, b);

            // calculate the results
            double sqrt_2       = (double)System.Math.Sqrt(2);
            double sqrt_2_div_2 = (double)System.Math.Sqrt(2) / 2.0f;

            // the point to test to.
            PointF2D c = new PointF2D(1, 0);

            Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // the point to test to.
            c = new PointF2D(0, 1);
            Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // the point to test to.
            c = new PointF2D(2, 2);
            Assert.AreEqual(line.Distance(c), 0.0f, delta, "Point distance should be 0.0f!");

            // the point to test to.
            c = new PointF2D(2, 3);
            Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // the point to test to.
            c = new PointF2D(3, 2);
            Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // Segments tests.
            line = new LineF2D(a, b, true, true);

            // the point to test to.
            c = new PointF2D(1, 0);
            Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // the point to test to.
            c = new PointF2D(0, 1);
            Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // the point to test to.
            c = new PointF2D(2, 2);
            Assert.AreEqual(line.Distance(c), sqrt_2, delta, string.Format("Point distance should be {0}!", sqrt_2));

            // the point to test to.
            c = new PointF2D(2, 1);
            Assert.AreEqual(line.Distance(c), 1, delta, string.Format("Point distance should be {0}f!", 1));

            // the point to test to.
            c = new PointF2D(1, 2);
            Assert.AreEqual(line.Distance(c), 1, delta, string.Format("Point distance should be {0}f!", 1));
        }
Example #3
0
        /// <summary>
        /// Simplify the specified points using epsilon.
        /// </summary>
        /// <param name="points">Points.</param>
        /// <param name="epsilon">Epsilon.</param>
        /// <param name="first">First.</param>
        /// <param name="last">Last.</param>
        public static PointF2D[] SimplifyBetween(PointF2D[] points, double epsilon, int first, int last)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }
            if (epsilon <= 0)
            {
                throw new ArgumentOutOfRangeException("epsilon");
            }
            if (first > last)
            {
                throw new ArgumentException(string.Format("first[{0}] must be smaller or equal than last[{1}]!",
                                                          first, last));
            }

            if (first + 1 != last)
            {
                // find point with the maximum distance.
                double maxDistance = 0;
                int    foundIndex  = -1;

                // create the line between first-last.
                LineF2D line = new LineF2D(points[first], points [last]);
                for (int idx = first + 1; idx < last; idx++)
                {
                    double distance = line.Distance(points[idx]);
                    if (distance > maxDistance)
                    {
                        // larger distance found.
                        maxDistance = distance;
                        foundIndex  = idx;
                    }
                }

                if (foundIndex > 0 && maxDistance > epsilon)                   // a point was found and it is far enough.
                {
                    PointF2D[] before = SimplifyCurve.SimplifyBetween(points, epsilon, first, foundIndex);
                    PointF2D[] after  = SimplifyCurve.SimplifyBetween(points, epsilon, foundIndex, last);

                    // build result.
                    PointF2D[] result = new PointF2D[before.Length + after.Length - 1];
                    for (int idx = 0; idx < before.Length - 1; idx++)
                    {
                        result [idx] = before [idx];
                    }
                    for (int idx = 0; idx < after.Length; idx++)
                    {
                        result [idx + before.Length - 1] = after [idx];
                    }
                    return(result);
                }
            }
            return(new PointF2D[] { points[first], points[last] });
        }
Example #4
0
 public static PointF2D[] SimplifyBetween(PointF2D[] points, double epsilon, int first, int last)
 {
     if (points == null)
     {
         throw new ArgumentNullException("points");
     }
     if (epsilon <= 0.0)
     {
         throw new ArgumentOutOfRangeException("epsilon");
     }
     if (first > last)
     {
         throw new ArgumentException(string.Format("first[{0}] must be smaller or equal than last[{1}]!", new object[2]
         {
             (object)first,
             (object)last
         }));
     }
     if (first + 1 != last)
     {
         double  num1    = 0.0;
         int     num2    = -1;
         LineF2D lineF2D = new LineF2D(points[first], points[last]);
         for (int index = first + 1; index < last; ++index)
         {
             double num3 = lineF2D.Distance(points[index]);
             if (num3 > num1)
             {
                 num1 = num3;
                 num2 = index;
             }
         }
         if (num2 > 0 && num1 > epsilon)
         {
             PointF2D[] pointF2DArray1 = SimplifyCurve.SimplifyBetween(points, epsilon, first, num2);
             PointF2D[] pointF2DArray2 = SimplifyCurve.SimplifyBetween(points, epsilon, num2, last);
             PointF2D[] pointF2DArray3 = new PointF2D[pointF2DArray1.Length + pointF2DArray2.Length - 1];
             for (int index = 0; index < pointF2DArray1.Length - 1; ++index)
             {
                 pointF2DArray3[index] = pointF2DArray1[index];
             }
             for (int index = 0; index < pointF2DArray2.Length; ++index)
             {
                 pointF2DArray3[index + pointF2DArray1.Length - 1] = pointF2DArray2[index];
             }
             return(pointF2DArray3);
         }
     }
     return(new PointF2D[2]
     {
         points[first],
         points[last]
     });
 }
Example #5
0
        public void LinePosition2DTest()
        {
            PointF2D a = new PointF2D(0, 0);
            PointF2D b = new PointF2D(1, 1);

            LineF2D line = new LineF2D(a, b);

            // test where the position lie.
            Assert.AreEqual(line.PositionOfPoint(new PointF2D(0, 0.5f)), LinePointPosition.Left, "Point position should be right!");
            Assert.AreEqual(line.PositionOfPoint(new PointF2D(0.5f, 0.5f)), LinePointPosition.On, "Point position should be on!");
            Assert.AreEqual(line.PositionOfPoint(new PointF2D(0.5f, 0)), LinePointPosition.Right, "Point position should be left!");
        }
Example #6
0
        public void LineSegmentIntersectionTests()
        {
            // double segments.
            LineF2D segment1 = new LineF2D(0, 0, 5, 0, true);
            LineF2D segment2 = new LineF2D(0, 0, 0, 5, true);
            LineF2D segment3 = new LineF2D(0, 3, 3, 0, true);
            LineF2D segment4 = new LineF2D(1, 1, 2, 2, true);
            LineF2D segment5 = new LineF2D(3, 3, 4, 4, true);
            LineF2D segment6 = new LineF2D(3, 1, 3, -1, true);

            PrimitiveF2D primitive = segment1.Intersection(segment2);

            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(0, 0), primitive as PointF2D);

            primitive = segment1.Intersection(segment3);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(3, 0), primitive as PointF2D);

            primitive = segment2.Intersection(segment3);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(0, 3), primitive as PointF2D);

            primitive = segment3.Intersection(segment4);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(1.5, 1.5), primitive as PointF2D);

            primitive = segment5.Intersection(segment1);
            Assert.IsNull(primitive);
            primitive = segment5.Intersection(segment2);
            Assert.IsNull(primitive);
            primitive = segment5.Intersection(segment3);
            Assert.IsNull(primitive);
            primitive = segment5.Intersection(segment4);
            Assert.IsNull(primitive);
            primitive = segment5.Intersection(segment6);
            Assert.IsNull(primitive);

            primitive = segment6.Intersection(segment3);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(3, 0), primitive as PointF2D);

            primitive = segment6.Intersection(segment1);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(3, 0), primitive as PointF2D);

            primitive = segment6.Intersection(segment3);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(3, 0), primitive as PointF2D);

            // half segments.
            LineF2D segment7 = new LineF2D(1.5, 2, 1.5, 0, true, false);  // only closed upwards.
            LineF2D segment9 = new LineF2D(1.5, 2, 1.5, 4, true, false);  // only closed downwards.

            LineF2D segment8  = new LineF2D(1.5, 1, 1.5, 0, true, false); // only closed upwards.
            LineF2D segment10 = new LineF2D(1.5, 1, 1.5, 4, true, false); // only closed downwards.

            primitive = segment7.Intersection(segment3);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(1.5, 1.5), primitive as PointF2D);
            primitive = segment3.Intersection(segment7);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(1.5, 1.5), primitive as PointF2D);
            primitive = segment9.Intersection(segment3);
            Assert.IsNull(primitive);
            primitive = segment3.Intersection(segment9);
            Assert.IsNull(primitive);

            primitive = segment10.Intersection(segment3);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(1.5, 1.5), primitive as PointF2D);
            primitive = segment3.Intersection(segment10);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(1.5, 1.5), primitive as PointF2D);
            primitive = segment8.Intersection(segment3);
            Assert.IsNull(primitive);
            primitive = segment3.Intersection(segment8);
            Assert.IsNull(primitive);

            LineF2D segment11 = new LineF2D(-1, 1, 0, 1, true, false);
            LineF2D segment12 = new LineF2D(0, 3, 3, 0, true, true);

            primitive = segment11.Intersection(segment12);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(2, 1), primitive as PointF2D);
            primitive = segment12.Intersection(segment11);
            Assert.IsNotNull(primitive);
            Assert.IsInstanceOf <PointF2D>(primitive);
            Assert.AreEqual(new PointF2D(2, 1), primitive as PointF2D);
        }
Example #7
0
        /// <summary>
        /// Returns true if the given coordinate is contained in this ring.
        ///
        /// See: http://geomalgorithms.com/a03-_inclusion.html
        /// </summary>
        /// <param name="X"></param>
        /// <param name="Y"></param>
        /// <param name="coordinate"></param>
        public static bool Contains(List <double> X, List <double> Y, double[] coordinate)
        {
            int number = 0;

            if (X[0] == coordinate[0] &&
                Y[0] == coordinate[1])
            { // the given point is one of the corners.
                return(true);
            }
            // loop over all edges and calculate if they possibly intersect.
            for (int idx = 0; idx < X.Count - 1; idx++)
            {
                if (X[idx + 1] == coordinate[0] &&
                    Y[idx + 1] == coordinate[1])
                { // the given point is one of the corners.
                    return(true);
                }
                bool idxRight  = X[idx] > coordinate[0];
                bool idx1Right = X[idx + 1] > coordinate[0];
                if (idxRight || idx1Right)
                { // at least one of the coordinates is to the right of the point to calculate for.
                    if ((Y[idx] <= coordinate[1] &&
                         Y[idx + 1] >= coordinate[1]) &&
                        !(Y[idx] == coordinate[1] &&
                          Y[idx + 1] == coordinate[1]))
                    {     // idx is lower than idx+1
                        if (idxRight && idx1Right)
                        { // no need for the left/right algorithm the result is already known.
                            number++;
                        }
                        else
                        { // one of the coordinates is not to the 'right' now we need the left/right algorithm.
                            LineF2D localLine = new LineF2D(
                                new PointF2D(X[idx], Y[idx]),
                                new PointF2D(X[idx + 1], Y[idx + 1]));
                            if (localLine.PositionOfPoint(new PointF2D(coordinate)) == LinePointPosition.Left)
                            {
                                number++;
                            }
                        }
                    }
                    else if ((Y[idx] >= coordinate[1] &&
                              Y[idx + 1] <= coordinate[1]) &&
                             !(Y[idx] == coordinate[1] &&
                               Y[idx + 1] == coordinate[1]))
                    {     // idx is higher than idx+1
                        if (idxRight && idx1Right)
                        { // no need for the left/right algorithm the result is already known.
                            number--;
                        }
                        else
                        { // one of the coordinates is not to the 'right' now we need the left/right algorithm.
                            LineF2D localLine = new LineF2D(
                                new PointF2D(X[idx], Y[idx]),
                                new PointF2D(X[idx + 1], Y[idx + 1]));
                            if (localLine.PositionOfPoint(new PointF2D(coordinate)) == LinePointPosition.Right)
                            {
                                number--;
                            }
                        }
                    }
                }
            }
            return(number != 0);
        }
Example #8
0
        public void LineDistance2DSegmentTest()
        {
            double delta = 0.000000000000001;

            // create the line to test.
            PointF2D a = new PointF2D(0, 0);
            PointF2D b = new PointF2D(1, 1);
            LineF2D line = new LineF2D(a, b,true,true);

            // calculate the results
            double sqrt_2 = (double)System.Math.Sqrt(2);
            double sqrt_2_div_2 = (double)System.Math.Sqrt(2) / 2.0f;

            // the point to test to.
            PointF2D c = new PointF2D(1, 0);
            Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // the point to test to.
            c = new PointF2D(0, 1);
            Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // the point to test to.
            c = new PointF2D(2, 2);
            Assert.AreEqual(line.Distance(c), sqrt_2, delta);

            // the point to test to.
            c = new PointF2D(2, 3);
            Assert.AreEqual(line.Distance(c), 2.23606797749979, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // the point to test to.
            c = new PointF2D(3, 2);
            Assert.AreEqual(line.Distance(c), 2.23606797749979, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // the point to test to.
            c = new PointF2D(1, 0);
            Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // the point to test to.
            c = new PointF2D(0, 1);
            Assert.AreEqual(line.Distance(c), sqrt_2_div_2, delta, string.Format("Point distance should be {0}f!", sqrt_2_div_2));

            // the point to test to.
            c = new PointF2D(2, 2);
            Assert.AreEqual(line.Distance(c), sqrt_2, delta, string.Format("Point distance should be {0}!", sqrt_2));

            // the point to test to.
            c = new PointF2D(2, 1);
            Assert.AreEqual(line.Distance(c), 1, delta, string.Format("Point distance should be {0}f!", 1));

            // the point to test to.
            c = new PointF2D(1, 2);
            Assert.AreEqual(line.Distance(c), 1, delta, string.Format("Point distance should be {0}f!", 1));

            // the point to test to.
            c = new PointF2D(-1, -1);
            Assert.AreEqual(line.Distance(c), sqrt_2, delta, string.Format("Point distance should be {0}f!", 1));

            // the point to test to.
            c = new PointF2D(1, -1);
            Assert.AreEqual(line.Distance(c), sqrt_2, delta, string.Format("Point distance should be {0}f!", 1));
        }
Example #9
0
        public void LinePosition2DTest()
        {
            PointF2D a = new PointF2D(0, 0);
            PointF2D b = new PointF2D(1, 1);

            LineF2D line = new LineF2D(a, b);

            // test where the position lie.
            Assert.AreEqual(line.PositionOfPoint(new PointF2D(0, 0.5f)), LinePointPosition.Left, "Point position should be right!");
            Assert.AreEqual(line.PositionOfPoint(new PointF2D(0.5f, 0.5f)), LinePointPosition.On, "Point position should be on!");
            Assert.AreEqual(line.PositionOfPoint(new PointF2D(0.5f, 0)), LinePointPosition.Right, "Point position should be left!");
        }
Example #10
0
        public static double[][] SimplifyBetween(double[][] points, double epsilon, int first, int last)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }
            if (points.Length != 2)
            {
                throw new ArgumentException();
            }
            if (epsilon < 0.0)
            {
                throw new ArgumentOutOfRangeException("epsilon");
            }
            if (first > last)
            {
                throw new ArgumentException(string.Format("first[{0}] must be smaller or equal than last[{1}]!", new object[2]
                {
                    (object)first,
                    (object)last
                }));
            }
            if (epsilon == 0.0)
            {
                return(points);
            }
            if (first == last)
            {
                return new double[2][]
                       {
                           new double[1]
                           {
                               points[0][first]
                           },
                           new double[1]
                           {
                               points[1][first]
                           }
                       }
            }
            ;
            if (points[0][first] == points[0][last] && points[1][first] == points[1][last])
            {
                double[][] numArray1 = SimplifyCurve.SimplifyBetween(points, epsilon, first, last - 1);

                double[][] numArray2 = new double[2][]
                {
                    new double[numArray1[0].Length + 1],
                    new double[numArray1[0].Length + 1]
                };
                for (int index = 0; index < numArray1[0].Length; ++index)
                {
                    numArray2[0][index] = numArray1[0][index];
                    numArray2[1][index] = numArray1[1][index];
                }
                numArray2[0][numArray1[0].Length] = points[0][last];
                numArray2[1][numArray1[0].Length] = points[1][last];
                return(numArray2);
            }
            if (first + 1 != last)
            {
                double  num1    = 0.0;
                int     num2    = -1;
                LineF2D lineF2D = new LineF2D(new PointF2D(points[0][first], points[1][first]), new PointF2D(points[0][last], points[1][last]));
                for (int index = first + 1; index < last; ++index)
                {
                    double num3 = lineF2D.Distance(new PointF2D(points[0][index], points[1][index]));
                    if (num3 > num1)
                    {
                        num1 = num3;
                        num2 = index;
                    }
                }
                if (num2 > 0 && num1 > epsilon)
                {
                    double[][] numArray1 = SimplifyCurve.SimplifyBetween(points, epsilon, first, num2);
                    double[][] numArray2 = SimplifyCurve.SimplifyBetween(points, epsilon, num2, last);
                    double[][] numArray3 = new double[2][]
                    {
                        new double[numArray1[0].Length + numArray2[0].Length - 1],
                        new double[numArray1[0].Length + numArray2[0].Length - 1]
                    };
                    for (int index = 0; index < numArray1[0].Length - 1; ++index)
                    {
                        numArray3[0][index] = numArray1[0][index];
                        numArray3[1][index] = numArray1[1][index];
                    }
                    for (int index = 0; index < numArray2[0].Length; ++index)
                    {
                        numArray3[0][index + numArray1[0].Length - 1] = numArray2[0][index];
                        numArray3[1][index + numArray1[0].Length - 1] = numArray2[1][index];
                    }
                    return(numArray3);
                }
            }
            return(new double[2][]
            {
                new double[2]
                {
                    points[0][first],
                    points[0][last]
                },
                new double[2]
                {
                    points[1][first],
                    points[1][last]
                }
            });
        }
Example #11
0
        /// <summary>
        /// Simplify the specified points using epsilon.
        /// </summary>
        /// <param name="points">Points.</param>
        /// <param name="epsilon">Epsilon.</param>
        /// <param name="first">First.</param>
        /// <param name="last">Last.</param>
        public static double[][] SimplifyBetween(double[][] points, double epsilon, int first, int last)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }
            if (points.Length != 2)
            {
                throw new ArgumentException();
            }
            if (epsilon < 0)
            {
                throw new ArgumentOutOfRangeException("epsilon");
            }
            if (first > last)
            {
                throw new ArgumentException(string.Format("first[{0}] must be smaller or equal than last[{1}]!",
                                                          first, last));
            }

            if (epsilon == 0)
            { // no simplification is possible.
                return(points);
            }
            if (first == last)
            { // first and last are equal, no simplification possible.
                return(new double[][]
                       { new double[] { points[0][first] }, new double[] { points[1][first] } });
            }

            double[][] result;
            // check for identical first and last points.
            if (points[0][first] == points[0][last] &&
                points[1][first] == points[1][last])
            { // first and last point are indentical.
                double[][] before = SimplifyCurve.SimplifyBetween(points, epsilon, first, last - 1);

                // build result.
                result    = new double[2][];
                result[0] = new double[before[0].Length + 1];
                result[1] = new double[before[0].Length + 1];
                for (int idx = 0; idx < before[0].Length; idx++)
                {
                    result[0][idx] = before[0][idx];
                    result[1][idx] = before[1][idx];
                }
                result[0][before[0].Length] = points[0][last];
                result[1][before[0].Length] = points[1][last];
                return(result);
            }

            if (first + 1 != last)
            {
                // find point with the maximum distance.
                double maxDistance = 0;
                int    foundIndex  = -1;

                // create the line between first-last.
                LineF2D line = new LineF2D(new PointF2D(
                                               points[0][first], points[1][first]),
                                           new PointF2D(
                                               points[0][last], points[1][last]));
                for (int idx = first + 1; idx < last; idx++)
                {
                    double distance = line.Distance(new PointF2D(
                                                        points[0][idx], points[1][idx]));
                    if (distance > maxDistance)
                    {
                        // larger distance found.
                        maxDistance = distance;
                        foundIndex  = idx;
                    }
                }

                if (foundIndex > 0 && maxDistance > epsilon)
                { // a point was found and it is far enough.
                    double[][] before = SimplifyCurve.SimplifyBetween(points, epsilon, first, foundIndex);
                    double[][] after  = SimplifyCurve.SimplifyBetween(points, epsilon, foundIndex, last);

                    // build result.
                    result    = new double[2][];
                    result[0] = new double[before[0].Length + after[0].Length - 1];
                    result[1] = new double[before[0].Length + after[0].Length - 1];
                    for (int idx = 0; idx < before[0].Length - 1; idx++)
                    {
                        result[0][idx] = before[0][idx];
                        result[1][idx] = before[1][idx];
                    }
                    for (int idx = 0; idx < after[0].Length; idx++)
                    {
                        result[0][idx + before[0].Length - 1] = after[0][idx];
                        result[1][idx + before[0].Length - 1] = after[1][idx];
                    }
                    return(result);
                }
            }
            result    = new double[2][];
            result[0] = new double[] { points[0][first], points[0][last] };
            result[1] = new double[] { points[1][first], points[1][last] };
            return(result);
        }