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; }
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); } } } } }
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); } }
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); } } } }
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)); }
public static RectangleD Transform(this RectangleD @this, ICoordinateTransformation transformation) { return(transformation.Transform(@this)); }
static RectangleD() { Empty = new RectangleD(); }
/// <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); }
/// <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))); }
/// <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; }
/// <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; }
/// <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))); }
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); } } } } }
/// <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))); }
/// <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; }
public QuadTree(RectangleD bounds) { rootNode = new QTNode(bounds, 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))); }
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]))); }
/// <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); }