/// <summary>Initializes a new instance of the <see cref="T:System.Drawing.RectangleD"></see> class with the specified location and size.</summary> /// <param name="size">A <see cref="T:System.Drawing.SizeD"></see> that represents the width and height of the rectangular region. </param> /// <param name="location">A <see cref="T:System.Drawing.PointD"></see> that represents the upper-left corner of the rectangular region. </param> public RectangleD(PointD location, SizeD size) { this.x = location.X; this.y = location.Y; this.width = size.Width; this.height = size.Height; }
/// <summary> /// Tests whether point is inside a polygon /// </summary> /// <param name="points"></param> /// <param name="x"></param> /// <param name="y"></param> /// <param name="ignoreHoles"></param> /// <param name="isHole"></param> /// <returns></returns> public static bool PointInPolygon(PointD[] points, double x, double y, bool ignoreHoles, ref bool isHole) { if (ignoreHoles) return PointInPolygon(points, x, y); //if we are detecting holes then we need to calculate the area double area = 0; //latitude = y int j = points.Length - 1; bool inPoly = false; for (int i = 0; i < points.Length; ++i) { if (points[i].X < x && points[j].X >= x || points[j].X < x && points[i].X >= x) { if (points[i].Y + (x - points[i].X) / (points[j].X - points[i].X) * (points[j].Y - points[i].Y) < y) { inPoly = !inPoly; } } area += (points[j].X * points[i].Y - points[i].X * points[j].Y); j = i; } area *= 0.5; //Console.Out.WriteLine("area = " + area); isHole = area > 0; return inPoly;// && isHole; }
public PointD ProjectionToLatLong(PointD pt) { double d = (Math.PI / 180) * pt.Y; d = Math.Atan(Math.Sinh(d)); d = d * (180 / Math.PI); return new PointD(pt.X, d); }
public PointD LatLongtoProjection(PointD pt) { if (pt.Y > MaxLLMercProjD) { pt.Y = MaxLLMercProjD; } else if (pt.Y < -MaxLLMercProjD) { pt.Y = -MaxLLMercProjD; } double d = (Math.PI / 180) * pt.Y; double sd = Math.Sin(d); d = (90 / Math.PI) * Math.Log((1 + sd) / (1 - sd)); return new PointD(pt.X, d); }
public static bool PointInPolygon(PointD[] points, double x, double y) { int j = points.Length - 1; bool inPoly = false; for (int i = 0; i < points.Length; ++i) { if (points[i].X < x && points[j].X >= x || points[j].X < x && points[i].X >= x) { if (points[i].Y + (x - points[i].X) / (points[j].X - points[i].X) * (points[j].Y - points[i].Y) < y) { inPoly = !inPoly; } } j = i; } return inPoly; }
public static void LLToPixel(PointD latLong, int zoomLevel, out long x, out long y) { //convert LL to Mercatator PointD merc = ShapeFile.LLToMercator(latLong); double scale = ZoomLevelToScale(zoomLevel); x = (long)Math.Round((merc.X+MaxMerc.X) * scale); y = (long)Math.Round((MaxMerc.Y-merc.Y) * scale); }
/// <summary>Adjusts the location of this rectangle by the specified amount.</summary> /// <returns>This method does not return a value.</returns> /// <param name="pos">The amount to offset the location. </param> /// <filterpriority>1</filterpriority> public void Offset(PointD pos) { this.Offset(pos.X, pos.Y); }
public void LatLongtoProjection(ref PointD ptLL, ref PointD ptProj) { ptProj = ptLL; }
public PointD LatLongtoProjection(PointD pt) { return(pt); }
public static unsafe bool PointOnPolyline(byte[] data, int offset, int numPoints, PointD pt, double minDist) { fixed (byte* bPtr = data) { PointD* points = (PointD*)(bPtr + offset); for (int i = 0; i < numPoints - 1; i++) { if (LineSegPointDist(ref points[i], ref points[i + 1], ref pt) <= minDist) { return true; } } } return false; }
public PointD ProjectionToLatLong(PointD pt) { return pt; }
public PointD LatLongtoProjection(PointD pt) { return pt; }
/// <summary> /// /// </summary> /// <param name="data"></param> /// <param name="offset"></param> /// <param name="numPoints"></param> /// <param name="centre"></param> /// <param name="radius"></param> /// <returns></returns> /// <remarks>Not tested</remarks> public static unsafe bool PolylineCircleIntersects(byte[] data, int offset, int numPoints, PointD centre, double radius) { fixed (byte* bPtr = data) { PointD* points = (PointD*)(bPtr + offset); for (int i = 0; i < numPoints - 1; i++) { if (LineSegPointDist(ref points[i], ref points[i + 1], ref centre) <= radius) { return true; } } } return false; }
public static bool RectangleCircleIntersects(ref System.Drawing.RectangleF 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); }
//Compute the distance from segment AB to C public static double LineSegPointDist(ref PointD a, ref PointD b, ref PointD c) { //float dist = cross(a,b,c) / distance(a,b); if (Dot(ref a, ref b, ref c) > 0) { return Distance(ref b, ref c); } if (Dot(ref b, ref a, ref c) > 0) { return Distance(ref a, ref c); } return Math.Abs(Cross(ref a, ref b, ref c) / Distance(ref a, ref b)); }
/// <summary> /// /// </summary> /// <param name="data"></param> /// <param name="offset"></param> /// <param name="numPoints"></param>6 /// + /// <param name="centre"></param> /// <param name="radius"></param> /// <param name="ignoreHoles"></param> /// <returns></returns> /// <remarks>Not tested</remarks> public static unsafe bool PolygonCircleIntersects(byte[] data, int offset, int numPoints, PointD centre, double radius, bool ignoreHoles) { //test 1 : check if polygon intersects or is inside the circle //test the dist from each polygon edge to circle centre. If < radius then intersects int j = numPoints - 1; fixed (byte* bPtr = data) { PointD* points = (PointD*)(bPtr + offset); for (int i = 0; i < numPoints; ++i) { //could optimize further by working with Distance Squared, but for the moment use the //distance if (LineSegPointDist(ref points[i], ref points[j], ref centre) <= radius) return true; j = i; } } //test 2 : check if the circle is inside the polygon if(ignoreHoles) return PointInPolygon(data, offset, numPoints, centre.X, centre.Y); //if a polygon is a hole then it doesn't intersect bool isHole = false; if (PointInPolygon(data, offset, numPoints, centre.X, centre.Y, false, ref isHole)) return !isHole; return false; }
public static double Distance(ref PointD a, ref PointD b) { double d1 = a.X - b.X; double d2 = a.Y - b.Y; return Math.Sqrt((d1 * d1) + (d2 * d2)); }
//Compute the cross product AB x AC public static double Cross(ref PointD a, ref PointD b, ref PointD c) { PointD ab = new PointD(b.X - a.X, b.Y - a.Y); PointD ac = new PointD(c.X - a.X, c.Y - a.Y); return (ab.X * ac.Y) - (ab.Y * ac.X); }
//compute the dot product AB*BC public static double Dot(ref PointD a, ref PointD b, ref PointD c) { PointD ab = new PointD(b.X - a.X, b.Y - a.Y); PointD bc = new PointD(c.X - b.X, c.Y - b.Y); return (ab.X * bc.X) + (ab.Y * bc.Y); }
//internal static void LLToProjection(ref double ptx, ref double pty, out double px, out double py) //{ // px = ptx; // double d; // if (pty > MaxLLMercProjD) // { // d = (Math.PI / 180) * MaxLLMercProjD; // } // else if (pty < -MaxLLMercProjD) // { // d = (Math.PI / 180) * (-MaxLLMercProjD); // } // else // { // d = (Math.PI / 180) * pty; // } // double sd = Math.Sin(d); // py = (90 / Math.PI) * Math.Log((1 + sd) / (1 - sd)); //} public void ProjectionToLatLong(ref PointD ptProj, ref PointD ptLL) { double d = (Math.PI / 180) * ptProj.Y; d = Math.Atan(Math.Sinh(d)); d = d * (180 / Math.PI); ptLL.X = ptProj.X; ptLL.Y = d; }
public void ProjectionToLatLong(ref PointD ptProj, ref PointD ptLL) { ptLL = ptProj; }
public void LatLongtoProjection(ref PointD ptLL, ref PointD ptProj) { ptProj.X = ptLL.X; double d; if (ptLL.Y > MaxLLMercProjD) { d = (Math.PI / 180) * MaxLLMercProjD; } else if (ptLL.Y < -MaxLLMercProjD) { d = (Math.PI / 180) * (-MaxLLMercProjD); } else { d = (Math.PI / 180) * ptLL.Y; } double sd = Math.Sin(d); ptProj.Y = (90 / Math.PI) * Math.Log((1 + sd) / (1 - sd)); }
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].InsertPointData(recordIndex, ref pt); } if (children[TR].Bounds.Contains(pt)) { children[TR].InsertPointData(recordIndex, ref pt); } if (children[BL].Bounds.Contains(pt)) { children[BL].InsertPointData(recordIndex, ref pt); } if (children[BR].Bounds.Contains(pt)) { children[BR].InsertPointData(recordIndex, ref pt); } //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); } } } }
/// <summary>Initializes a new instance of the <see cref="T:EGIS.ShapeFileLib.SizeD"></see> class from the specified <see cref="T:EGIS.ShapeFileLib.PointD"></see>.</summary> /// <param name="pt">The <see cref="T:EGIS.ShapeFileLib.PointD"></see> from which to initialize this <see cref="T:EGIS.ShapeFileLib.SizeD"></see>. </param> public SizeD(PointD pt) { this.width = pt.X; this.height = pt.Y; }
/// <summary>Determines if the specified point is contained within this <see cref="T:System.Drawing.RectangleD"></see> structure.</summary> /// <returns>This method returns true if the point represented by the pt parameter is contained within this <see cref="T:System.Drawing.RectangleD"></see> structure; otherwise false.</returns> /// <param name="pt">The <see cref="T:System.Drawing.PointD"></see> to test. </param> /// <filterpriority>1</filterpriority> public bool Contains(PointD pt) { return this.Contains(pt.X, pt.Y); }
public PointD ProjectionToLatLong(PointD pt) { return(pt); }
public static unsafe bool PolygonCircleIntersects(byte[] data, int offset, int numPoints, PointD centre, double radius) { return PolygonCircleIntersects(data, offset, numPoints, centre, radius, true); }