public Point ClosestPointFromPointToPolygon(CustomPolygon customPolygon, Point point) { if (customPolygon.GetPolygonVertices().Count == 2) // horizontal line { double minX = customPolygon.polygon.Points[0].X; double maxX = customPolygon.polygon.Points[0].X; for (int i = 1; i < customPolygon.polygon.Points.Count; i++) { Point q = customPolygon.polygon.Points[i]; minX = Math.Min(q.X, minX); maxX = Math.Max(q.X, maxX); } if (point.X < minX) { point.X = minX; } if (point.X > maxX) { point.X = maxX; } point.Y = customPolygon.center.Y; } else // n > 2 { // list of lines in polygon List <Line> polygonLines = customPolygon.GetPolygonLines(); Point? minPoint = null; double minDist = double.MaxValue; // for each line in polygon, find the perpendicular line from point foreach (var line in polygonLines) { Point p1 = new Point(line.X1, line.Y1); Point p2 = new Point(line.X2, line.Y2); // calculate slopes double slope = CustomPolygon.GetSlope(p1, p2); double perpSlope = CustomPolygon.GetPerpendicularSlope(slope); Debug.WriteLine("slope:{0} perp:{1}", slope, perpSlope); // perpendicular line from point Line perpLine = CustomPolygon.GetPerpLine(point, perpSlope); // find intersection point Point?intersectionPoint = CustomPolygon.GetIntersectionPoint(line, perpLine); if (intersectionPoint.HasValue) { //get distance from point double dist = CustomPolygon.GetDistance(intersectionPoint.Value, point); Debug.WriteLine("dist: {0}", dist); // does this line intersect the polygon line // is the intersection point and the point a min distance if (CustomPolygon.IsPointInLine(intersectionPoint.Value, line) && dist < minDist) { minDist = dist; minPoint = intersectionPoint; } } else { throw new Exception("Intersection Point is null even though it should have a coordinate"); } } // If there is no minpoint we calculate the closest distance from the point to the polygon corners if (!minPoint.HasValue) { minDist = double.MaxValue; PointCollection points = customPolygon.polygon.Points; for (int i = 0; i < points.Count; i++) { double dist = CustomPolygon.GetDistance(points[i], point); if (dist < minDist) { minDist = dist; minPoint = points[i]; } } } point = minPoint.Value; } return(point); }
private List <Double> GetExtendedDistanceList(PointCollection points, Point clickPoint) { List <Double> extendedDistances = new List <Double>(); const double offset = 0.01; for (int i = 0; i < points.Count; i++) { Point objectivePoint = points[i]; // get the line from objective point to the clickpoint Line clickLine = new Line(); clickLine.X1 = objectivePoint.X; clickLine.X2 = clickPoint.X; clickLine.Y1 = objectivePoint.Y; clickLine.Y2 = clickPoint.Y; Point?intersectionPoint = null; // we cycle through the polygon points 2 at a time, finding the polygon line // that intersects with the extended clickLine for (int j = 0; j < points.Count; j++) { Point currentPoint = points[j]; Point nextPoint; if ((j + 1) < points.Count) { nextPoint = points[j + 1]; } else { // if the point is the last point, we cycle back to get the point in the 0th index nextPoint = points[0]; } Line polygonLine = new Line(); polygonLine.X1 = currentPoint.X; polygonLine.X2 = nextPoint.X; polygonLine.Y1 = currentPoint.Y; polygonLine.Y2 = nextPoint.Y; intersectionPoint = CustomPolygon.GetIntersectionPoint(clickLine, polygonLine); // Make sure the intersection point calculated is not the objectivePoint if (intersectionPoint.HasValue && // this part is trick af because it is floating point calculation. Need some offset (!CustomPolygon.FloatsAreEqual(objectivePoint.X, intersectionPoint.Value.X, offset) || !CustomPolygon.FloatsAreEqual(objectivePoint.Y, intersectionPoint.Value.Y, offset)) && CustomPolygon.IsPointInLine(intersectionPoint.Value, polygonLine)) { // if we have discovered the point we break out of the for loop Console.WriteLine("the valid intersection point is ({0}, {1})", intersectionPoint.Value.X, intersectionPoint.Value.Y); break; } } // Get distance between the polygon corner and the intersecting coordinate if (intersectionPoint.HasValue) { double extendedDistance = CustomPolygon.GetDistance(intersectionPoint.Value, objectivePoint); extendedDistances.Add(extendedDistance); } //else //{ // // I should be getting some kind of intersection here if not // throw new Exception("Intersection Point is null even though it should have a coordinate"); //} } return(extendedDistances); }