Esempio n. 1
0
        private double?offsetX; // Not for horizontals

        private Line(double?slope, ICartesianCoordinate point)
        {
            this.slope = slope;

            offsetX = slope.HasValue ? (slope.Value.Equals(0.0) ? (double?)null : point.X - point.Y / slope.Value) : point.X;
            offsetY = slope.HasValue ? point.Y - slope.Value * point.X : (double?)null;
        }
Esempio n. 2
0
        //public static bool IsPointInsideRing_WindingNumber(IEnumerable<ICartesianCoordinate> ring, ICartesianCoordinate point)
        //{

        //    //var boundingRectangle = GetBoundingRectangle(ring);

        //    //// obvious cases
        //    //if (point.X < boundingRectangle.LowerLeft.X || point.X > boundingRectangle.UpperRight.X)
        //    //    return false;

        //    //if (point.Y < boundingRectangle.LowerLeft.Y || point.Y > boundingRectangle.UpperRight.Y)
        //    //    return false;



        //    int windingNumberCount = 0;    // the  winding number counter

        //    var ringwalker = new RingWalker(ring);

        //    foreach(var pointInRing in ringwalker)
        //    {
        //        if (pointInRing.curr.Equals(point))
        //            return true;

        //        if (pointInRing.prev.Y <= point.Y)
        //        {          // start y <= P.y
        //            if (pointInRing.curr.Y > point.Y &&      // an upward crossing
        //                !new Triangle(pointInRing.prev, pointInRing.curr, point).RightOrientation())  // P left of  edge
        //                    ++windingNumberCount;            // have  a valid up intersect
        //        }
        //        else
        //        {                        // start y > P.y (no test needed)
        //            if (pointInRing.curr.Y <= point.Y &&     // a downward crossing
        //                 new Triangle(pointInRing.prev, pointInRing.curr, point).RightOrientation())  // P right of  edge
        //                    --windingNumberCount;            // have  a valid down intersect
        //        }
        //    }
        //    return windingNumberCount != 0;
        //}

        // Winding ring algoritm with few extensions and optimalizations. Very fast.
        // Bounding rectangle can be used in combination with intelligent polygon but otherwise too time consuming.
        // Other optimalizations still possible. Same remark. Ex. Monotone polygons etc...
        public static bool IsPointInsideRing(IList <ICartesianCoordinate> ring, ICartesianCoordinate point /*, bool includeBorder = true*/)
        {
            bool       flipflop      = false;
            const bool includeBorder = true; // Algoritm could be parameterized to optionally include the border.

            for (int i = 0, j = ring.Count - 1; i < ring.Count; j = i++)
            {
                if (ring[j].Equals(point))
                {
                    return(includeBorder);
                }

                bool b = ring[i].Y <= point.Y;
                if (b != (ring[j].Y <= point.Y))
                {
                    var triangularOrientation = (ring[j].X - ring[i].X) * (point.Y - ring[i].Y) - (ring[j].Y - ring[i].Y) * (point.X - ring[i].X);
                    //var triangularOrientation = new Triangle(ring[i], ring[j], point).Orientation();
                    if (triangularOrientation > 0 && b || triangularOrientation < 0 && !b)
                    {
                        flipflop = !flipflop;
                    }
                    else if (triangularOrientation == 0)
                    {
                        return(includeBorder);
                    }
                }
            }
            return(flipflop);
        }
Esempio n. 3
0
        private double? offsetX; // Not for horizontals

        private Line(double? slope, ICartesianCoordinate point)
        {
            this.slope = slope;

            offsetX = slope.HasValue ? (slope.Value.Equals(0.0) ? (double?) null : point.X - point.Y / slope.Value) : point.X;
            offsetY = slope.HasValue ? point.Y - slope.Value * point.X : (double?)null;
        }
Esempio n. 4
0
        public float StackPoint(ICartesianCoordinate point, int seriesStackPosition)
        {
            var start = seriesStackPosition == 0 ? 0 : stack[seriesStackPosition - 1][point.Index].End;
            var value = direction == SeriesDirection.Horizontal ? point.X : point.Y;

            var si = stack[seriesStackPosition];

            if (si.Count < point.Index + 1)
            {
                si.Add(new StackedValue {
                    Start = start, End = start + value
                });
                totals.Add(value);
                knownMaxLenght++;
            }
            else
            {
                si[point.Index] = new StackedValue {
                    Start = start, End = start + value
                };
            }

            var total = totals[point.Index] + value;

            totals[point.Index] = total;

            return(total);
        }
Esempio n. 5
0
        public static double DistanceSquared(ICartesianCoordinate p1, ICartesianCoordinate p2)
        {
            var diffX = p2.X - p1.X;
            var diffY = p2.Y - p1.Y;

            return(diffX * diffX + diffY * diffY);
        }
Esempio n. 6
0
        public StackedValue GetStack(int seriesStackPosition, ICartesianCoordinate point)
        {
            var p = stack[seriesStackPosition][point.Index];

            return(new StackedValue
            {
                Start = p.Start,
                End = p.End
            });
        }
Esempio n. 7
0
        //public static bool IsRectangleInsideRing(ICartesianCoordinate[] ring, IRectangle rectangle)
        //{
        //    return (IsPointInsideRing(ring, rectangle.UpperLeft) &&
        //        IsPointInsideRing(ring, rectangle.UpperRight) &&
        //        IsPointInsideRing(ring, rectangle.LowerLeft) &&
        //        IsPointInsideRing(ring, rectangle.LowerRight));
        //}

        public static bool IsPerpendicular(ICartesianCoordinate pointA, ICartesianCoordinate pointB, ICartesianCoordinate pointC, ICartesianCoordinate pointD)
        {
            if (pointB.Y.Equals(pointA.Y) && pointD.X.Equals(pointC.X) || pointB.X.Equals(pointA.X) && pointD.Y.Equals(pointC.Y))
            {
                return(true);
            }

            var rico1 = (pointB.Y - pointA.Y) / (pointB.X - pointA.X);
            var rico2 = (pointD.Y - pointC.Y) / (pointD.X - pointC.X);

            return(rico1 * rico2 == -1);
        }
Esempio n. 8
0
        // Monotone Chain algoritm by Andrew 1979
        public ICartesianCoordinate[] Algorithm(IEnumerable <ICartesianCoordinate> pointcloud)
        {
            var pointcloudArray = pointcloud.ToArray();

            if (pointcloudArray.Length > 1)
            {
                var hull = new ICartesianCoordinate[2 * pointcloudArray.Length];

                Array.Sort(pointcloudArray, new PointComparerForMonotoneChainAlgorithm());

                int k = 0;

                // Lower hull
                for (int i = 0; i < pointcloudArray.Length; i++)
                {
                    while (k >= 2 && GoniometryAlgorithms.CrossProduct(hull[k - 2], hull[k - 1], pointcloudArray[i]) <= 0)
                    {
                        k--;
                    }
                    hull[k++] = pointcloudArray[i];
                }

                // Upper hull
                for (int i = pointcloudArray.Length - 2, t = k + 1; i >= 0; i--)
                {
                    while (k >= t && GoniometryAlgorithms.CrossProduct(hull[k - 2], hull[k - 1], pointcloudArray[i]) <= 0)
                    {
                        k--;
                    }
                    hull[k++] = pointcloudArray[i];
                }

                Array.Resize(ref hull, k - 1);

                return(hull);
            }
            else if (pointcloudArray.Length <= 1)
            {
                return(pointcloudArray);
            }
            else
            {
                return(null);
            }
        }
Esempio n. 9
0
        public static Line CreateFromTwoPoints(ICartesianCoordinate pointA, ICartesianCoordinate pointB)
        {
            double?slope = pointB.X.Equals(pointA.X) ? (double?)null : (pointB.Y - pointA.Y) / (pointB.X - pointA.X);

            return(new Line(slope, pointA));
        }
Esempio n. 10
0
 public static Line CreateHorizontalThroughPoint(ICartesianCoordinate point)
 {
     return new Line(0.0, point);
 }
Esempio n. 11
0
 public static Line CreateFromSlopeAndPoint(double slope, ICartesianCoordinate point)
 {
     return new Line(slope, point);
 }
Esempio n. 12
0
        public static Line CreateFromTwoPoints(ICartesianCoordinate pointA, ICartesianCoordinate pointB)
        {
            double? slope = pointB.X.Equals(pointA.X) ? (double?)null : (pointB.Y - pointA.Y) / (pointB.X - pointA.X);

            return new Line(slope, pointA);
        }
Esempio n. 13
0
 public static Line CreateVerticalThroughPoint(ICartesianCoordinate point)
 {
     return new Line(null, point);
 }
Esempio n. 14
0
 public bool Equals(ICartesianCoordinate other)
 {
     return X.Equals(other.X) && Y.Equals(other.Y);
 }
Esempio n. 15
0
        //public static bool Contains(IList<GeoCoordinate> Coordinates, GeoCoordinate coordinate)
        //{
        //    bool flipflop = false;
        //    const bool includeBorder = true; // Algoritm could be parameterized to optionally include the border.

        //    for (int i = 0, j = Coordinates.Count - 1; i < Coordinates.Count; j = i++)
        //    {
        //        if (Coordinates[j].Equals(coordinate))
        //            return includeBorder;

        //        bool b = Coordinates[i].Latitude <= coordinate.Latitude;
        //        if (b != (Coordinates[j].Latitude <= coordinate.Latitude))
        //        {
        //            var triangularOrientation = (Coordinates[j].Longitude - Coordinates[i].Longitude) * (coordinate.Latitude - Coordinates[i].Latitude) - (Coordinates[j].Latitude - Coordinates[i].Latitude) * (coordinate.Longitude - Coordinates[i].Longitude);
        //            if (triangularOrientation > 0 && b || triangularOrientation < 0 && !b)
        //                flipflop = !flipflop;
        //            else if (triangularOrientation == 0)
        //                return includeBorder;
        //        }
        //    }
        //    return flipflop;
        //}


        //public static bool Contains2(IList<PointF2D> Coordinates, GeoCoordinate coordinate)
        //{
        //    bool flipflop = false;
        //    const bool includeBorder = true; // Algoritm could be parameterized to optionally include the border.

        //    for (int i = 0, j = Coordinates.Count - 1; i < Coordinates.Count; j = i++)
        //    {
        //        if (Coordinates[j].Equals(coordinate))
        //            return includeBorder;

        //        bool b = Coordinates[i][1] <= coordinate.Latitude;
        //        if (b != (Coordinates[j][1] <= coordinate.Latitude))
        //        {
        //            var triangularOrientation = (Coordinates[j][0] - Coordinates[i][0]) * (coordinate.Latitude - Coordinates[i][1]) - (Coordinates[j][1] - Coordinates[i][1]) * (coordinate.Longitude - Coordinates[i][0]);
        //            if (triangularOrientation > 0 && b || triangularOrientation < 0 && !b)
        //                flipflop = !flipflop;
        //            else if (triangularOrientation == 0)
        //                return includeBorder;
        //        }
        //    }
        //    return flipflop;
        //}


        public static bool IsLineSegmentInsideRing(IList <ICartesianCoordinate> ring, ICartesianCoordinate pointA, ICartesianCoordinate pointB, bool includeBorder = true)
        {
            for (int i = 0; i < ring.Count - 1; i++)
            {
                var test1 = new Triangle(ring[i], ring[i + 1], pointA).Orientation() * new Triangle(ring[i], ring[i + 1], pointB).Orientation();
                var test2 = new Triangle(pointA, pointB, ring[i]).Orientation() * new Triangle(pointA, pointB, ring[i + 1]).Orientation();
                if ((test1 <= 0) && (test2 <= 0))
                {
                    return(false);
                }
            }

            return(IsPointInsideRing(ring, pointA /*, includeBorder*/) && IsPointInsideRing(ring, pointB /*, includeBorder*/));
        }
Esempio n. 16
0
 public static Line CreateHorizontalThroughPoint(ICartesianCoordinate point)
 {
     return(new Line(0.0, point));
 }
Esempio n. 17
0
 public static Line CreateFromSlopeAndPoint(double slope, ICartesianCoordinate point)
 {
     return(new Line(slope, point));
 }
Esempio n. 18
0
        //// TODO check gedoe met includeborder
        //public static bool IsPointInsideConvexRing(IEnumerable<ICartesianCoordinate> convexRing, ICartesianCoordinate point, bool includeBorder = true)
        //{
        //    //var boundingRectangle = GetBoundingRectangle(convexRing);

        //    //// obvious cases
        //    //if (point.X < boundingRectangle.LowerLeft.X || point.X > boundingRectangle.UpperRight.X)
        //    //    return false;

        //    //if (point.Y < boundingRectangle.LowerLeft.Y || point.Y > boundingRectangle.UpperRight.Y)
        //    //    return false;

        //    foreach (var coordinate in new RingWalker(convexRing)) // .Skip(1).Union(new [] { prev}))
        //    {
        //        var t = new Triangle(coordinate.prevprev, coordinate.prev, point);

        //        var isOnBorder = t.IsFlattened();

        //        // TODO optimaliseer deze ifs
        //        if ((!point.Equals(coordinate.prevprev) || !includeBorder) && (!point.Equals(coordinate) || !includeBorder) && !t.RightOrientation() && (!isOnBorder || !includeBorder))
        //            return false;
        //    }
        //    return true;
        //}

        //public static bool IsPointInsideRing_Trivial(IEnumerable<ICartesianCoordinate> ring, ICartesianCoordinate point)
        //{
        //    var convexring = new RingWalker(ring).Where(t => new Triangle(t.prevprev, t.prev, t.curr).RightOrientation());
        //    var concavePoints = new RingWalker(ring).Where(t => !new Triangle(t.prevprev, t.prev, t.curr).RightOrientation());

        //    if (IsPointInsideConvexRing(convexring.Select(t => t.prev), point))
        //    {
        //        foreach(var concavePoint in concavePoints)
        //        {
        //            if (IsPointInsideConvexRing(new[] {concavePoint.prevprev, concavePoint.curr, concavePoint.prev}, point, false))
        //                return false;
        //        }
        //        return true;
        //    }

        //    return false;
        //}
        public static double CrossProduct(ICartesianCoordinate origin, ICartesianCoordinate P1, ICartesianCoordinate P2)
        {
            return((P1.X - origin.X) * (P2.Y - origin.Y) - (P2.X - origin.X) * (P1.Y - origin.Y));
        }
Esempio n. 19
0
 public bool Equals(ICartesianCoordinate other)
 {
     return(X.Equals(other.X) && Y.Equals(other.Y));
 }
Esempio n. 20
0
 public Triangle(ICartesianCoordinate point1, ICartesianCoordinate point2, ICartesianCoordinate point3)
 {
     this.point1 = point1;
     this.point2 = point2;
     this.point3 = point3;
 }
Esempio n. 21
0
 public Triangle(ICartesianCoordinate point1, ICartesianCoordinate point2, ICartesianCoordinate point3)
 {
     this.point1 = point1;
     this.point2 = point2;
     this.point3 = point3;
 }
Esempio n. 22
0
 public static GDIPoint ToGDI(this ICartesianCoordinate coordinate)
 {
     return(new GDIPoint(Convert.ToInt32(coordinate.X), Convert.ToInt32(coordinate.Y)));
 }
Esempio n. 23
0
 public static Line CreateVerticalThroughPoint(ICartesianCoordinate point)
 {
     return(new Line(null, point));
 }
Esempio n. 24
0
 public static double DistanceSquared(ICartesianCoordinate p1, ICartesianCoordinate p2)
 {
     var diffX = p2.X - p1.X;
     var diffY = p2.Y - p1.Y;
     return diffX * diffX + diffY * diffY;
 }