Пример #1
0
 public void Initialize(float scale)
 {
     mScale = scale;
     mArea  = GeoPolygonUtils.CalcualetArea(mPolygonData);
     if (mArea < 0)
     {
         mPolygonData.Reverse();
         mArea = -mArea;
     }
     mAABB     = GeoPolygonUtils.CalculateAABB(mPolygonData);
     mMaxSize  = mAABB.mMax - mAABB.mMin;
     mIsConvex = IsAllConvex();
     Decompose();
     mLeftRectangle.Clear();
 }
Пример #2
0
        public static List <Vector3> CalculateConvexHull(List <Vector3> vertices, bool use2d, int ignore = 1)
        {
            List <Vector3> temp = new List <Vector3>();

            if (use2d)
            {
                int x = 0;
                int y = 1;
                if (ignore == 0)
                {
                    x = 1;
                    y = 2;
                }
                else if (ignore == 1)
                {
                    x = 0;
                    y = 2;
                }
                else
                {
                    x = 0;
                    y = 1;
                }
                List <Vector2> temp2 = new List <Vector2>();
                foreach (Vector3 v in vertices)
                {
                    temp2.Add(new Vector2(v[x], v[y]));
                }
                temp2 = JarvisConvex.BuildHull(temp2);
                GeoPolygonUtils.ReverseIfCW(ref temp2);
                foreach (Vector2 v in temp2)
                {
                    temp.Add(vertices.Find((Vector3 v3) => { return(v3[x] == v[0] && v3[y] == v[1]); }));
                }
            }
            else
            {
                temp = QuickHull.BuildHull(vertices);
            }
            return(temp);
        }
        private static void UpdateEdge(HalfEdge edgeToRemove, KeyedPriorityQueue <int, HalfEdge, float> priorityQueue, HashSet <EdgeID> deletedEdgeSet, List <Vector2> pointList)
        {
            HalfEdge left   = GetUndeletedLeft(edgeToRemove, deletedEdgeSet);
            HalfEdge right  = GetUndeletedRight(edgeToRemove, deletedEdgeSet);
            HalfEdge reLeft = RepresentActive(left);

            if (priorityQueue.Contain(reLeft.mKey))
            {
                // Check if this is still removable
                HalfEdge leftOfLeft = GetUndeletedLeft(left.mPartner, deletedEdgeSet);
                if ((leftOfLeft.mPartner != null && (leftOfLeft.mPartner.mKey == right.mKey || leftOfLeft.mPartner.mKey == edgeToRemove.mKey)) ||
                    !GeoPolygonUtils.IsConvex(pointList[edgeToRemove.mIndex], pointList[right.mNext.mIndex], pointList[leftOfLeft.mIndex]))
                {
                    priorityQueue.Remove(reLeft.mKey);
                }
                else
                {
                    // Need to update the priority
                    float pri = GetSmallestAdjacentAngleOnEdge(left, deletedEdgeSet, pointList);
                    priorityQueue.Remove(reLeft.mKey);
                    priorityQueue.Enqueue(reLeft.mKey, reLeft, pri);
                }
            }
            HalfEdge reRight = RepresentActive(right);

            if (priorityQueue.Contain(reRight.mKey))
            {
                HalfEdge rightOfRight = GetUndeletedRight(right, deletedEdgeSet);
                if ((rightOfRight.mPartner != null && (rightOfRight.mPartner.mKey == left.mKey || rightOfRight.mKey == edgeToRemove.mKey)) ||
                    !GeoPolygonUtils.IsConvex(pointList[edgeToRemove.mIndex], pointList[rightOfRight.mNext.mIndex], pointList[left.mIndex]))
                {
                    priorityQueue.Remove(reRight.mKey);
                }
                else
                {
                    priorityQueue.Remove(reRight.mKey);
                    priorityQueue.Enqueue(reRight.mKey, reRight, GetSmallestAdjacentAngleOnEdge(right, deletedEdgeSet, pointList));
                }
            }
        }
Пример #4
0
        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]);
            }
        }
Пример #5
0
        private static List <Vector2> ExpandPolygonSegments(List <Vector2> original, float length = 1.0f)
        {
            List <Vector2> tempOrigin = new List <Vector2>();

            tempOrigin.AddRange(original);
            if (GeoPolygonUtils.CalcualetArea(tempOrigin) < 0)
            {
                tempOrigin.Reverse();
            }
            List <Vector2> result = new List <Vector2>();

            for (int i = 0; i < tempOrigin.Count; ++i)
            {
                int j = i + 1;
                if (j == tempOrigin.Count)
                {
                    j = 0;
                }
                int k = i - 1;
                if (k == -1)
                {
                    k = tempOrigin.Count - 1;
                }
                Vector2 vk  = tempOrigin[k] - tempOrigin[i];
                Vector2 vj  = tempOrigin[j] - tempOrigin[i];
                Vector2 dir = vk.normalized + vj.normalized;
                dir.Normalize();
                if (GeoPolygonUtils.IsConvexAngle(tempOrigin[k], tempOrigin[i], dir + tempOrigin[i]))
                {
                    dir = -dir;
                }
                result.Add(tempOrigin[i]);
                result.Add(tempOrigin[i] + dir * length);
            }
            return(result);
        }
Пример #6
0
        private bool CheckRectangleValid(Vector2 min, Vector2 max, float w, float h)
        {
            Vector2 p4 = new Vector2(min[0], max[1]);
            Vector2 p2 = new Vector2(max[0], min[1]);

            // 点都在polygon 内部  // 使用 bvh 判断
            if (mIsConvex)
            {
                bool isInconvex = GeoPolygonUtils.IsPointInConvexPolygon2(mPolygonData, ref max);
                if (!isInconvex)
                {
                    return(false);
                }
                isInconvex = GeoPolygonUtils.IsPointInConvexPolygon2(mPolygonData, ref min);
                if (!isInconvex)
                {
                    return(false);
                }
                isInconvex = GeoPolygonUtils.IsPointInConvexPolygon2(mPolygonData, ref p2);
                if (!isInconvex)
                {
                    return(false);
                }
                isInconvex = GeoPolygonUtils.IsPointInConvexPolygon2(mPolygonData, ref p4);
                if (!isInconvex)
                {
                    return(false);
                }
            }
            else
            {
                if (mSegmentsBvh != null)
                {
                    bool insect = mSegmentsBvh.TestIntersection(new GeoAABB2(min, max));
                    if (insect)
                    {
                        return(false);
                    }
                }
                else
                {
                    bool isInconvex = GeoPolygonUtils.IsPointInPolygon2(mPolygonData, ref max);
                    if (!isInconvex)
                    {
                        return(false);
                    }
                    isInconvex = GeoPolygonUtils.IsPointInPolygon2(mPolygonData, ref min);
                    if (!isInconvex)
                    {
                        return(false);
                    }
                    isInconvex = GeoPolygonUtils.IsPointInPolygon2(mPolygonData, ref p2);
                    if (!isInconvex)
                    {
                        return(false);
                    }
                    isInconvex = GeoPolygonUtils.IsPointInPolygon2(mPolygonData, ref p4);
                    if (!isInconvex)
                    {
                        return(false);
                    }
                }
            }
            // 矩形与矩形是否有交叉
            bool isInsectAABB = IsIntersectOtherAABB(min, max);

            if (isInsectAABB)
            {
                return(false);
            }
            return(true);
        }
Пример #7
0
 private bool IsAllConvex()
 {
     return(GeoPolygonUtils.IsConvexPolygon2(mPolygonData));
 }
Пример #8
0
        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);
            }
        }
Пример #9
0
        // 对于环状问题,暂时没处理。处理起来,稍作修改即可。后期遇到时加入(检测环状,然后分离环状,及带孔的多边形环形区域。)
        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;
                    }
                }
            }
        }
Пример #10
0
 private bool IsConvex(int i, int j, int k)
 {
     return(GeoPolygonUtils.IsConvexAngle(mPoints[i], mPoints[j], mPoints[k]));
 }