public void CalculateWeights(Point clickPoint) { List <Double> clickDistances = this.GetClickDistanceList(this.polygon.Points, clickPoint); if (this.polygon.Points.Count == 2) //line { double max = CustomPolygon.GetDistance(this.polygon.Points[0], this.polygon.Points[1]); Debug.WriteLine("max distance:{0}", max); weights = this.NormalizeWeightsTwoSide(clickDistances, max); } else { List <Double> extendedDistances = this.GetExtendedDistanceList(this.polygon.Points, clickPoint); List <Double> unnormalizedWeights = this.GetUnnormalizedWeights(extendedDistances, clickDistances); // Need to include this because line thickness of the polygon causes it to "bleed outwards" from the polygon's points if (CustomPolygon.ContainsNegative(unnormalizedWeights)) { Console.WriteLine("Out of bounds of the polygon"); weights = this.NormalizeWeights(unnormalizedWeights); } else { weights = this.NormalizeWeights(unnormalizedWeights); } } }
private List <Double> GetClickDistanceList(PointCollection points, Point clickPoint) { List <Double> distances = points.Aggregate( new List <Double>(), (acc, p) => { acc.Add(CustomPolygon.GetDistance(p, clickPoint)); return(acc); }); return(distances); }
public static bool IsPointInLine(Point point3, Line line) { Point point1 = new Point(line.X1, line.Y1); Point point2 = new Point(line.X2, line.Y2); // we use sqrt here because getDistance does not actually sqrt double p1p2 = CustomPolygon.GetDistance(point1, point2); double p1p3 = CustomPolygon.GetDistance(point1, point3); double p2p3 = CustomPolygon.GetDistance(point2, point3); if (p1p2 == (p1p3 + p2p3)) { return(true); } else { return(false); } }
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); }