Files
2026-03-04 10:03:45 +08:00

143 lines
3.4 KiB
C#

using System;
using System.Collections.Generic;
namespace TriangleNet.Geometry
{
public class Contour
{
private int marker;
private bool convex;
public List<Vertex> Points { get; set; }
public Contour(IEnumerable<Vertex> points)
: this(points, 0, convex: false)
{
}
public Contour(IEnumerable<Vertex> points, int marker)
: this(points, marker, convex: false)
{
}
public Contour(IEnumerable<Vertex> points, int marker, bool convex)
{
AddPoints(points);
this.marker = marker;
this.convex = convex;
}
public List<ISegment> GetSegments()
{
List<ISegment> list = new List<ISegment>();
List<Vertex> 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<Vertex> points)
{
Points = new List<Vertex>(points);
int index = Points.Count - 1;
if (Points[0] == Points[index])
{
Points.RemoveAt(index);
}
}
private static Point FindPointInPolygon(List<Vertex> contour, int limit, double eps)
{
List<Point> points = contour.ConvertAll((Converter<Vertex, Point>)((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<Vertex> 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;
}
}
}