public MainWindow() { this.MouseMove += this.onMouseMove; // Create a canvas sized to fill the window this.canvas = new Canvas(); // Add polygon this.polygon = new Polygon(); this.polygon.Stroke = Brushes.Black; this.polygon.Fill = Brushes.Transparent; this.polygon.StrokeThickness = 1; // this.polygon.Margin = new Thickness(0, 0, 0, 0.5); this.polygon.Points = Constants.rectangle; // this.polygon.MouseMove += this.onMouseMovePolygon; this.canvas.Children.Add(this.polygon); // Make sure the polygon is right at the top so the textbox does not overlay it Canvas.SetZIndex(this.polygon, (int)99); // Add customPolygon this.customPolygon = new CustomPolygon(this.polygon); // Add crosshair Point centroid = Utilities.getPolygonCentroid(this.polygon); // this.crossHair = this.addTextBlockToCanvas("X", centroid.X, centroid.Y); this.crossHair = new Ellipse(); this.crossHair.Width = Constants.crossHairDim; this.crossHair.Height = Constants.crossHairDim; this.crossHair.Fill = Brushes.Red; Canvas.SetLeft(this.crossHair, centroid.X - Constants.crossHairDim / 2); Canvas.SetTop(this.crossHair, centroid.Y - Constants.crossHairDim / 2); this.canvas.Children.Add(this.crossHair); // Populate based on the number of points in the polygon this.populateObjectiveNames(); this.labelPolygonPoints(); // Add objective names to text elements this.addObjectiveText(); this.Content = this.canvas; this.Title = "Shapes Demo"; this.Show(); // mock click in the center of the polygon }
private void onMouseMove(object sender, MouseEventArgs e) { if (e.LeftButton == MouseButtonState.Pressed) { Point clickPoint = e.GetPosition(this); Console.WriteLine("the click point is ({0}, {1})", clickPoint.X, clickPoint.Y); if (!CustomPolygon.IsInPolygon(this.polygon.Points, clickPoint)) { Point closestPoint = CustomPolygon.ClosestPointFromPointToPolygon(this.customPolygon, clickPoint); this.displayWeightsFromClick(closestPoint); } else { this.displayWeightsFromClick(clickPoint); } } }
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"); } }