Exemple #1
0
        /// <summary>
        /// Returns all the intersections the line has with this polygon.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public PointF2D[] Intersections(LineF2D line)
        {
            List <PointF2D> points = new List <PointF2D>();

            foreach (LineF2D polygon_line in this.LineEnumerator)
            {
                // calculate the intersection.
                PrimitiveF2D primitive = line.Intersection(polygon_line);

                // the primitive not null.
                if (primitive != null)
                {
                    if (primitive is LineF2D)
                    { // primitive is a line; convert.
                        LineF2D intersect_line =
                            (primitive as LineF2D);

                        // we are sure the line is a segment.
                        // if the line is not a segment this means that the polygon contains an line with infinite length; impossible.

                        // TODO: how to determine the order?
                        points.Add(intersect_line.Point1);
                        points.Add(intersect_line.Point2);
                    }
                    else if (primitive is PointF2D)
                    { // primitive is a point; convert.
                        PointF2D point = (primitive as PointF2D);
                        points.Add(point);
                    }
                }
            }

            return(points.ToArray());
        }
Exemple #2
0
        public static PointF2D PositionAtPosition(double[] x, double[] y, double position)
        {
            if (x.Length < 2)
            {
                throw new ArgumentOutOfRangeException("Given coordinates do not represent a polyline.");
            }
            double num1 = 0.0;

            for (int index = 1; index < x.Length; ++index)
            {
                double num2 = x[index - 1] - x[index];
                double num3 = y[index - 1] - y[index];
                double num4 = System.Math.Sqrt(num2 * num2 + num3 * num3);
                if (num1 + num4 > position)
                {
                    LineF2D   lineF2D   = new LineF2D(new PointF2D(x[index - 1], y[index - 1]), new PointF2D(x[index], y[index]));
                    double    num5      = position - num1;
                    VectorF2D vectorF2D = lineF2D.Direction.Normalize() * num5;
                    return(lineF2D.Point1 + vectorF2D);
                }
                num1 += num4;
            }
            LineF2D lineF2D1 = new LineF2D(new PointF2D(x[x.Length - 2], y[x.Length - 2]), new PointF2D(x[x.Length - 1], y[x.Length - 1]));

            return(lineF2D1.Point1 + lineF2D1.Direction.Normalize() * (position - num1));
        }
Exemple #3
0
        /// <summary>
        /// Returns a position on the given polyline corresponding with the given position. (0 smaller than position smaller than polyline.lenght).
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        public static PointF2D PositionAtPosition(double[] x, double[] y, double position)
        {
            if (x.Length < 2)
            {
                throw new ArgumentOutOfRangeException("Given coordinates do not represent a polyline.");
            }

            double  lenght    = 0;
            LineF2D localLine = null;

            for (int idx = 1; idx < x.Length; idx++)
            {
                localLine = new LineF2D(new PointF2D(x[idx - 1], y[idx - 1]),
                                        new PointF2D(x[idx], y[idx]));
                double localLength = localLine.Length;
                if (lenght + localLength > position)
                { // position is between point at idx and idx + 1.
                    double    localPosition = position - lenght;
                    VectorF2D vector        = localLine.Direction.Normalize() * localPosition;
                    return(localLine.Point1 + vector);
                }
                lenght = lenght + localLength;
            }
            return(localLine.Point1 + (localLine.Direction.Normalize() * (position - lenght)));
        }
Exemple #4
0
        /// <summary>
        /// Returns a position on the given polyline corresponding with the given position. (0 smaller than position smaller than polyline.lenght).
        /// </summary>
        /// <param name="x"></param>
        /// <param name="y"></param>
        /// <param name="position"></param>
        /// <returns></returns>
        public static PointF2D PositionAtPosition(double[] x, double[] y, double position)
        {
            if (x.Length < 2) throw new ArgumentOutOfRangeException("Given coordinates do not represent a polyline.");

            double lenght = 0;
            LineF2D localLine;
            for (int idx = 1; idx < x.Length; idx++)
            {
                double xDiff = (x [idx - 1] - x [idx]);
                double yDiff = (y [idx - 1] - y [idx]);
                double localLength = System.Math.Sqrt ((xDiff * xDiff) + (yDiff * yDiff));
                if(lenght + localLength > position)
                { // position is between point at idx and idx + 1.
                    localLine = new LineF2D(new PointF2D(x[idx - 1], y[idx - 1]),
                        new PointF2D(x[idx], y[idx]));
                    double localPosition = position - lenght;
                    VectorF2D vector = localLine.Direction.Normalize() * localPosition;
                    return localLine.Point1 + vector;
                }
                lenght = lenght + localLength;
            }
            localLine = new LineF2D(new PointF2D(x[x.Length - 2], y[x.Length - 2]),
                new PointF2D(x[x.Length - 1], y[x.Length - 1]));
            return localLine.Point1 + (localLine.Direction.Normalize() * (position - lenght));
        }
Exemple #5
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 #6
0
        /// <summary>
        /// Transforms the given the coordinates to a coordinate system defined inside this rectangle.
        /// </summary>
        /// <param name="width">Width.</param>
        /// <param name="height">Height.</param>
        /// <param name="reverseX">If set to <c>true</c> reverse x.</param>
        /// <param name="reverseY">If set to <c>true</c> reverse y.</param>
        /// <param name="point">Point.</param>
        /// <param name="transformed">Transformed.</param>
        public void TransformTo(double width, double height, bool reverseX, bool reverseY,
                                PointF2D point, double[] transformed)
        {
            if (transformed == null)
            {
                throw new ArgumentNullException();
            }
            if (transformed.Length != 2)
            {
                throw new ArgumentException("Tranformed array needs to be of length 2.");
            }

            PointF2D  reference = _bottomLeft;
            VectorF2D vectorX   = _vectorX;
            VectorF2D vectorY   = _vectorY;

            if (reverseX && !reverseY)
            {
                reference = this.BottomRight;
                vectorX   = _vectorX * -1;
            }
            else if (!reverseX && reverseY)
            {
                reference = this.TopLeft;
                vectorY   = _vectorY * -1;
            }
            else if (reverseX && reverseY)
            {
                reference = this.TopRight;
                vectorX   = _vectorX * -1;
                vectorY   = _vectorY * -1;
            }

            LineF2D   xLine               = new LineF2D(point, point + vectorX, false);
            PointF2D  yIntersection       = xLine.Intersection(new LineF2D(reference, reference + vectorY)) as PointF2D;
            VectorF2D yIntersectionVector = (yIntersection - reference);
            double    yFactor             = yIntersectionVector.Size / vectorY.Size;

            if (!yIntersectionVector.CompareNormalized(vectorY, 0.0001))
            {
                yFactor = -yFactor;
            }

            LineF2D   yLine               = new LineF2D(point, point + vectorY);
            PointF2D  xIntersection       = yLine.Intersection(new LineF2D(reference, reference + vectorX)) as PointF2D;
            VectorF2D xIntersectionVector = (xIntersection - reference);
            double    xFactor             = xIntersectionVector.Size / vectorX.Size;

            if (!xIntersectionVector.CompareNormalized(vectorX, 0.0001))
            {
                xFactor = -xFactor;
            }

            transformed [0] = xFactor * width;
            transformed [1] = yFactor * height;
        }
Exemple #7
0
        public bool Intersects(LineF2D line)
        {
            PointF2D[]        corners           = this.Corners;
            LinePointPosition linePointPosition = line.PositionOfPoint(corners[0]);

            for (int index = 1; index <= corners.Length; ++index)
            {
                if (line.PositionOfPoint(corners[index]) != linePointPosition)
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #8
0
        /// <summary>
        /// Transforms the given the coordinates to a coordinate system defined inside this rectangle.
        /// </summary>
        /// <param name="width">The width of the rectangle in the coordinate system of the given coordinates.</param>
        /// <param name="height">The height of the rectangle in the coordinate system of the given coordinates.</param>
        /// <param name="reverseX">Assumes that the origin of the x-axis is on the top of this rectangle if false.</param>
        /// <param name="reverseY">Assumes that the origin of the y-axis is on the right of this rectangle if false.</param>
        /// <param name="x">The x-coordinate to transform.</param>
        /// <param name="y">The y-coordinate to transform.</param>
        public double[][] TransformTo(double width, double height, bool reverseX, bool reverseY,
                                      double[] x, double[] y)
        {
            PointF2D  reference = _bottomLeft;
            VectorF2D vectorX   = _vectorX;
            VectorF2D vectorY   = _vectorY;

            if (reverseX && !reverseY)
            {
                reference = this.BottomRight;
                vectorX   = _vectorX * -1;
            }
            else if (!reverseX && reverseY)
            {
                reference = this.TopLeft;
                vectorY   = _vectorY * -1;
            }
            else if (reverseX && reverseY)
            {
                reference = this.TopRight;
                vectorX   = _vectorX * -1;
                vectorY   = _vectorY * -1;
            }

            double[][] transformed = new double[x.Length][];
            for (int idx = 0; idx < x.Length; idx++)
            {
                PointF2D  point               = new PointF2D(x [idx], y [idx]);
                LineF2D   xLine               = new LineF2D(point, point + vectorX, false);
                PointF2D  yIntersection       = xLine.Intersection(new LineF2D(reference, reference + vectorY)) as PointF2D;
                VectorF2D yIntersectionVector = (yIntersection - reference);
                double    yFactor             = yIntersectionVector.Size / vectorY.Size;
                if (!yIntersectionVector.CompareNormalized(vectorY, 0.0001))
                {
                    yFactor = -yFactor;
                }

                LineF2D   yLine               = new LineF2D(point, point + vectorY);
                PointF2D  xIntersection       = yLine.Intersection(new LineF2D(reference, reference + vectorX)) as PointF2D;
                VectorF2D xIntersectionVector = (xIntersection - reference);
                double    xFactor             = xIntersectionVector.Size / vectorX.Size;
                if (!xIntersectionVector.CompareNormalized(vectorX, 0.0001))
                {
                    xFactor = -xFactor;
                }

                transformed[idx] = new double[] { xFactor *width, yFactor *height };
            }
            return(transformed);
        }
Exemple #9
0
        public bool Intersects(PointF2D point1, PointF2D point2)
        {
            PointF2D[]        corners           = this.Corners;
            LineF2D           lineF2D           = new LineF2D(point1, point2, true);
            LinePointPosition linePointPosition = lineF2D.PositionOfPoint(corners[0]);

            for (int index = 1; index < corners.Length; ++index)
            {
                if (lineF2D.PositionOfPoint(corners[index]) != linePointPosition)
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #10
0
        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.");
            }
            double[] values = new double[2]
            {
                points[0][0],
                points[0][1]
            };
            for (int index = 1; index < points.Length; ++index)
            {
                values[0] = values[0] + points[index][0];
                values[1] = values[1] + points[index][1];
            }
            values[0] = values[0] / (double)points.Length;
            values[1] = values[1] / (double)points.Length;
            PointF2D p    = new PointF2D(values);
            double   num1 = 0.0;

            for (int index = 0; index < points.Length; ++index)
            {
                double num2 = new LineF2D(points[index], points[index] + this._vectorY).Distance(p);
                if (num2 > num1)
                {
                    num1 = num2;
                }
            }
            double num3 = num1 * 2.0;
            double num4 = 0.0;

            for (int index = 0; index < points.Length; ++index)
            {
                double num2 = new LineF2D(points[index], points[index] + this._vectorX).Distance(p);
                if (num2 > num4)
                {
                    num4 = num2;
                }
            }
            double num5 = num4 * 2.0;

            return(RectangleF2D.FromBoundsAndCenter(num3 + num3 / 100.0 * percentage, num5 + num5 / 100.0 * percentage, p[0], p[1], this.DirectionY));
        }
Exemple #11
0
        /// <summary>
        /// Projects a point onto the given line.
        ///
        /// (= intersection of the line with an angle 90° different from this line through the given point)
        /// </summary>
        /// <param name="point"></param>
        /// <returns>The projection point if it occurs inside the segmented line.</returns>
        public PointF2D ProjectOn(PointF2D point)
        {
            if (this.Length == 0 && this.IsSegment)
            { // cannot project on a line of length zero.
                return(null);
            }

            // get the direction.
            VectorF2D direction = this.Direction;

            // rotate.
            VectorF2D rotated = direction.Rotate90(true);

            // create second point
            PointF2D point2 = new PointF2D((point + rotated).ToArray());

            if (point[0] != point2[0] || point[1] != point2[1])
            {
                // create line.
                LineF2D line = new LineF2D(
                    point,
                    point2,
                    false,
                    false);

                // intersect.
                PrimitiveF2D primitive =
                    this.Intersection(line, true);

                if (primitive == null)
                {
                    return(null);
                }
                else if (primitive is PointF2D)
                {
                    return(primitive as PointF2D);
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
            else
            {
                return(point2);
            }
        }
Exemple #12
0
        /// <summary>
        /// Transforms the given the coordinates to a coordinate system defined inside this rectangle.
        /// </summary>
        /// <param name="width">The width of the rectangle in the coordinate system of the given coordinates.</param>
        /// <param name="height">The height of the rectangle in the coordinate system of the given coordinates.</param>
        /// <param name="reverseX">Assumes that the origin of the x-axis is on the top of this rectangle if false.</param>
        /// <param name="reverseY">Assumes that the origin of the y-axis is on the right of this rectangle if false.</param>
        /// <param name="point">The coordinate to transform.</param>
        public double[] TransformTo(double width, double height, bool reverseX, bool reverseY,
                                    PointF2D point)
        {
            PointF2D  reference = _bottomLeft;
            VectorF2D vectorX   = _vectorX;
            VectorF2D vectorY   = _vectorY;

            if (reverseX && !reverseY)
            {
                reference = this.BottomRight;
                vectorX   = _vectorX * -1;
            }
            else if (!reverseX && reverseY)
            {
                reference = this.TopLeft;
                vectorY   = _vectorY * -1;
            }
            else if (reverseX && reverseY)
            {
                reference = this.TopRight;
                vectorX   = _vectorX * -1;
                vectorY   = _vectorY * -1;
            }

            LineF2D   xLine               = new LineF2D(point, point + vectorX, false);
            PointF2D  yIntersection       = xLine.Intersection(new LineF2D(reference, reference + vectorY)) as PointF2D;
            VectorF2D yIntersectionVector = (yIntersection - reference);
            double    yFactor             = yIntersectionVector.Size / vectorY.Size;

            if (!yIntersectionVector.CompareNormalized(vectorY, 0.0001))
            {
                yFactor = -yFactor;
            }

            LineF2D   yLine               = new LineF2D(point, point + vectorY);
            PointF2D  xIntersection       = yLine.Intersection(new LineF2D(reference, reference + vectorX)) as PointF2D;
            VectorF2D xIntersectionVector = (xIntersection - reference);
            double    xFactor             = xIntersectionVector.Size / vectorX.Size;

            if (!xIntersectionVector.CompareNormalized(vectorX, 0.0001))
            {
                xFactor = -xFactor;
            }

            return(new double[] { xFactor *width, yFactor *height });
        }
Exemple #13
0
        /// <summary>
        /// Returns true if the line intersects with this bounding box.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public bool Intersects(LineF2D line)
        {
            // if all points have the same relative position with respect to the line
            // there is no intersection. In the other case there is.

            PointF2D[]        corners        = this.Corners;
            LinePointPosition first_position = line.PositionOfPoint(corners[0]);

            for (int idx = 1; idx <= corners.Length; idx++)
            {
                if (line.PositionOfPoint(corners[idx]) != first_position)
                {
                    return(true);
                }
            }

            return(false);
        }
        /// <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] };
        }
Exemple #15
0
        public override double Distance(PointF2D p)
        {
            double num1 = new LineF2D(this.BottomLeft, this.BottomRight, true).Distance(p);
            double num2 = new LineF2D(this.BottomRight, this.TopRight, true).Distance(p);

            if (num2 < num1)
            {
                num1 = num2;
            }
            double num3 = new LineF2D(this.TopRight, this.TopLeft, true).Distance(p);

            if (num3 < num1)
            {
                num1 = num3;
            }
            double num4 = new LineF2D(this.TopLeft, this.BottomLeft, true).Distance(p);

            if (num4 < num1)
            {
                num1 = num4;
            }
            return(num1);
        }
Exemple #16
0
 public PointF2D[] Intersections(LineF2D line)
 {
     List<PointF2D> pointF2DList = new List<PointF2D>();
       foreach (LineF2D line1 in this.LineEnumerator)
       {
     PrimitiveF2D primitiveF2D = line.Intersection(line1);
     if (primitiveF2D != null)
     {
       if (primitiveF2D is LineF2D)
       {
     LineF2D lineF2D = primitiveF2D as LineF2D;
     pointF2DList.Add(lineF2D.Point1);
     pointF2DList.Add(lineF2D.Point2);
       }
       else if ((object) (primitiveF2D as PointF2D) != null)
       {
     PointF2D pointF2D = primitiveF2D as PointF2D;
     pointF2DList.Add(pointF2D);
       }
     }
       }
       return pointF2DList.ToArray();
 }
Exemple #17
0
        /// <summary>
        /// Calculates and returns the line intersection.
        /// </summary>
        /// <param name="line"></param>
        /// <param name="doSegment"></param>
        /// <returns></returns>
        public PrimitiveF2D Intersection(LineF2D line, bool doSegment)
        {
            if (line == this)
            { // if the lines equal, the full lines intersect.
                return line;
            }
            else if (line.A == this.A
                    && line.B == this.B
                    && line.C == this.C)
            { // if the lines equal in direction and position; return the smallest segment.
                KeyValuePair<double, PointF2D> point1 = new KeyValuePair<double, PointF2D>(
                    0, this.Point1);

                KeyValuePair<double, PointF2D> point2 = new KeyValuePair<double, PointF2D>(
                     this.Point1.Distance(this.Point2), this.Point2);

                // sort.
                KeyValuePair<double, PointF2D> temp;
                if (point2.Key < point1.Key)
                { // point2 smaller than point1.
                    temp = point2;
                    point2 = point1;
                    point1 = temp;
                }

                KeyValuePair<double, PointF2D> point = new KeyValuePair<double, PointF2D>(
                     this.Point1.Distance(line.Point1), line.Point1);

                if (point.Key < point2.Key) // sort.
                { // point smaller than point2.
                    temp = point;
                    point = point2;
                    point2 = temp;
                }
                if (point2.Key < point1.Key)
                { // point2 smaller than point1.
                    temp = point2;
                    point2 = point1;
                    point1 = temp;
                }

                point = new KeyValuePair<double, PointF2D>(
                     this.Point1.Distance(line.Point2), line.Point2);

                if (point.Key < point2.Key) // sort.
                { // point smaller than point2.
                    temp = point;
                    point = point2;
                    point2 = temp;
                }
                if (point2.Key < point1.Key)
                { // point2 smaller than point1.
                    temp = point2;
                    point2 = point1;
                    point1 = temp;
                }

                // this line is a segment.
                if (doSegment && (this.IsSegment1 || this.IsSegment2))
                { // test where the intersection lies.
                    double this_distance =
                        this.Point1.Distance(this.Point2);
                    if (this.IsSegment)
                    { // if in any directions one of the points are further away from the point.
                        double this_distance_1 = System.Math.Min(this.Point1.Distance(point1.Value),
                            this.Point1.Distance(point2.Value));
                        if (this_distance_1 > this_distance)
                        { // the point is further away.
                            return null;
                        }
                    }
                    else if (this.IsSegment1)
                    { // if in any directions one of the points are further away from the point.
                        double this_distance_1 = this.Point1.Distance(point1.Value);
                        if (this_distance_1 > this_distance)
                        { // the point is further away.
                            return null;
                        }
                    }
                    else if (this.IsSegment2)
                    { // if in any directions one of the points are further away from the point.
                        double this_distance_2 = this.Point2.Distance(point1.Value);
                        if (this_distance_2 > this_distance)
                        { // the point is further away.
                            return null;
                        }
                    }
                }
                // other line is a segment.
                if (doSegment && (line.IsSegment1 || line.IsSegment2))
                { // test where the intersection lies.
                    double this_distance =
                        line.Point1.Distance(line.Point2);
                    if (line.IsSegment)
                    {// if in any directions one of the points are further away from the point.
                        double this_distance_1 = System.Math.Min(line.Point1.Distance(point1.Value),
                            line.Point1.Distance(point2.Value));
                        if (this_distance_1 > this_distance)
                        { // the point is further away.
                            return null;
                        }
                    }
                    else if (line.IsSegment1)
                    { // if in any directions one of the points are further away from the point.
                        double this_distance_1 = line.Point1.Distance(point1.Value);
                        if (this_distance_1 > this_distance)
                        { // the point is further away.
                            return null;
                        }
                    }
                    else if (line.IsSegment2)
                    { // if in any directions one of the points are further away from the point.
                        double this_distance_2 = line.Point2.Distance(point2.Value);
                        if (this_distance_2 > this_distance)
                        { // the point is further away.
                            return null;
                        }
                    }
                }
                return new LineF2D(
                    point1.Value,
                    point2.Value,
                    true);
            }
            else
            { // line.A = A1, line.B = B1, line.C = C1, this.A = A2, this.B = B2, this.C = C2
                double det = (line.A * this.B - this.A * line.B);
                if (det == 0) // TODO: implement an accuracy threshold epsilon.
                { // lines are parallel; no intersections.
                    return null;
                }
                else
                { // lines are not the same and not parallel so they will intersect.
                    double x = (this.B * line.C - line.B * this.C) / det;
                    double y = (line.A * this.C - this.A * line.C) / det;

                    // create the point.
                    PointF2D point = new PointF2D(new double[]{x, y});

                    // this line is a segment.
                    if (doSegment && (this.IsSegment1 || this.IsSegment2))
                    { // test where the intersection lies.
                        double this_distance =
                            this.Point1.Distance(this.Point2);
                        if (this.IsSegment)
                        {// if in any directions one of the points are further away from the point.
                            double this_distance_1 = this.Point1.Distance(point);
                            if (this_distance_1 > this_distance)
                            { // the point is further away.
                                return null;
                            }
                            double this_distance_2 = this.Point2.Distance(point);
                            if (this_distance_2 > this_distance)
                            { // the point is further away.
                                return null;
                            }
                        }
                        else if (this.IsSegment1 && this.Point2.Distance(point) > this_distance)
                        { // only check this direction and only if the points lies far enough away from point2.
                            VectorF2D pointDirection = point - this.Point2;
                            VectorF2D point2ToPoint1 = this.Direction.Inverse;
                            if (pointDirection.CompareNormalized(point2ToPoint1, 0.001))
                            { // point lies in the direction of the segmented point1 and far away from point2
                                return null;
                            }
                        }
                        else if (this.IsSegment1 && this.Point1.Distance(point) > this_distance)
                        { // only check this direction and only if the points lies far enough away from point1.
                            VectorF2D pointDirection = point - this.Point1;
                            VectorF2D point1ToPoint2 = this.Direction;
                            if (pointDirection.CompareNormalized(point1ToPoint2, 0.001))
                            { // point lies in the direction of the segmented point1 and far away from point2
                                return null;
                            }
                        }
                    }
                    // line this is a segment.
                    if (doSegment && (line.IsSegment1 || line.IsSegment2))
                    { // test where the intersection lies.
                        double line_distance =
                            line.Point1.Distance(line.Point2);
                        if (line.IsSegment)
                        {// if in any directions one of the points are further away from the point.
                            double line_distance_1 = line.Point1.Distance(point);
                            if (line_distance_1 > line_distance)
                            { // the point is further away.
                                return null;
                            }
                            double line_distance_2 = line.Point2.Distance(point);
                            if (line_distance_2 > line_distance)
                            { // the point is further away.
                                return null;
                            }
                        }
                        else if (line.IsSegment1 && line.Point2.Distance(point) > line_distance)
                        { // only check line direction and only if the points lies far enough away from point2.
                            VectorF2D pointDirection = point - line.Point2;
                            VectorF2D point2ToPoint1 = line.Direction.Inverse;
                            if (pointDirection.CompareNormalized(point2ToPoint1, 0.001))
                            { // point lies in the direction of the segmented point1 and far away from point2
                                return null;
                            }
                        }
                        else if (line.IsSegment1 && line.Point1.Distance(point) > line_distance)
                        { // only check line direction and only if the points lies far enough away from point1.
                            VectorF2D pointDirection = point - line.Point1;
                            VectorF2D point1ToPoint2 = line.Direction;
                            if (pointDirection.CompareNormalized(point1ToPoint2, 0.001))
                            { // point lies in the direction of the segmented point1 and far away from point2
                                return null;
                            }
                        }
                    }

                    // the intersection is valid.
                    return point;
                }
            }
        }
Exemple #18
0
 /// <summary>
 /// Return true if the given line intersects with this line.
 /// </summary>
 /// <param name="line">Line.</param>
 public bool Intersects(LineF2D line)
 {
     return this.Intersection (line) != null;
 }
Exemple #19
0
 /// <summary>
 /// Return true if the given line intersects with this line.
 /// </summary>
 /// <param name="line">Line.</param>
 /// <param name="doSegment"></param>
 public bool Intersects(LineF2D line, bool doSegment)
 {
     return this.Intersection (line, doSegment) != null;
 }
Exemple #20
0
        /// <summary>
        /// Transforms the given the coordinates to a coordinate system defined inside this rectangle.
        /// </summary>
        public double[] TransformTo(double width, double height, bool reverseX, bool reverseY,
		                            PointF2D point)
        {
            PointF2D reference = _bottomLeft;
            VectorF2D vectorX = _vectorX;
            VectorF2D vectorY = _vectorY;

            if (reverseX && !reverseY) {
                reference = this.BottomRight;
                vectorX = _vectorX * -1;
            } else if (!reverseX && reverseY) {
                reference = this.TopLeft;
                vectorY = _vectorY * -1;
            } else if (reverseX && reverseY) {
                reference = this.TopRight;
                vectorX = _vectorX * -1;
                vectorY = _vectorY * -1;
            }

            LineF2D xLine = new LineF2D (point, point + vectorX, false);
            PointF2D yIntersection = xLine.Intersection (new LineF2D (reference, reference + vectorY)) as PointF2D;
            VectorF2D yIntersectionVector = (yIntersection - reference);
            double yFactor = yIntersectionVector.Size / vectorY.Size;
            if (!yIntersectionVector.CompareNormalized (vectorY, 0.0001)) {
                yFactor = -yFactor;
            }

            LineF2D yLine = new LineF2D (point, point + vectorY);
            PointF2D xIntersection = yLine.Intersection (new LineF2D (reference, reference + vectorX)) as PointF2D;
            VectorF2D xIntersectionVector = (xIntersection - reference);
            double xFactor = xIntersectionVector.Size / vectorX.Size;
            if (!xIntersectionVector.CompareNormalized (vectorX, 0.0001)) {
                xFactor = -xFactor;
            }

            return new double[] { xFactor * width, yFactor * height };
        }
Exemple #21
0
        /// <summary>
        /// Transforms the given the coordinates to a coordinate system defined inside this rectangle.
        /// </summary>
        /// <param name="width">Width.</param>
        /// <param name="height">Height.</param>
        /// <param name="reverseX">If set to <c>true</c> reverse x.</param>
        /// <param name="reverseY">If set to <c>true</c> reverse y.</param>
        /// <param name="point">Point.</param>
        /// <param name="transformed">Transformed.</param>
        public void TransformTo(double width, double height, bool reverseX, bool reverseY,
			PointF2D point, double[] transformed)
        {
            if (transformed == null) {
                throw new ArgumentNullException ();
            }
            if (transformed.Length != 2) {
                throw new ArgumentException ("Tranformed array needs to be of length 2.");
            }

            PointF2D reference = _bottomLeft;
            VectorF2D vectorX = _vectorX;
            VectorF2D vectorY = _vectorY;

            if (reverseX && !reverseY) {
                reference = this.BottomRight;
                vectorX = _vectorX * -1;
            } else if (!reverseX && reverseY) {
                reference = this.TopLeft;
                vectorY = _vectorY * -1;
            } else if (reverseX && reverseY) {
                reference = this.TopRight;
                vectorX = _vectorX * -1;
                vectorY = _vectorY * -1;
            }

            LineF2D xLine = new LineF2D (point, point + vectorX, false);
            PointF2D yIntersection = xLine.Intersection (new LineF2D (reference, reference + vectorY)) as PointF2D;
            VectorF2D yIntersectionVector = (yIntersection - reference);
            double yFactor = yIntersectionVector.Size / vectorY.Size;
            if (!yIntersectionVector.CompareNormalized (vectorY, 0.0001)) {
                yFactor = -yFactor;
            }

            LineF2D yLine = new LineF2D (point, point + vectorY);
            PointF2D xIntersection = yLine.Intersection (new LineF2D (reference, reference + vectorX)) as PointF2D;
            VectorF2D xIntersectionVector = (xIntersection - reference);
            double xFactor = xIntersectionVector.Size / vectorX.Size;
            if (!xIntersectionVector.CompareNormalized (vectorX, 0.0001)) {
                xFactor = -xFactor;
            }

            transformed [0] = xFactor * width;
            transformed [1] = yFactor * height;
        }
Exemple #22
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!");
        }
        /// <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 #24
0
 /// <summary>
 /// Return true if the given line intersects with this line.
 /// </summary>
 /// <param name="line">Line.</param>
 public bool Intersects(LineF2D line)
 {
     return(this.Intersection(line) != null);
 }
Exemple #25
0
 /// <summary>
 /// Calculates and returns the line intersection.
 /// </summary>
 /// <param name="line"></param>
 /// <returns></returns>
 public PrimitiveF2D Intersection(LineF2D line)
 {
     return this.Intersection(line, true);
 }
Exemple #26
0
 /// <summary>
 /// Return true if the given line intersects with this line.
 /// </summary>
 /// <param name="line">Line.</param>
 /// <param name="doSegment"></param>
 public bool Intersects(LineF2D line, bool doSegment)
 {
     return(this.Intersection(line, doSegment) != null);
 }
Exemple #27
0
 /// <summary>
 /// Calculates and returns the line intersection.
 /// </summary>
 /// <param name="line"></param>
 /// <returns></returns>
 public PrimitiveF2D Intersection(LineF2D line)
 {
     return(this.Intersection(line, true));
 }
Exemple #28
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;
 }
Exemple #29
0
        /// <summary>
        /// Projects a point onto the given line.
        /// 
        /// (= intersection of the line with an angle 90° different from this line through the given point)
        /// </summary>
        /// <param name="point"></param>
        /// <returns>The projection point if it occurs inside the segmented line.</returns>
        public PointF2D ProjectOn(PointF2D point)
        {
            // get the direction.
            VectorF2D direction = this.Direction;

            // rotate.
            VectorF2D rotated = direction.Rotate90(true);

            // create second point
            PointF2D point2 = new PointF2D((point + rotated).ToArray());

            if (point[0] != point2[0] || point[1] != point2[1])
            {
                // create line.
                LineF2D line = new LineF2D(
                    point,
                    point2,
                    false,
                    false);

                // intersect.
                PrimitiveF2D primitive =
                    this.Intersection(line, true);

                if (primitive == null)
                {
                    return null;
                }
                else if (primitive is PointF2D)
                {
                    return primitive as PointF2D;
                }
                else
                {
                    throw new InvalidOperationException();
                }
            }
            else
            {
                return point2;
            }
        }
Exemple #30
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(double[] coordinate)
 {
     int number = 0;
     if (this.X[0] == coordinate[0] &&
         this.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 < this.X.Length - 1; idx++)
     {
         if (this.X[idx + 1] == coordinate[0] &&
             this.Y[idx + 1] == coordinate[1])
         { // the given point is one of the corners.
             return true;
         }
         bool idxRight = this.X[idx] > coordinate[0];
         bool idx1Right = this.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 ((this.Y[idx] <= coordinate[1] &&
                 this.Y[idx + 1] >= coordinate[1]) &&
                 !(this.Y[idx] == coordinate[1] &&
                 this.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(this.X[idx], this.Y[idx]),
                         new PointF2D(this.X[idx + 1], this.Y[idx + 1]));
                     if (localLine.PositionOfPoint(new PointF2D(coordinate)) == LinePointPosition.Left)
                     {
                         number++;
                     }
                 }
             }
             else if ((this.Y[idx] >= coordinate[1] &&
                 this.Y[idx + 1] <= coordinate[1]) &&
                 !(this.Y[idx] == coordinate[1] &&
                 this.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(this.X[idx], this.Y[idx]),
                         new PointF2D(this.X[idx + 1], this.Y[idx + 1]));
                     if (localLine.PositionOfPoint(new PointF2D(coordinate)) == LinePointPosition.Right)
                     {
                         number--;
                     }
                 }
             }
         }
     }
     return number != 0;
 }
Exemple #31
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 #32
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);
        }
Exemple #33
0
        /// <summary>
        /// Calculates and returns the line intersection.
        /// </summary>
        /// <param name="line"></param>
        /// <param name="doSegment"></param>
        /// <returns></returns>
        public PrimitiveF2D Intersection(LineF2D line, bool doSegment)
        {
            if (line == this)
            { // if the lines equal, the full lines intersect.
                return(line);
            }
            else if (line.A == this.A &&
                     line.B == this.B &&
                     line.C == this.C)
            { // if the lines equal in direction and position; return the smallest segment.
                KeyValuePair <double, PointF2D> point1 = new KeyValuePair <double, PointF2D>(
                    0, this.Point1);

                KeyValuePair <double, PointF2D> point2 = new KeyValuePair <double, PointF2D>(
                    this.Point1.Distance(this.Point2), this.Point2);

                // sort.
                KeyValuePair <double, PointF2D> temp;
                if (point2.Key < point1.Key)
                { // point2 smaller than point1.
                    temp   = point2;
                    point2 = point1;
                    point1 = temp;
                }

                KeyValuePair <double, PointF2D> point = new KeyValuePair <double, PointF2D>(
                    this.Point1.Distance(line.Point1), line.Point1);

                if (point.Key < point2.Key) // sort.
                {                           // point smaller than point2.
                    temp   = point;
                    point  = point2;
                    point2 = temp;
                }
                if (point2.Key < point1.Key)
                { // point2 smaller than point1.
                    temp   = point2;
                    point2 = point1;
                    point1 = temp;
                }

                point = new KeyValuePair <double, PointF2D>(
                    this.Point1.Distance(line.Point2), line.Point2);

                if (point.Key < point2.Key) // sort.
                {                           // point smaller than point2.
                    temp   = point;
                    point  = point2;
                    point2 = temp;
                }
                if (point2.Key < point1.Key)
                { // point2 smaller than point1.
                    temp   = point2;
                    point2 = point1;
                    point1 = temp;
                }

                // this line is a segment.
                if (doSegment && (this.IsSegment1 || this.IsSegment2))
                { // test where the intersection lies.
                    double this_distance =
                        this.Point1.Distance(this.Point2);
                    if (this.IsSegment)
                    { // if in any directions one of the points are further away from the point.
                        double this_distance_1 = System.Math.Min(this.Point1.Distance(point1.Value),
                                                                 this.Point1.Distance(point2.Value));
                        if (this_distance_1 > this_distance)
                        { // the point is further away.
                            return(null);
                        }
                    }
                    else if (this.IsSegment1)
                    { // if in any directions one of the points are further away from the point.
                        double this_distance_1 = this.Point1.Distance(point1.Value);
                        if (this_distance_1 > this_distance)
                        { // the point is further away.
                            return(null);
                        }
                    }
                    else if (this.IsSegment2)
                    { // if in any directions one of the points are further away from the point.
                        double this_distance_2 = this.Point2.Distance(point1.Value);
                        if (this_distance_2 > this_distance)
                        { // the point is further away.
                            return(null);
                        }
                    }
                }
                // other line is a segment.
                if (doSegment && (line.IsSegment1 || line.IsSegment2))
                { // test where the intersection lies.
                    double this_distance =
                        line.Point1.Distance(line.Point2);
                    if (line.IsSegment)
                    {// if in any directions one of the points are further away from the point.
                        double this_distance_1 = System.Math.Min(line.Point1.Distance(point1.Value),
                                                                 line.Point1.Distance(point2.Value));
                        if (this_distance_1 > this_distance)
                        { // the point is further away.
                            return(null);
                        }
                    }
                    else if (line.IsSegment1)
                    { // if in any directions one of the points are further away from the point.
                        double this_distance_1 = line.Point1.Distance(point1.Value);
                        if (this_distance_1 > this_distance)
                        { // the point is further away.
                            return(null);
                        }
                    }
                    else if (line.IsSegment2)
                    { // if in any directions one of the points are further away from the point.
                        double this_distance_2 = line.Point2.Distance(point2.Value);
                        if (this_distance_2 > this_distance)
                        { // the point is further away.
                            return(null);
                        }
                    }
                }
                return(new LineF2D(
                           point1.Value,
                           point2.Value,
                           true));
            }
            else
            {                 // line.A = A1, line.B = B1, line.C = C1, this.A = A2, this.B = B2, this.C = C2
                double det = (line.A * this.B - this.A * line.B);
                if (det == 0) // TODO: implement an accuracy threshold epsilon.
                {             // lines are parallel; no intersections.
                    return(null);
                }
                else
                { // lines are not the same and not parallel so they will intersect.
                    double x = (this.B * line.C - line.B * this.C) / det;
                    double y = (line.A * this.C - this.A * line.C) / det;

                    // create the point.
                    PointF2D point = new PointF2D(new double[] { x, y });

                    // this line is a segment.
                    if (doSegment && (this.IsSegment1 || this.IsSegment2))
                    { // test where the intersection lies.
                        double this_distance =
                            this.Point1.Distance(this.Point2);
                        if (this.IsSegment)
                        {// if in any directions one of the points are further away from the point.
                            double this_distance_1 = this.Point1.Distance(point);
                            if (this_distance_1 > this_distance)
                            { // the point is further away.
                                return(null);
                            }
                            double this_distance_2 = this.Point2.Distance(point);
                            if (this_distance_2 > this_distance)
                            { // the point is further away.
                                return(null);
                            }
                        }
                        else if (this.IsSegment1 && this.Point2.Distance(point) > this_distance)
                        { // only check this direction and only if the points lies far enough away from point2.
                            VectorF2D pointDirection = point - this.Point2;
                            VectorF2D point2ToPoint1 = this.Direction.Inverse;
                            if (pointDirection.CompareNormalized(point2ToPoint1, 0.001))
                            { // point lies in the direction of the segmented point1 and far away from point2
                                return(null);
                            }
                        }
                        else if (this.IsSegment1 && this.Point1.Distance(point) > this_distance)
                        { // only check this direction and only if the points lies far enough away from point1.
                            VectorF2D pointDirection = point - this.Point1;
                            VectorF2D point1ToPoint2 = this.Direction;
                            if (pointDirection.CompareNormalized(point1ToPoint2, 0.001))
                            { // point lies in the direction of the segmented point1 and far away from point2
                                return(null);
                            }
                        }
                    }
                    // line this is a segment.
                    if (doSegment && (line.IsSegment1 || line.IsSegment2))
                    { // test where the intersection lies.
                        double line_distance =
                            line.Point1.Distance(line.Point2);
                        if (line.IsSegment)
                        {// if in any directions one of the points are further away from the point.
                            double line_distance_1 = line.Point1.Distance(point);
                            if (line_distance_1 > line_distance)
                            { // the point is further away.
                                return(null);
                            }
                            double line_distance_2 = line.Point2.Distance(point);
                            if (line_distance_2 > line_distance)
                            { // the point is further away.
                                return(null);
                            }
                        }
                        else if (line.IsSegment1 && line.Point2.Distance(point) > line_distance)
                        { // only check line direction and only if the points lies far enough away from point2.
                            VectorF2D pointDirection = point - line.Point2;
                            VectorF2D point2ToPoint1 = line.Direction.Inverse;
                            if (pointDirection.CompareNormalized(point2ToPoint1, 0.001))
                            { // point lies in the direction of the segmented point1 and far away from point2
                                return(null);
                            }
                        }
                        else if (line.IsSegment1 && line.Point1.Distance(point) > line_distance)
                        { // only check line direction and only if the points lies far enough away from point1.
                            VectorF2D pointDirection = point - line.Point1;
                            VectorF2D point1ToPoint2 = line.Direction;
                            if (pointDirection.CompareNormalized(point1ToPoint2, 0.001))
                            { // point lies in the direction of the segmented point1 and far away from point2
                                return(null);
                            }
                        }
                    }

                    // the intersection is valid.
                    return(point);
                }
            }
        }
Exemple #34
0
 /// <summary>
 /// Returns true if the two points could potentially intersect this bounding box.
 ///
 /// This is a rudemantairy quick test to rule out intersection.
 ///     - If false is returned there can be no intersection.
 ///     - If true is returned there might be intersection but it is not certain.
 /// </summary>
 /// <param name="line"></param>
 /// <returns></returns>
 public bool IntersectsPotentially(LineF2D line)
 {
     return(this.IntersectsPotentially(line.Point1, line.Point2));
 }
Exemple #35
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));
        }
Exemple #36
0
        /// <summary>
        /// Returns all the intersections the line has with this polygon.
        /// </summary>
        /// <param name="line"></param>
        /// <returns></returns>
        public PointF2D[] Intersections(LineF2D line)
        {
            List<PointF2D> points = new List<PointF2D>();
            foreach (LineF2D polygon_line in this.LineEnumerator)
            {
                // calculate the intersection.
                PrimitiveF2D primitive = line.Intersection(polygon_line);

                // the primitive not null.
                if (primitive != null)
                {
                    if (primitive is LineF2D)
                    { // primitive is a line; convert.
                        LineF2D intersect_line =
                            (primitive as LineF2D);

                        // we are sure the line is a segment.
                        // if the line is not a segment this means that the polygon contains an line with infinite length; impossible.

                        // TODO: how to determine the order?
                        points.Add(intersect_line.Point1);
                        points.Add(intersect_line.Point2);
                    }
                    else if (primitive is PointF2D)
                    { // primitive is a point; convert.
                        PointF2D point = (primitive as PointF2D);
                        points.Add(point);
                    }
                }
            }

            return points.ToArray();
        }
Exemple #37
0
        public PrimitiveF2D Intersection(LineF2D line, bool doSegment)
        {
            if (line == this)
            {
                return((PrimitiveF2D)line);
            }
            if (line.A == this.A && line.B == this.B && line.C == this.C)
            {
                KeyValuePair <double, PointF2D> keyValuePair1 = new KeyValuePair <double, PointF2D>(0.0, this.Point1);
                KeyValuePair <double, PointF2D> keyValuePair2 = new KeyValuePair <double, PointF2D>(this.Point1.Distance(this.Point2), this.Point2);
                if (keyValuePair2.Key < keyValuePair1.Key)
                {
                    KeyValuePair <double, PointF2D> keyValuePair3 = keyValuePair2;
                    keyValuePair2 = keyValuePair1;
                    keyValuePair1 = keyValuePair3;
                }
                KeyValuePair <double, PointF2D> keyValuePair4 = new KeyValuePair <double, PointF2D>(this.Point1.Distance(line.Point1), line.Point1);
                if (keyValuePair4.Key < keyValuePair2.Key)
                {
                    KeyValuePair <double, PointF2D> keyValuePair3 = keyValuePair4;
                    keyValuePair4 = keyValuePair2;
                    keyValuePair2 = keyValuePair3;
                }
                if (keyValuePair2.Key < keyValuePair1.Key)
                {
                    KeyValuePair <double, PointF2D> keyValuePair3 = keyValuePair2;
                    keyValuePair2 = keyValuePair1;
                    keyValuePair1 = keyValuePair3;
                }
                keyValuePair4 = new KeyValuePair <double, PointF2D>(this.Point1.Distance(line.Point2), line.Point2);
                if (keyValuePair4.Key < keyValuePair2.Key)
                {
                    KeyValuePair <double, PointF2D> keyValuePair3 = keyValuePair4;
                    keyValuePair4 = keyValuePair2;
                    keyValuePair2 = keyValuePair3;
                }
                if (keyValuePair2.Key < keyValuePair1.Key)
                {
                    KeyValuePair <double, PointF2D> keyValuePair3 = keyValuePair2;
                    keyValuePair2 = keyValuePair1;
                    keyValuePair1 = keyValuePair3;
                }
                if (doSegment && (this.IsSegment1 || this.IsSegment2))
                {
                    double num = this.Point1.Distance(this.Point2);
                    if (this.IsSegment)
                    {
                        if (System.Math.Min(this.Point1.Distance(keyValuePair1.Value), this.Point1.Distance(keyValuePair2.Value)) > num)
                        {
                            return((PrimitiveF2D)null);
                        }
                    }
                    else if (this.IsSegment1)
                    {
                        if (this.Point1.Distance(keyValuePair1.Value) > num)
                        {
                            return((PrimitiveF2D)null);
                        }
                    }
                    else if (this.IsSegment2 && this.Point2.Distance(keyValuePair1.Value) > num)
                    {
                        return((PrimitiveF2D)null);
                    }
                }
                if (doSegment && (line.IsSegment1 || line.IsSegment2))
                {
                    double num = line.Point1.Distance(line.Point2);
                    if (line.IsSegment)
                    {
                        if (System.Math.Min(line.Point1.Distance(keyValuePair1.Value), line.Point1.Distance(keyValuePair2.Value)) > num)
                        {
                            return((PrimitiveF2D)null);
                        }
                    }
                    else if (line.IsSegment1)
                    {
                        if (line.Point1.Distance(keyValuePair1.Value) > num)
                        {
                            return((PrimitiveF2D)null);
                        }
                    }
                    else if (line.IsSegment2 && line.Point2.Distance(keyValuePair2.Value) > num)
                    {
                        return((PrimitiveF2D)null);
                    }
                }
                return((PrimitiveF2D) new LineF2D(keyValuePair1.Value, keyValuePair2.Value, true));
            }
            double num1 = line.A * this.B - this.A * line.B;

            if (num1 == 0.0)
            {
                return((PrimitiveF2D)null);
            }
            PointF2D p = new PointF2D(new double[2]
            {
                (this.B * line.C - line.B * this.C) / num1,
                (line.A * this.C - this.A * line.C) / num1
            });

            if (doSegment && (this.IsSegment1 || this.IsSegment2))
            {
                double num2 = this.Point1.Distance(this.Point2);
                if (this.IsSegment)
                {
                    if (this.Point1.Distance(p) > num2)
                    {
                        return((PrimitiveF2D)null);
                    }
                    if (this.Point2.Distance(p) > num2)
                    {
                        return((PrimitiveF2D)null);
                    }
                }
                else if (this.IsSegment1 && this.Point2.Distance(p) > num2)
                {
                    if ((p - this.Point2).CompareNormalized(this.Direction.Inverse, 0.001))
                    {
                        return((PrimitiveF2D)null);
                    }
                }
                else if (this.IsSegment1 && this.Point1.Distance(p) > num2 && (p - this.Point1).CompareNormalized(this.Direction, 0.001))
                {
                    return((PrimitiveF2D)null);
                }
            }
            if (doSegment && (line.IsSegment1 || line.IsSegment2))
            {
                double num2 = line.Point1.Distance(line.Point2);
                if (line.IsSegment)
                {
                    if (line.Point1.Distance(p) > num2)
                    {
                        return((PrimitiveF2D)null);
                    }
                    if (line.Point2.Distance(p) > num2)
                    {
                        return((PrimitiveF2D)null);
                    }
                }
                else if (line.IsSegment1 && line.Point2.Distance(p) > num2)
                {
                    if ((p - line.Point2).CompareNormalized(line.Direction.Inverse, 0.001))
                    {
                        return((PrimitiveF2D)null);
                    }
                }
                else if (line.IsSegment1 && line.Point1.Distance(p) > num2 && (p - line.Point1).CompareNormalized(line.Direction, 0.001))
                {
                    return((PrimitiveF2D)null);
                }
            }
            return((PrimitiveF2D)p);
        }