Exemple #1
0
        /// <summary>
        /// Fits this rectangle to the given points.
        /// </summary>
        /// <param name="points">The points to wrap the rectangle around.</param>
        /// <param name="percentage">The margin in percentage.</param>
        /// <returns></returns>
        public RectangleF2D Fit(PointF2D[] points, double percentage)
        {
            if (points == null)
            {
                throw new ArgumentNullException("points");
            }
            if (points.Length < 2)
            {
                throw new ArgumentOutOfRangeException("Rectangle fit needs at least two points.");
            }

            // calculate the center.
            double[] center = new double[] { points[0][0], points[0][1] };
            for (int idx = 1; idx < points.Length; idx++)
            {
                center[0] = center[0] + points[idx][0];
                center[1] = center[1] + points[idx][1];
            }
            center[0] = center[0] / points.Length;
            center[1] = center[1] / points.Length;
            PointF2D centerPoint = new PointF2D(center);

            LineF2D line = null;
            // calculate the width.
            double width = 0;

            for (int idx = 0; idx < points.Length; idx++)
            {
                line = new LineF2D(points[idx], points[idx] + this._vectorY);
                double distance = line.Distance(centerPoint);
                if (distance > width)
                { // the distance is larger.
                    width = distance;
                }
            }
            width = width * 2;

            // calculate the height.
            double height = 0;

            for (int idx = 0; idx < points.Length; idx++)
            {
                line = new LineF2D(points[idx], points[idx] + this._vectorX);
                double distance = line.Distance(centerPoint);
                if (distance > height)
                { // this distance is larger.
                    height = distance;
                }
            }
            height = height * 2;

            // expand with the given percentage.
            width  = width + (width / 100.0 * percentage);
            height = height + (height / 100.0 * percentage);

            return(RectangleF2D.FromBoundsAndCenter(width, height, centerPoint[0], centerPoint[1],
                                                    this.DirectionY));
        }
        /// <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] };
        }
        /// <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 (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;
        }
Exemple #4
0
        /// <summary>
        /// Fits this rectangle to the given points.
        /// </summary>
        /// <param name="points">The points to wrap the rectangle around.</param>
        /// <param name="percentage">The margin in percentage.</param>
        /// <returns></returns>
        public RectangleF2D Fit(PointF2D[] points, double percentage)
        {
            if (points == null) { throw new ArgumentNullException("points"); }
            if (points.Length < 2) { throw new ArgumentOutOfRangeException("Rectangle fit needs at least two points."); }

            // calculate the center.
            double[] center = new double[] { points[0][0], points[0][1] };
            for (int idx = 1; idx < points.Length; idx++)
            {
                center[0] = center[0] + points[idx][0];
                center[1] = center[1] + points[idx][1];
            }
            center[0] = center[0] / points.Length;
            center[1] = center[1] / points.Length;
            PointF2D centerPoint = new PointF2D(center);

            LineF2D line = null;
            // calculate the width.
            double width = 0;
            for (int idx = 0; idx < points.Length; idx++)
            {
                line = new LineF2D(points[idx], points[idx] + this._vectorY);
                double distance = line.Distance(centerPoint);
                if (distance > width)
                { // the distance is larger.
                    width = distance;
                }
            }
            width = width * 2;

            // calculate the height.
            double height = 0;
            for (int idx = 0; idx < points.Length; idx++)
            {
                line = new LineF2D(points[idx], points[idx] + this._vectorX);
                double distance = line.Distance(centerPoint);
                if (distance > height)
                { // this distance is larger.
                    height = distance;
                }
            }
            height = height * 2;

            // expand with the given percentage.
            width = width + (width / 100.0 * percentage);
            height = height + (height / 100.0 * percentage);

            return RectangleF2D.FromBoundsAndCenter(width, height, centerPoint[0], centerPoint[1],
                this.DirectionY);
        }
Exemple #5
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));
        }