#region 计算点的凸包,并返回凸包的点集
public static List<XYZ> GetConvexHullPoints(List<XYZ> points)
{
List<Segment> segments = new List<Segment>();
segments = GetAllSegments(points);
List<XYZ> ProcessingPoints = new List<XYZ>();
int i = 0;
int j = 0;
for (i = 0; i < segments.Count; )
{
//ProcessingPoints will be the points that are not in the current segment
ProcessingPoints = new List<XYZ>(points);
for (j = 0; j < ProcessingPoints.Count; )
{
if (segments[i].contains(ProcessingPoints[j]))
{
ProcessingPoints.Remove(ProcessingPoints[j]);
j = 0;
continue;
}
j++;
}
if (!isEdge(ProcessingPoints, segments[i]))
{
segments.Remove(segments[i]);
i = 0;
continue;
}
else
{ i++; }
}
return segments.Select(x => x.p).ToList();
}
private static bool isEdge(List<XYZ> processingPoints, Segment edge)
{
for (int k = 0; k < processingPoints.Count; k++)
{
if (IsLeft(edge, processingPoints[k]))
{
return false;
}
}
return true;
}
private static bool IsLeft(Segment segment, XYZ r)
{
double D = 0;
double px, py, qx, qy, rx, ry = 0;
//The determinant
// | 1 px py |
// | 1 qx qy |
// | 1 rx ry |
//if the determinant result is positive then the point is left of the segment
px = segment.p.X;
py = segment.p.Y;
qx = segment.q.X;
qy = segment.q.Y;
rx = r.X;
ry = r.Y;
D = ((qx * ry) - (qy * rx)) - (px * (ry - qy)) + (py * (rx - qx));
if (D <= 0)
return false;
return true;
}
private static List<Segment> GetAllSegments(List<XYZ> points)
{
List<Segment> segments = new List<Segment>();
//Initialize all possible segments from the picked points
for (int i = 0; i < points.Count; i++)
{
for (int j = 0; j < points.Count; j++)
{
if (i != j)
{
Segment op = new Segment();
XYZ p1 = points[i];
XYZ p2 = points[j];
op.p = p1;
op.q = p2;
segments.Add(op);
}
}
}
return segments;
}
public struct Segment
{
public XYZ p;
public XYZ q;
public bool contains(XYZ point)
{
if (p.IsAlmostEqualTo(point) || q.IsAlmostEqualTo(point))
return true;
return false;
}
}
#endregion
————————————————
版权声明:本文为CSDN博主「niuge No.1」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/niuge8905/article/details/83090366
进一步改进算法,这里的segement点不是按照顺序连起来的,那么需要让点按照顺序串联起来需要进一步判断。
public static List<XYZ> GetConvexHullPoints(List<XYZ> points)
{
List<Segment> segments = new List<Segment>();
segments = GetAllSegments(points);
List<XYZ> ProcessingPoints = new List<XYZ>();
int i = 0;
int j = 0;
for (i = 0; i < segments.Count; )
{
//ProcessingPoints will be the points that are not in the current segment
ProcessingPoints = new List<XYZ>(points);
for (j = 0; j < ProcessingPoints.Count; )
{
if (segments[i].contains(ProcessingPoints[j]))
{
ProcessingPoints.Remove(ProcessingPoints[j]);
j = 0;
continue;
}
j++;
}
if (!isEdge(ProcessingPoints, segments[i]))
{
segments.Remove(segments[i]);
i = 0;
continue;
}
else
{ i++; }
}
List<XYZ> xyzList = new List<XYZ>();
xyzList.Add(segments[0].StartPoint);
xyzList.Add(segments[0].EndPoint);
segments.RemoveAt(0);
while(segments.Count!=0)
{
bool hasContinuePoint = false;
for (int ii=0;ii<segments.Count;ii++)
{
if (xyzList.Last().IsAlmostEqualTo(segments[ii].StartPoint))
{
xyzList.Add(segments[ii].EndPoint);
hasContinuePoint = true;
segments.RemoveAt(ii);
break;
}
if (hasContinuePoint == false && xyzList.Last().IsAlmostEqualTo(segments[ii].EndPoint))
{
xyzList.Add(segments[ii].StartPoint);
segments.RemoveAt(ii);
break;
}
}
}
return xyzList;
}