public bool CanContinue()
 {
     return(!mWrapper.IsFull() && mCacheIndex.Count < mProb && mInsertedCount < mInsertMaxCount && mProbTotal > 1e-5f);
 }
        /// <summary>
        /// 1 在某一个段内找不到时,并且找的概率为1,容易出现死循环 nowCount insertMaxCount 来控制 退出循环
        /// 2 wrapper.IsFull() 设置占比,退出循环
        /// 3 cacheIndex.Count < prob 退出循环
        /// </summary>
        /// <param name="original"></param>
        /// <param name="probablities"></param>
        /// <param name="connects"></param>
        /// <returns></returns>
        private static List <List <GeoAABB2> > PolygonPartition(List <Vector2> original, List <PartitionUnit> probablities, List <Vector4> connects = null)
        {
            List <PartitionUnit> newUnits = new List <PartitionUnit>();

            newUnits.AddRange(probablities);
            PolygonWrapper          wrapper     = PolygonWrapper.Create(original, true, connects, 2);
            float                   total       = wrapper.Area;
            int                     prob        = newUnits.Count;
            List <List <GeoAABB2> > results     = new List <List <GeoAABB2> >();
            List <float>            resultsArea = new List <float>();
            List <float>            areaProb    = new List <float>();
            // 更新概率
            float proSum = 0.0f;

            for (int i = 0; i < prob; ++i)
            {
                results.Add(new List <GeoAABB2>());
                resultsArea.Add(0.0f);
                areaProb.Add(newUnits[i].mProbablity);
                proSum += newUnits[i].mProbablity;
            }
            int insertMaxCount            = prob * 10;
            int nowCount                  = 0;
            HashSet <Vector2i> cacheWH    = new HashSet <Vector2i>();
            HashSet <int>      cacheIndex = new HashSet <int>();
            int index = RandomInt(areaProb, proSum);

            while (!wrapper.IsFull() && cacheIndex.Count < prob && nowCount < insertMaxCount)
            {
                float    sizew = RandomUtils.GetRandomFloat(newUnits[index].mMinW, newUnits[index].mMaxW);
                float    sizeh = RandomUtils.GetRandomFloat(newUnits[index].mMinH, newUnits[index].mMaxH);
                Vector2i temp  = new Vector2i((int)(sizew * 100), (int)(sizeh * 100));
                if (!cacheWH.Contains(temp))
                {
                    GeoAABB2 aabb = new GeoAABB2();
                    if (!wrapper.GetRectangle(sizew, sizeh, ref aabb))
                    {
                        cacheWH.Add(temp);
                        if (!cacheIndex.Add(index))
                        {
                            nowCount++;
                        }
                    }
                    else
                    {
                        results[index].Add(aabb);
                        float aabbArea = aabb.Area();
                        resultsArea[index] += aabbArea;
                        cacheIndex.Clear();
                        nowCount = 0;
                        areaProb.Clear();
                        proSum = 0.0f;
                        for (int a = 0; a < prob; ++a)
                        {
                            float newProb = resultsArea[a] / total - newUnits[a].mProbablity;
                            newProb = newProb > 0 ? 0 : -newProb;
                            areaProb.Add(newProb);
                            proSum += newProb;
                        }
                        if (proSum == 0)
                        {
                            break;
                        }
                    }
                }
                else
                {
                    if (!cacheIndex.Add(index))
                    {
                        nowCount++;
                    }
                }
                index = RandomInt(areaProb, proSum);
            }
            for (int a = 0; a < resultsArea.Count; ++a)
            {
                float abs = resultsArea[a] / total;
                Debug.Log(string.Format("count: {0}, xLen: {1}", results[a].Count, abs));
            }
            return(results);
        }
Exemple #3
0
 public bool CanContinue()
 {
     return(!mWrapper.IsFull() && mWrapper.Proportion(mMissCount) < mMissProportion);
 }