private PolygonWrapperRotation(List <Vector2> data) { mPolygonData = new GeoPointsArray2(data); mCenterList = new List <Vector2>(); mRectangleList = new List <GeoAABB2>(); mOccupied = 0.0f; mScale = 4.0f; }
public List <Vector2> Build() { GeoPointsArray2 polygon2 = FirstTriangle(); for (int i = 0; i < mCount; ++i) { Vector2 tmp = mPoints[i]; if (GeoPolygonUtils.IsPointInConvexPolygon2(polygon2, tmp) == -1) { AddPoint(polygon2, tmp); } } return(polygon2.mPointArray); }
public static GeoPointsArray3 BuildConvexHull(GeoPointsArray3 points) { points.Distinct(); GeoPlane plane = new GeoPlane(Vector3.zero, 0); if (IsOnSamePlane(points, ref plane)) { GeoPointsArray2 point2 = new GeoPointsArray2(GeoPlaneUtils.PlaneTransformLocal(points.mPointArray, plane)); point2 = BuildConvexHull(point2); return(new GeoPointsArray3(GeoPlaneUtils.PlaneTransformGlobal(point2.mPointArray, plane))); } else { return(new GeoPointsArray3(QuickHull.BuildHull(points))); } }
private void RemovePointsInPolygon(List <Vector2> innerPoly) { List <Vector2> temp = new List <Vector2>(); temp.AddRange(innerPoly); GeoPolygonUtils.ReverseIfCW(ref temp); GeoPointsArray2 poly = new GeoPointsArray2(temp); List <int> removeIndex = new List <int>(); for (int i = 0; i < mCenterList.Count; ++i) { Vector2 t = mCenterList[i]; if (GeoPolygonUtils.IsPointInPolygon2(poly, ref t)) { removeIndex.Add(i); } } for (int i = removeIndex.Count - 1; i >= 0; --i) { mCenterList.RemoveAt(removeIndex[i]); } }
private void AddPoint(GeoPointsArray2 polygon2, Vector2 p) { int cnt = polygon2.Count; List <bool> convexMask = new List <bool>(); for (int i = 0; i < cnt; ++i) { int j = i + 1; if (j == cnt) { j = 0; } convexMask.Add(GeoPolygonUtils.IsConvexAngle(polygon2[i], polygon2[j], p)); } int start = -1; int end = -1; for (int i = 0; i < cnt; i++) { int j = i + 1; if (j == cnt) { j = 0; } if (start == -1 && convexMask[i] == false && convexMask[j] == true) { start = j; } if (end == -1 && convexMask[i] == true && convexMask[j] == false) { end = j; } if (start != -1 && end != -1) { break; } } if (start != -1 && end != -1) { GeoPointsArray2 other = new GeoPointsArray2(); if (start <= end) { for (int i = start; i <= end; ++i) { other.Add(polygon2[i]); } } else { for (int i = start; i < cnt; ++i) { other.Add(polygon2[i]); } for (int i = 0; i <= end; ++i) { other.Add(polygon2[i]); } } other.Add(p); polygon2.Clear(); polygon2.mPointArray.AddRange(other.mPointArray); } }
// CCW private GeoPointsArray2 FirstTriangle() { GeoPointsArray2 polygon2 = new GeoPointsArray2(); int minIndex = 0; int maxIndex = 0; float minX = mPoints[0].x; float maxX = mPoints[0].x; for (int i = 1; i < mCount; ++i) { if (mPoints[i].x < minX) { minX = mPoints[i].x; minIndex = i; } if (mPoints[i].x > maxX) { maxX = mPoints[i].x; maxIndex = i; } } Vector2 max = mPoints[maxIndex]; Vector2 min = mPoints[minIndex]; if (maxIndex > minIndex) { mPoints.RemoveAt(maxIndex); mPoints.RemoveAt(minIndex); } else { mPoints.RemoveAt(minIndex); mPoints.RemoveAt(maxIndex); } mCount = mPoints.Count; Vector2 dir = max - min; // 逆时针 Vector2 left = new Vector2(-dir.y, dir.x); maxX = -1e10f; int sign = 0; for (int i = 0; i < mCount; ++i) { dir = mPoints[i] - min; float d = Vector2.Dot(dir, left); bool s = d < 0; if (s) { d = -d; } if (d > maxX) { maxX = d; sign = s ? -1 : 1; maxIndex = i; } } Vector2 threePoint = mPoints[maxIndex]; mPoints.RemoveAt(maxIndex); mCount = mPoints.Count; Assert.IsTrue(maxX > -1.0f, "wrong"); polygon2.Add(min); if (sign == 1) { polygon2.Add(max); polygon2.Add(threePoint); } else { polygon2.Add(threePoint); polygon2.Add(max); } return(polygon2); }
public static GeoPointsArray2 BuildConvexHull(GeoPointsArray2 points) { points.Distinct(); return(new GeoPointsArray2(JarvisConvex.BuildHull(points.mPointArray))); }
// 对于环状问题,暂时没处理。处理起来,稍作修改即可。后期遇到时加入(检测环状,然后分离环状,及带孔的多边形环形区域。) public static void PolygonExpand(List <Vector2> original, List <Vector2> results, float length = 1.0f, bool useHull = true) { List <Vector2> origin = new List <Vector2>(); origin.AddRange(original); GeoPointsArray2 hullArray = null; if (useHull) { List <Vector2> hull = JarvisConvex.BuildHull(original); GeoPolygonUtils.ReverseIfCW(ref hull); hullArray = new GeoPointsArray2(hull); } float len = length; while (results.Count == 0) { List <Vector2> segs = ExpandPolygonSegments(origin, len); float min = CheckSegmentsIntersect(segs); if (min > len) { min = len; } if (min > 1e-5f) { List <Vector2> expands = ExpandPolygon(origin, min); //List<int> vLst = GeoUtils.VertexIndexList(expands); //List<List<int>> circles = CommonUtils.CheckCircle(vLst); // GeoUtils.Split(origin, circles); origin = PolygonIntersectRemove(expands); len = len - min; if (len < 0.01f) { results.AddRange(origin); } } else { for (int i = 1; i < segs.Count; i += 2) { results.Add(segs[i]); } } if (useHull && results.Count == 0 && hullArray != null) { bool flag = false; for (int i = 0; i < origin.Count; i++) { Vector2 refV = origin[i]; if (GeoPolygonUtils.IsPointInConvexPolygon2(hullArray, ref refV)) { flag = true; break; } } if (!flag) { List <Vector2> split = JarvisConvex.BuildHull(origin); GeoPolygonUtils.ReverseIfCW(ref split); split = ConvexMarginalExpand(split, len); results.AddRange(split); len = 0; } } } }