Пример #1
0
 public List<int> GetIndices(ref RectangleD rect)
 {
     if (rootNode.Bounds.IntersectsWith(rect))
     {
         List<int> indices = new List<int>();
         Dictionary<int, int> duplicates = new Dictionary<int, int>();
         rootNode.GetIndices(ref rect, indices, duplicates);
         return indices;
     } 
     return null;
 }
Пример #2
0
 internal void GetIndices(ref RectangleD rect, List <int> indices, System.Collections.Generic.Dictionary <int, int> foundIndicies)
 {
     if (children != null)
     {
         //check each child bounds
         if (children[TL].Bounds.IntersectsWith(rect))
         {
             children[TL].GetIndices(ref rect, indices, foundIndicies);
         }
         if (children[TR].Bounds.IntersectsWith(rect))
         {
             children[TR].GetIndices(ref rect, indices, foundIndicies);
         }
         if (children[BL].Bounds.IntersectsWith(rect))
         {
             children[BL].GetIndices(ref rect, indices, foundIndicies);
         }
         if (children[BR].Bounds.IntersectsWith(rect))
         {
             children[BR].GetIndices(ref rect, indices, foundIndicies);
         }
     }
     else
     {
         if (indexList != null)
         {
             //assumes already checked node's Bounds intersect rect
             //add the node'x indices, checking if it has already been added
             //We need to check for duplicates as a shape may intersect more than 1 node
             for (int n = indexList.Count - 1; n >= 0; --n)
             {
                 if (!foundIndicies.ContainsKey(indexList[n]))
                 {
                     indices.Add(indexList[n]);
                     foundIndicies.Add(indexList[n], 0);
                 }
             }
         }
     }
 }
Пример #3
0
 public void Insert(int recordIndex, QTNodeHelper helper, System.IO.Stream shapeFileStream)
 {
     if (helper.IsPointData())
     {
         rootNode.Insert(recordIndex, helper, shapeFileStream);
     }
     else
     {
         RectangleD recBounds = helper.GetRecordBoundsD(recordIndex, shapeFileStream);
         //check for zero width or height to avoid issue when checking rectangle intersection
         //if width/height is zero
         if (recBounds.Width < 0.0000001)
         {
             recBounds.Width = 0.0000001;
         }
         if (recBounds.Height < 0.0000001)
         {
             recBounds.Height = 0.0000001;
         }
         rootNode.Insert(recordIndex, helper, ref recBounds, shapeFileStream);
     }
 }
Пример #4
0
        public void Insert(int recordIndex, QTNodeHelper helper, System.IO.Stream shapeFileStream)
        {
            if (Level == MaxLevels)
            {
                indexList.Add(recordIndex);
            }
            else
            {
                if (helper.IsPointData())
                {
                    PointD pt = helper.GetRecordPoint(recordIndex, shapeFileStream);

                    if (children == null)
                    {
                        CreateChildren();
                    }

                    if (children[TL].Bounds.Contains(pt))
                    {
                        children[TL].Insert(recordIndex, helper, shapeFileStream);
                    }
                    if (children[TR].Bounds.Contains(pt))
                    {
                        children[TR].Insert(recordIndex, helper, shapeFileStream);
                    }
                    if (children[BL].Bounds.Contains(pt))
                    {
                        children[BL].Insert(recordIndex, helper, shapeFileStream);
                    }
                    if (children[BR].Bounds.Contains(pt))
                    {
                        children[BR].Insert(recordIndex, helper, shapeFileStream);
                    }
                    //else
                    //{
                    //    throw new InvalidOperationException("point " + pt + " is not contained in children bounds");
                    //}
                }
                else
                {
                    RectangleD recBounds = helper.GetRecordBoundsD(recordIndex, shapeFileStream);

                    if (children == null)
                    {
                        CreateChildren();
                    }
                    int c = 0;
                    if (children[TL].Bounds.IntersectsWith(recBounds))
                    {
                        c++;
                        children[TL].Insert(recordIndex, helper, shapeFileStream);
                    }
                    if (children[TR].Bounds.IntersectsWith(recBounds))
                    {
                        c++;
                        children[TR].Insert(recordIndex, helper, shapeFileStream);
                    }
                    if (children[BL].Bounds.IntersectsWith(recBounds))
                    {
                        c++;
                        children[BL].Insert(recordIndex, helper, shapeFileStream);
                    }
                    if (children[BR].Bounds.IntersectsWith(recBounds))
                    {
                        c++;
                        children[BR].Insert(recordIndex, helper, shapeFileStream);
                    }
                }
            }
        }
Пример #5
0
        public static RectangleD Transform(this EGIS.Projections.ICoordinateTransformation @this, RectangleD rect, Projections.TransformDirection direction = Projections.TransformDirection.Forward)
        {
            //following code was derived from code in QGIS TransformBoundingBox function in QgsCoordinateTransform
            //improves calculated bounding box after transforming to a different CRS when
            //only using the corners of the rectangle will not give an accurate result when transforming to some CRS.
            //This method creates a grid of points over the input rectangle,
            //transforms these points and then calculates the target bounding box from these points.

            const int nPoints  = 1000;
            double    t        = Math.Pow(Math.Sqrt((double)nPoints) - 1, 2.0);
            double    d        = Math.Sqrt((rect.Width * rect.Height) / Math.Pow(Math.Sqrt((double)nPoints) - 1, 2.0));
            int       nXPoints = (int)Math.Min(Math.Ceiling(rect.Width / d) + 1, 1000);
            int       nYPoints = (int)Math.Min(Math.Ceiling(rect.Height / d) + 1, 1000);

            int totalPoints = (nXPoints * nYPoints);

            PointD[] pts = new PointD[totalPoints];

            double dx = rect.Width / (double)(nXPoints - 1);
            double dy = rect.Height / (double)(nYPoints - 1);

            double pointY = rect.Top;
            int    index  = 0;

            for (int i = nYPoints; i > 0; --i)
            {
                double pointX = rect.Left;
                for (int j = nXPoints; j > 0; --j)
                {
                    pts[index].X   = pointX;
                    pts[index++].Y = pointY;
                    pointX        += dx;
                }
                pointY += dy;
            }
            @this.Transform(pts, direction);
            double minX = double.PositiveInfinity, maxX = double.NegativeInfinity, minY = double.PositiveInfinity, maxY = double.NegativeInfinity;

            for (int n = totalPoints - 1; n >= 0; --n)
            {
                if (double.IsInfinity(pts[n].X) || double.IsInfinity(pts[n].Y))
                {
                    continue;
                }
                minX = Math.Min(pts[n].X, minX);
                minY = Math.Min(pts[n].Y, minY);
                maxX = Math.Max(pts[n].X, maxX);
                maxY = Math.Max(pts[n].Y, maxY);
            }
            return(RectangleD.FromLTRB(minX, minY, maxX, maxY));
        }
Пример #6
0
 public static RectangleD Transform(this RectangleD @this, ICoordinateTransformation transformation)
 {
     return(transformation.Transform(@this));
 }
Пример #7
0
 static RectangleD()
 {
     Empty = new RectangleD();
 }
Пример #8
0
 /// <summary>Creates the smallest possible third rectangle that can contain both of two rectangles that form a union.</summary>
 /// <returns>A third <see cref="T:System.Drawing.RectangleD"></see> structure that contains both of the two rectangles that form the union.</returns>
 /// <param name="a">A rectangle to union. </param>
 /// <param name="b">A rectangle to union. </param>
 /// <filterpriority>1</filterpriority>
 public static RectangleD Union(RectangleD a, RectangleD b)
 {
     double x = Math.Min(a.X, b.X);
     double num2 = Math.Max((double)(a.X + a.Width), (double)(b.X + b.Width));
     double y = Math.Min(a.Y, b.Y);
     double num4 = Math.Max((double)(a.Y + a.Height), (double)(b.Y + b.Height));
     return new RectangleD(x, y, num2 - x, num4 - y);
 }
Пример #9
0
 /// <summary>Determines if the rectangular region represented by rect is entirely contained within this <see cref="T:System.Drawing.RectangleD"></see> structure.</summary>
 /// <returns>This method returns true if the rectangular region represented by rect is entirely contained within the rectangular region represented by this <see cref="T:System.Drawing.RectangleD"></see>; otherwise false.</returns>
 /// <param name="rect">The <see cref="T:System.Drawing.RectangleD"></see> to test. </param>
 /// <filterpriority>1</filterpriority>
 public bool Contains(RectangleD rect)
 {
     return((((this.X <= rect.X) && ((rect.X + rect.Width) <= (this.X + this.Width))) && (this.Y <= rect.Y)) && ((rect.Y + rect.Height) <= (this.Y + this.Height)));
 }
Пример #10
0
 /// <summary>Replaces this <see cref="T:System.Drawing.RectangleD"></see> structure with the intersection of itself and the specified <see cref="T:System.Drawing.RectangleD"></see> structure.</summary>
 /// <returns>This method does not return a value.</returns>
 /// <param name="rect">The rectangle to intersect. </param>
 /// <filterpriority>1</filterpriority>
 public void Intersect(RectangleD rect)
 {
     RectangleD ef = Intersect(rect, this);
     this.X = ef.X;
     this.Y = ef.Y;
     this.Width = ef.Width;
     this.Height = ef.Height;
 }
Пример #11
0
 /// <summary>Creates and returns an inflated copy of the specified <see cref="T:System.Drawing.RectangleD"></see> structure. The copy is inflated by the specified amount. The original rectangle remains unmodified.</summary>
 /// <returns>The inflated <see cref="T:System.Drawing.RectangleD"></see>.</returns>
 /// <param name="rect">The <see cref="T:System.Drawing.RectangleD"></see> to be copied. This rectangle is not modified. </param>
 /// <param name="y">The amount to inflate the copy of the rectangle vertically. </param>
 /// <param name="x">The amount to inflate the copy of the rectangle horizontally. </param>
 /// <filterpriority>1</filterpriority>
 public static RectangleD Inflate(RectangleD rect, double x, double y)
 {
     RectangleD ef = rect;
     ef.Inflate(x, y);
     return ef;
 }
Пример #12
0
 /// <summary>Determines if the rectangular region represented by rect is entirely contained within this <see cref="T:System.Drawing.RectangleD"></see> structure.</summary>
 /// <returns>This method returns true if the rectangular region represented by rect is entirely contained within the rectangular region represented by this <see cref="T:System.Drawing.RectangleD"></see>; otherwise false.</returns>
 /// <param name="rect">The <see cref="T:System.Drawing.RectangleD"></see> to test. </param>
 /// <filterpriority>1</filterpriority>
 public bool Contains(RectangleD rect)
 {
     return ((((this.X <= rect.X) && ((rect.X + rect.Width) <= (this.X + this.Width))) && (this.Y <= rect.Y)) && ((rect.Y + rect.Height) <= (this.Y + this.Height)));
 }
Пример #13
0
        internal void GetIndices(ref RectangleD rect, List<int> indices, System.Collections.Generic.Dictionary<int, int> foundIndicies)
        {
            if (children != null)
            {
                //check each child bounds
                if (children[TL].Bounds.IntersectsWith(rect))
                {
                    children[TL].GetIndices(ref rect, indices, foundIndicies);
                }
                if (children[TR].Bounds.IntersectsWith(rect))
                {
                    children[TR].GetIndices(ref rect, indices, foundIndicies);
                }
                if (children[BL].Bounds.IntersectsWith(rect))
                {
                    children[BL].GetIndices(ref rect, indices, foundIndicies);
                }
                if (children[BR].Bounds.IntersectsWith(rect))
                {
                    children[BR].GetIndices(ref rect, indices, foundIndicies);
                }                
            }
            else
            {
                if (indexList != null)
                {
                    //assumes already checked node's Bounds intersect rect
                    //add the node'x indices, checking if it has already been added
                    //We need to check for duplicates as a shape may intersect more than 1 node
                    for (int n = indexList.Count - 1; n >= 0; --n)
                    {
                        if (!foundIndicies.ContainsKey(indexList[n]))
                        {
                            indices.Add(indexList[n]);
                            foundIndicies.Add(indexList[n], 0);
                        }
                    }
                }
            }

        }
Пример #14
0
 static RectangleD()
 {
     Empty = new RectangleD();
 }
Пример #15
0
 /// <summary>Determines if this rectangle intersects with rect.</summary>
 /// <returns>This method returns true if there is any intersection.</returns>
 /// <param name="rect">The rectangle to test. </param>
 /// <filterpriority>1</filterpriority>
 public bool IntersectsWith(RectangleD rect)
 {
     return((((rect.X < (this.X + this.Width)) && (this.X < (rect.X + rect.Width))) && (rect.Y < (this.Y + this.Height))) && (this.Y < (rect.Y + rect.Height)));
 }
Пример #16
0
 /// <summary>Returns a <see cref="T:System.Drawing.RectangleD"></see> structure that represents the intersection of two rectangles. If there is no intersection, and empty <see cref="T:System.Drawing.RectangleD"></see> is returned.</summary>
 /// <returns>A third <see cref="T:System.Drawing.RectangleD"></see> structure the size of which represents the overlapped area of the two specified rectangles.</returns>
 /// <param name="a">A rectangle to intersect. </param>
 /// <param name="b">A rectangle to intersect. </param>
 /// <filterpriority>1</filterpriority>
 public static RectangleD Intersect(RectangleD a, RectangleD b)
 {
     double x = Math.Max(a.X, b.X);
     double num2 = Math.Min((double)(a.X + a.Width), (double)(b.X + b.Width));
     double y = Math.Max(a.Y, b.Y);
     double num4 = Math.Min((double)(a.Y + a.Height), (double)(b.Y + b.Height));
     if ((num2 >= x) && (num4 >= y))
     {
         return new RectangleD(x, y, num2 - x, num4 - y);
     }
     return Empty;
 }
Пример #17
0
 public QuadTree(RectangleD bounds)
 {
     rootNode = new QTNode(bounds, 0);
 }
Пример #18
0
 /// <summary>Determines if this rectangle intersects with rect.</summary>
 /// <returns>This method returns true if there is any intersection.</returns>
 /// <param name="rect">The rectangle to test. </param>
 /// <filterpriority>1</filterpriority>
 public bool IntersectsWith(RectangleD rect)
 {
     return ((((rect.X < (this.X + this.Width)) && (this.X < (rect.X + rect.Width))) && (rect.Y < (this.Y + this.Height))) && (this.Y < (rect.Y + rect.Height)));
 }
Пример #19
0
 public static RectangleD Transform(this EGIS.Projections.ICoordinateTransformation @this, RectangleD rect, Projections.TransformDirection direction = Projections.TransformDirection.Forward)
 {
     double[] pts = new double[8];
     pts[0] = rect.Left; pts[1] = rect.Bottom;
     pts[2] = rect.Right; pts[3] = rect.Bottom;
     pts[4] = rect.Right; pts[5] = rect.Top;
     pts[6] = rect.Left; pts[7] = rect.Top;
     @this.Transform(pts, 4, direction);
     return(RectangleD.FromLTRB(Math.Min(pts[0], pts[6]),
                                Math.Min(pts[5], pts[7]), Math.Max(pts[2], pts[4]),
                                Math.Max(pts[1], pts[3])));
 }
Пример #20
0
        /// <summary>        
        /// </summary>
        /// <param name="r"></param>
        /// <param name="centre"></param>
        /// <param name="radius"></param>
        /// <returns></returns>
        /// <remarks>This method is untested</remarks>
        public static bool RectangleCircleIntersects(ref RectangleD r, ref PointD centre, double radius)
        {
            //following code obtained from http://stackoverflow.com/questions/401847/circle-rectangle-collision-detection-intersection

            // clamp(value, min, max) - limits value to the range min..max

            // Find the closest point to the circle within the rectangle
            //float closestX = clamp(circle.X, rectangle.Left, rectangle.Right);
            //float closestY = clamp(circle.Y, rectangle.Top, rectangle.Bottom);

            //// Calculate the distance between the circle's center and this closest point
            //float distanceX = circle.X - closestX;
            //float distanceY = circle.Y - closestY;

            //// If the distance is less than the circle's radius, an intersection occurs
            //float distanceSquared = (distanceX * distanceX) + (distanceY * distanceY);
            //return distanceSquared < (circle.Radius * circle.Radius);
            
            double closestX = Math.Max(Math.Min(centre.X, r.Right), r.Left);
            double closestY = Math.Max(Math.Min(centre.Y, r.Bottom), r.Top);

            // Calculate the distance between the circle's center and this closest point
            double distanceX = centre.X - closestX;
            double distanceY = centre.Y - closestY;

            // If the distance is less than the circle's radius, an intersection occurs
            return ((distanceX * distanceX) + (distanceY * distanceY)) <= (radius*radius);
            


        }