public CustomLine(Point p1, double s) : this() { this.point1 = p1; this.slope = s; if (slope == 1e+10) { this.isVertical = true; } if (!isVertical) { this.c = CustomLine.calculateC(p1, slope); } ; this.point2 = this.calculatePoint2(); }
public CustomLine(Point p1, Point p2) : this() { this.point1 = p1; this.point2 = p2; this.slope = CustomLine.calculateSlope(p1, p2); if (slope == 1e+10) { this.isVertical = true; } if (!isVertical) { this.c = CustomLine.calculateC(p1, slope); } ; }
public static bool withinLineSegment(Point point3, CustomLine l) { Point point1 = l.getPoint1(); Point point2 = l.getPoint2(); // we use sqrt here because getDistance does not actually sqrt double p1p2 = (Utilities.getDistance(point1, point2)); double p1p3 = (Utilities.getDistance(point1, point3)); double p2p3 = (Utilities.getDistance(point2, point3)); if (p1p2 == (p1p3 + p2p3)) { return(true); } else { return(false); } }
public static Point?getIntersectionCoordinates(CustomLine l1, CustomLine l2) { Point intersectionPoint = new Point(); // if parallel if (l1.getSlope() == l2.getSlope()) { return(null); } // if either one is vertical (but not both because we would have returned null already) else if (l1.getIsVertical()) { intersectionPoint.X = l1.getPoint1().X; Point l2Point = l2.getPoint1(); intersectionPoint.Y = (intersectionPoint.X * l2.getSlope()) + l2.getConstant(); } else if (l2.getIsVertical()) { intersectionPoint.X = l2.getPoint1().X; Point l1Point = l1.getPoint1(); intersectionPoint.Y = (intersectionPoint.X * l1.getSlope()) + l1.getConstant(); } else { Point l1Point = l1.getPoint1(); Point l2Point = l2.getPoint1(); double a1 = l1Point.Y - l1.getSlope() * l1Point.X; double a2 = l2Point.Y - l2.getSlope() * l2Point.X; intersectionPoint.X = (a1 - a2) / (l2.getSlope() - l1.getSlope()); intersectionPoint.Y = a2 + l2.getSlope() * intersectionPoint.X; } return(intersectionPoint); }
public static Point ClosestPointFromPointToPolygon(CustomPolygon polygon, Point point) { // we keep track of point with minimum distance Point? minPoint = null; double minDist = double.MaxValue; List <CustomLine> polygonLines = polygon.GetPolygonLines(); // for each line in polygon, find the perpendicular line from point for (int i = 0; i < polygonLines.Count(); i++) { CustomLine lineSegment = polygonLines[i]; double slope = lineSegment.getSlope(); double perpSlope = CustomLine.getPerpendicularSlope(slope); CustomLine perpLine = new CustomLine(point, perpSlope); Point? intersectionPoint = CustomLine.getIntersectionCoordinates(lineSegment, perpLine); if (intersectionPoint.HasValue) { double dist = Utilities.getDistance(intersectionPoint.Value, point); // does this line intersect the polygon line segment? // is the intersection point and the point a min distance if (CustomLine.withinLineSegment(intersectionPoint.Value, lineSegment) && dist < minDist) { minDist = dist; minPoint = intersectionPoint; } } else { throw new Exception("Intersection Point is null even though it should have a coordinate"); } } // If there is a minpoint we are good to go if (minPoint.HasValue) { return(minPoint.Value); } // or else we calculate the closest distance from the point to the polygon corners else { minDist = double.MaxValue; PointCollection points = polygon.GetPoints(); for (int i = 0; i < points.Count; i++) { double dist = Utilities.getDistance(points[i], point); if (dist < minDist) { minDist = dist; minPoint = points[i]; } } } // If there is a minpoint we are good to go if (minPoint.HasValue) { return(minPoint.Value); } else { throw new Exception("Point with minimum distance is null even though it should have a coordinate"); } }
private List <Double> getExtendedDistanceList(PointCollection points, Point clickPoint) { List <Double> extendedDistances = new List <Double>(); for (int i = 0; i < points.Count; i++) { Point objectivePoint = points[i]; // get the line from objective point to the clickpoint CustomLine clickLine = new CustomLine(objectivePoint, clickPoint); 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]; } CustomLine polygonLine = new CustomLine(currentPoint, nextPoint); intersectionPoint = CustomLine.getIntersectionCoordinates(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 (!Utilities.floatsEqual(objectivePoint.X, intersectionPoint.Value.X, Constants.offset) || !Utilities.floatsEqual(objectivePoint.Y, intersectionPoint.Value.Y, Constants.offset)) && CustomLine.withinLineSegment(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 = Utilities.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); }