using System; using System.Collections.Generic; namespace TriangleNet.Geometry { public class Contour { private int marker; private bool convex; public List Points { get; set; } public Contour(IEnumerable points) : this(points, 0, convex: false) { } public Contour(IEnumerable points, int marker) : this(points, marker, convex: false) { } public Contour(IEnumerable points, int marker, bool convex) { AddPoints(points); this.marker = marker; this.convex = convex; } public List GetSegments() { List list = new List(); List points = Points; int num = points.Count - 1; for (int i = 0; i < num; i++) { list.Add(new Segment(points[i], points[i + 1], marker)); } list.Add(new Segment(points[num], points[0], marker)); return list; } public Point FindInteriorPoint(int limit = 5, double eps = 2E-05) { if (convex) { int count = Points.Count; Point point = new Point(0.0, 0.0); for (int i = 0; i < count; i++) { point.x += Points[i].x; point.y += Points[i].y; } point.x /= count; point.y /= count; return point; } return FindPointInPolygon(Points, limit, eps); } private void AddPoints(IEnumerable points) { Points = new List(points); int index = Points.Count - 1; if (Points[0] == Points[index]) { Points.RemoveAt(index); } } private static Point FindPointInPolygon(List contour, int limit, double eps) { List points = contour.ConvertAll((Converter)((Vertex result) => result)); Rectangle rectangle = new Rectangle(); rectangle.Expand(points); int count = contour.Count; Point point = new Point(); RobustPredicates robustPredicates = new RobustPredicates(); Point point2 = contour[0]; Point point3 = contour[1]; for (int num = 0; num < count; num++) { Point point4 = contour[(num + 2) % count]; double x = point3.x; double y = point3.y; double value = robustPredicates.CounterClockwise(point2, point3, point4); double num2; double num3; if (Math.Abs(value) < eps) { num2 = (point4.y - point2.y) / 2.0; num3 = (point2.x - point4.x) / 2.0; } else { num2 = (point2.x + point4.x) / 2.0 - x; num3 = (point2.y + point4.y) / 2.0 - y; } point2 = point3; point3 = point4; value = 1.0; for (int num4 = 0; num4 < limit; num4++) { point.x = x + num2 * value; point.y = y + num3 * value; if (rectangle.Contains(point) && IsPointInPolygon(point, contour)) { return point; } point.x = x - num2 * value; point.y = y - num3 * value; if (rectangle.Contains(point) && IsPointInPolygon(point, contour)) { return point; } value /= 2.0; } } throw new Exception(); } private static bool IsPointInPolygon(Point point, List poly) { bool flag = false; double x = point.x; double y = point.y; int count = poly.Count; int i = 0; int index = count - 1; for (; i < count; i++) { if (((poly[i].y < y && poly[index].y >= y) || (poly[index].y < y && poly[i].y >= y)) && (poly[i].x <= x || poly[index].x <= x)) { flag ^= poly[i].x + (y - poly[i].y) / (poly[index].y - poly[i].y) * (poly[index].x - poly[i].x) < x; } index = i; } return flag; } } }