示例#1
0
        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);
        }
示例#2
0
        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);
        }