/// <summary> /// 顺时针顶点 /// </summary> /// <param name="p1"></param> /// <param name="p2"></param> /// <param name="p3"></param> public Triangle2D(Double2 p1, Double2 p2, Double2 p3) { this.p1 = p1; this.p2 = p2; this.p3 = p3; Double2 min = Double2.Min(p1, Double2.Min(p2, p3)); Double2 max = Double2.Max(p1, Double2.Max(p2, p3)); this.SetAABB(min, max); }
/// <summary> /// 初始化数据 /// </summary> /// <param name="points"></param> private void Init(Double2[] points) { if (points == null || points.Length < 3) { return; } this.pointArr = new Double2[points.Length]; this.normalAttr = new Double2[points.Length]; this.distancArr = new double[points.Length + 1]; Double2 min = points[0]; Double2 max = points[0]; int i; for (i = 0; i < points.Length; i++) { this.pointArr[i] = points[i]; if (i > 0) { min = Double2.Min(min, points[i]); max = Double2.Max(max, points[i]); totalDistance += MathUtil.GetNearDistance(points[i - 1], points[i]); this.distancArr[i] = totalDistance; } else { min = points[i]; max = points[i]; this.distancArr[i] = 0; totalDistance = 0; } // Double2 dir; if (i < points.Length - 1) { dir = (points[i + 1] - points[i]).normalized; } else { dir = (points[0] - points[i]).normalized; } this.normalAttr[i] = Double2.Perpendicular(dir); } totalDistance += MathUtil.GetNearDistance(points[points.Length - 1], points[0]); this.distancArr[i] = totalDistance; this.SetAABB(min, max); }
/// <summary> /// 获取凸包 /// </summary> /// <param name="listpt"></param> /// <returns></returns> public static List <Double2> GenerateConvexPolygon(Double2[] listpt) { if (listpt == null || listpt.Length == 0) { return(null); } // 先生成aabb。 Double2 min = Double2.positiveInfinity; Double2 max = Double2.negativeInfinity; foreach (Double2 pos in listpt) { min = Double2.Min(min, pos); max = Double2.Max(max, pos); } // 收集条边上的点,按顺时针收集。lb放置在bottom边上,rb 放置在right边上,ru顶点放置up边上, lu顶点放置在left边上 Double2[][] edgePointArray = new Double2[4][]; for (int i = 0; i < 4; i++) { edgePointArray[i] = new Double2[2]; if (i < 2) { edgePointArray[i][0] = Double2.positiveInfinity; edgePointArray[i][1] = Double2.negativeInfinity; } else { edgePointArray[i][0] = Double2.negativeInfinity; edgePointArray[i][1] = Double2.positiveInfinity; } } // 不在边上的顶点 List <Double2> listOutEdgePoint = new List <Double2>(); // 进行收集了。 foreach (Double2 pos in listpt) { bool isInedge = false; // 第一条边 bottom edge if (pos.y == min.y) { edgePointArray[0][0] = Double2.Min(pos, edgePointArray[0][0]); edgePointArray[0][1] = Double2.Max(pos, edgePointArray[0][1]); isInedge = true; } if (pos.x == max.x) // right edge { edgePointArray[1][0] = Double2.Min(pos, edgePointArray[1][0]); edgePointArray[1][1] = Double2.Max(pos, edgePointArray[1][1]); isInedge = true; } if (pos.y == max.y) // up edge { edgePointArray[2][0] = Double2.Max(pos, edgePointArray[2][0]); edgePointArray[2][1] = Double2.Min(pos, edgePointArray[2][1]); isInedge = true; } if (pos.x == min.x) // left edge { edgePointArray[3][0] = Double2.Max(pos, edgePointArray[3][0]); edgePointArray[3][1] = Double2.Min(pos, edgePointArray[3][1]); isInedge = true; } if (isInedge == false) { listOutEdgePoint.Add(pos); } } // 边上的顶点按顺时针排序了。 // List <Double2> listPoly = new List <Double2>(); Double2 startPoint; Double2 endPoint = Double2.negativeInfinity; for (int i = 0; i < 4; i++) { startPoint = edgePointArray[i][0]; if (startPoint != endPoint) { listPoly.Add(startPoint); } endPoint = edgePointArray[i][1]; if (startPoint != endPoint) { listPoly.Add(endPoint); } if (endPoint != edgePointArray[(i + 1) % 4][0]) { List <Double2> llinkPoint = SearchOutPoint(i, endPoint, edgePointArray[(i + 1) % 4][0], listOutEdgePoint); if (llinkPoint != null && llinkPoint.Count > 0) { listPoly.AddRange(llinkPoint); } } } for (int i = 0; i < 4; i++) { edgePointArray[i] = null; } edgePointArray = null; if (listPoly.Count > 1) { if (listPoly[0] == listPoly[listPoly.Count - 1]) { listPoly.RemoveAt(listPoly.Count - 1); } } return(listPoly); }