Rebracer update.
1 // --------------------------------------------------------------------------------------------------------------------
2 // <copyright file="ScreenPointHelper.cs" company="OxyPlot">
3 // The MIT License (MIT)
5 // Copyright (c) 2012 Oystein Bjorke
7 // Permission is hereby granted, free of charge, to any person obtaining a
8 // copy of this software and associated documentation files (the
9 // "Software"), to deal in the Software without restriction, including
10 // without limitation the rights to use, copy, modify, merge, publish,
11 // distribute, sublicense, and/or sell copies of the Software, and to
12 // permit persons to whom the Software is furnished to do so, subject to
13 // the following conditions:
15 // The above copyright notice and this permission notice shall be included
16 // in all copies or substantial portions of the Software.
18 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
19 // OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
21 // IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
22 // CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
23 // TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
24 // SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
27 // Provides various algorithms for polygons and lines of ScreenPoint.
29 // --------------------------------------------------------------------------------------------------------------------
32 using System.Collections.Generic;
35 /// Provides algorithms for polygons and lines of <see cref="ScreenPoint"/>.
37 public static class ScreenPointHelper
40 /// Finds the nearest point on the specified polyline.
42 /// <param name="point">
45 /// <param name="points">
49 /// The nearest point.
51 public static ScreenPoint FindNearestPointOnPolyline(ScreenPoint point, IList<ScreenPoint> points)
53 double minimumDistance = double.MaxValue;
54 var nearestPoint = default(ScreenPoint);
56 for (int i = 0; i + 1 < points.Count; i++)
59 var p2 = points[i + 1];
60 if (ScreenPoint.IsUndefined(p1) || ScreenPoint.IsUndefined(p2))
65 // Find the nearest point on the line segment.
66 var nearestPointOnSegment = FindPointOnLine(point, p1, p2);
68 if (ScreenPoint.IsUndefined(nearestPointOnSegment))
73 double l2 = (point - nearestPointOnSegment).LengthSquared;
75 if (l2 < minimumDistance)
77 nearestPoint = nearestPointOnSegment;
86 /// Finds the point on line.
92 /// The first point on the line.
95 /// The second point on the line.
98 /// The nearest point on the line.
101 /// See <a href="http://paulbourke.net/geometry/pointlineplane/">Bourke</a>.
103 public static ScreenPoint FindPointOnLine(ScreenPoint p, ScreenPoint p1, ScreenPoint p2)
105 double dx = p2.x - p1.x;
106 double dy = p2.y - p1.y;
107 double u = FindPositionOnLine(p, p1, p2);
124 return new ScreenPoint(p1.x + (u * dx), p1.y + (u * dy));
128 /// Finds the nearest point on line.
133 /// <param name="p1">
134 /// The start point on the line.
136 /// <param name="p2">
137 /// The end point on the line.
140 /// The relative position of the nearest point.
143 /// See <a href="http://paulbourke.net/geometry/pointlineplane/">Bourke</a>.
145 public static double FindPositionOnLine(ScreenPoint p, ScreenPoint p1, ScreenPoint p2)
147 double dx = p2.x - p1.x;
148 double dy = p2.y - p1.y;
149 double u1 = ((p.x - p1.x) * dx) + ((p.y - p1.y) * dy);
150 double u2 = (dx * dx) + (dy * dy);
161 /// Determines whether the specified point is in the specified polygon.
166 /// <param name="pts">
167 /// The polygon points.
170 /// <c>true</c> if the point is in the polygon; otherwise, <c>false</c>.
172 public static bool IsPointInPolygon(ScreenPoint p, IList<ScreenPoint> pts)
174 int nvert = pts.Count;
176 for (int i = 0, j = nvert - 1; i < nvert; j = i++)
178 if (((pts[i].Y > p.Y) != (pts[j].Y > p.Y))
179 && (p.X < ((pts[j].X - pts[i].X) * ((p.Y - pts[i].Y) / (pts[j].Y - pts[i].Y))) + pts[i].X))
189 /// Resamples the points with the specified point distance limit.
191 /// <param name="allPoints">
194 /// <param name="minimumDistance">
195 /// The minimum squared distance.
198 /// List of resampled points.
200 public static IList<ScreenPoint> ResamplePoints(IList<ScreenPoint> allPoints, double minimumDistance)
202 double minimumSquaredDistance = minimumDistance * minimumDistance;
203 int n = allPoints.Count;
204 var result = new List<ScreenPoint>(n);
207 result.Add(allPoints[0]);
209 for (int i = 1; i < n; i++)
211 double distSquared = allPoints[i0].DistanceToSquared(allPoints[i]);
212 if (distSquared < minimumSquaredDistance && i != n - 1)
218 result.Add(allPoints[i]);
226 /// Gets the centroid of the specified polygon.
228 /// <param name="points">
234 public static ScreenPoint GetCentroid(IList<ScreenPoint> points)
240 for (int i = 0; i < points.Count; i++)
242 int i1 = (i + 1) % points.Count;
243 double da = (points[i].x * points[i1].y) - (points[i1].x * points[i].y);
244 cx += (points[i].x + points[i1].x) * da;
245 cy += (points[i].y + points[i1].y) * da;
252 return new ScreenPoint(cx, cy);