Пример #1
0
 public static IEnumerable<Spot> GetSpots(RandomPaint proper)
 {
     List<Spot> spots = new List<Spot>();
      for (int i = 0; i < proper.TailCount; i++)
      {
     Spot spot = new Spot(proper);
     spots.Add(spot);
      }
      return spots;
 }
        // Вставка ячейки покраски (пока = одной плитке)
        private void insertSpot(Spot spot, int x, int y, Transaction t)
        {
            Point3d position;

            if (_colorAreaSize.PatternChess)
            {
                double offset = 0;
                if (y % 2 == 0)
                {
                    offset = _colorAreaSize.LenghtSpot * 0.5;
                }
                position = new Point3d(_colorAreaSize.ExtentsColorArea.MinPoint.X + x * _colorAreaSize.LenghtSpot + offset,
                                       _colorAreaSize.ExtentsColorArea.MinPoint.Y + y * _colorAreaSize.HeightSpot, 0);
            }
            else
            {
                position = new Point3d(_colorAreaSize.ExtentsColorArea.MinPoint.X + x * _colorAreaSize.LenghtSpot,
                                       _colorAreaSize.ExtentsColorArea.MinPoint.Y + y * _colorAreaSize.HeightSpot, 0);
            }

            using (IdMapping map = new IdMapping())
            {
                _db.DeepCloneObjects(_idColCopy, _idMS, map, false);
                ObjectId idBlRefCopy = map[_idBlRefColorAreaTemplate].Value;

                if (idBlRefCopy.IsValid && !idBlRefCopy.IsNull)
                {
                    using (var blRefSpot = t.GetObject(idBlRefCopy, OpenMode.ForWrite, false, true) as BlockReference)
                    {
                        blRefSpot.Position = position;
                        blRefSpot.LayerId  = spot.Proper.IdLayer;
                        spot.IdBlRef       = blRefSpot.Id;
                        _countInsertBlocksSpot++;
                    }
                }
            }
        }
        // Огонь
        private void Fire(object sender, EventArgs e)
        {
            try
            {
                // Удаление предыдущей покраски
                if (_spots.Count > 0)
                {
                    deleteSpots(_spots);
                }
                _spots = new List <Spot>();

                List <RandomPaint> propers = ((Dictionary <string, RandomPaint>)sender).Values.ToList();
                _xsize = _colorAreaSize.LenghtSize; //Convert.ToInt32((_extentsPrompted.MaxPoint.X - _extentsPrompted.MinPoint.X) / 300);
                _ysize = _colorAreaSize.HeightSize; //Convert.ToInt32((_extentsPrompted.MaxPoint.Y - _extentsPrompted.MinPoint.Y) / 100);
                int totalTileCount = _xsize * _ysize;
                _ed.WriteMessage("\n");
                _ed.WriteMessage("\n-----------------------------------");
                _ed.WriteMessage($"\nОбщее кол-во зон покраски = {totalTileCount} штук.");
                //Logger.Log.Info("totalTileCount = {0}, xsize={1}, ysize={2}", totalTileCount, _xsize, _ysize);
                int distributedCount = 0;
                foreach (var proper in propers.OrderByDescending(o => o.TailCount))
                {
                    proper.TailCount  = Convert.ToInt32(proper.Percent * totalTileCount / 100d);
                    distributedCount += proper.TailCount;
                    _ed.WriteMessage($"\nРаспределяемый цвет '{proper.LayerName}' - {proper.Percent}% = {proper.TailCount} штук.");
                    //Logger.Log.Info("Распределяемый цвет {0}, процентов {1}, штук {2}", proper.LayerName, proper.Percent, proper.TailCount);
                }

                if (distributedCount > totalTileCount)
                {
                    RandomPaint lastProper = propers.Last();
                    lastProper.TailCount -= distributedCount - totalTileCount;
                    _ed.WriteMessage($"\nУменьшено кол распределяемого цвета '{lastProper.LayerName}' на {(distributedCount - totalTileCount)} штук.");
                    //Logger.Log.Info("Уменьшено кол распр цвета {0} на штук {1}", lastProper.LayerName, (distributedCount - totalTileCount));
                }
                _ed.WriteMessage($"\nВсего рспределено = {distributedCount} ({distributedCount *100 / totalTileCount}%)");
                //Logger.Log.Info("distributedCount = {0}", distributedCount);

                // Сортировка по процентам (начиная с меньшего)
                var propersOrdered = propers.OrderBy(p => p.Percent);
                // Получение общего списка распределения покроаски
                foreach (var proper in propersOrdered)
                {
                    _spots.AddRange(Spot.GetSpots(proper));
                }

                // Распределение зон покраски
                List <Spot> distributedSpots = distributeSpots(_spots, totalTileCount);

                // Вставка блоков зон
                placementSpots(distributedSpots);

                // отчет
                Report(distributedSpots);

                _ed.Regen();
            }
            catch (System.Exception ex)
            {
                _ed.WriteMessage("\n{0}", ex.ToString());
                Logger.Log.Error(ex, "FormProper_Fire()");
            }
        }
        // Вставка ячейки покраски (пока = одной плитке)
        private void insertSpot(Spot spot, int x, int y, Transaction t)
        {
            Point3d position;
            if (_colorAreaSize.PatternChess)
            {
                double offset = 0;
                if (y % 2 == 0)
                {
                    offset = _colorAreaSize.LenghtSpot * 0.5;
                }
                position = new Point3d(_colorAreaSize.ExtentsColorArea.MinPoint.X + x * _colorAreaSize.LenghtSpot + offset,
                                       _colorAreaSize.ExtentsColorArea.MinPoint.Y + y * _colorAreaSize.HeightSpot, 0);
            }
            else
            {
                position = new Point3d(_colorAreaSize.ExtentsColorArea.MinPoint.X + x * _colorAreaSize.LenghtSpot,
                                       _colorAreaSize.ExtentsColorArea.MinPoint.Y + y * _colorAreaSize.HeightSpot, 0);
            }

            using (IdMapping map = new IdMapping())
            {
                _db.DeepCloneObjects(_idColCopy, _idMS, map, false);
                ObjectId idBlRefCopy = map[_idBlRefColorAreaTemplate].Value;

                if (idBlRefCopy.IsValid && !idBlRefCopy.IsNull)
                {
                    using (var blRefSpot = t.GetObject(idBlRefCopy, OpenMode.ForWrite, false, true) as BlockReference)
                    {
                        blRefSpot.Position = position;
                        blRefSpot.LayerId = spot.Proper.IdLayer;
                        spot.IdBlRef = blRefSpot.Id;
                        _countInsertBlocksSpot++;
                    }
                }
            }
        }
 /// <summary>
 /// Определение индексов зон покраски
 /// </summary>
 /// <param name="_spots"></param>
 /// <param name="totalTileCount"></param>
 /// <returns>Список зон покраски с записанными индексами</returns>
 private List<Spot> distributeSpots(List<Spot> _spots, int totalTileCount)
 {
     Spot[] distributeSpots = new Spot[totalTileCount];
     var spotOrdered = _spots.GroupBy(s => s.Proper);
     int countPercent = 0;
     foreach (var spots in spotOrdered)
     {
         countPercent += spots.Key.Percent;
         if (countPercent < 70)
         {
             if (spots.Key.Percent < 25)
             {
                 // Без соседей одного цвета
                 distributeListWithoutNeighborSomeColor(spots.ToList(), totalTileCount, ref distributeSpots);
             }
             else
             {
                 distributeListAllRandom(spots.ToList(), totalTileCount, ref distributeSpots);
             }
         }
         else
         {
             distributeListNear100(spots.ToList(), totalTileCount, ref distributeSpots);
         }
     }
     return distributeSpots.Where(s => s != null).ToList();
 }
        private void distributeListWithoutNeighborSomeColor(List<Spot> spots, int Count, ref Spot[] mixSpots)
        {
            Spot temp;
            bool mayNext = false;
            foreach (var spot in spots)
            {
                do
                {
                    int number = _rnd.Next(Count - 1); // случайное место для размещения зоны покраски
                    temp = mixSpots[number]; // получение спота в этом расположении
                    if (temp == null) // если там никого нет
                    {
                        mayNext = true;
                        // проверка соседа сверху
                        if (number < (Count - 1))
                        {
                            mayNext = checkNeighborSomeColor(mixSpots[number + 1], spot);
                            if (!mayNext) continue;
                        }
                        // проверка соседа снизу
                        if (number > 0)
                        {
                            mayNext = checkNeighborSomeColor(mixSpots[number - 1], spot);
                            if (!mayNext) continue;
                        }
                        // Проверка соседа справа
                        int indexRightHandMan = number - _ysize;
                        if (indexRightHandMan >= 0)
                        {
                            mayNext = checkNeighborSomeColor(mixSpots[indexRightHandMan], spot);
                            if (!mayNext) continue;
                        }
                        int indexLeftHandMan = number + _ysize;
                        if (indexLeftHandMan <= (Count - 1))
                        {
                            mayNext = checkNeighborSomeColor(mixSpots[indexLeftHandMan], spot);
                            if (!mayNext) continue;
                        }

                        if (mayNext)
                        {
                            mixSpots[number] = spot;
                            spot.Index = number;
                        }
                    }
                    else
                    {
                        mayNext = false;
                    }
                } while (!mayNext);
            }
        }
 //private List<Spot> mixingListUpstairsNeighbor(List<Spot> spotsReal, int totalCount)
 //{
 //   Spot[] mixSpots = new Spot[totalCount];
 //   Spot temp;
 //   Spot upstairsNeighbor;
 //   //Spot downstairsNeighbor;
 //   bool mayNext = false;
 //   foreach (var spot in spotsReal)
 //   {
 //      do
 //      {
 //         int number = _rnd.Next(totalCount - 1);
 //         temp = mixSpots[number];
 //         if (temp == null)
 //         {
 //            mayNext = true;
 //            // проверка соседей
 //            if (number < totalCount - 1)
 //            {
 //               upstairsNeighbor = mixSpots[number + 1];
 //               if (upstairsNeighbor != null)
 //               {
 //                  mayNext = false;
 //               }
 //            }
 //            //if (number > 0)
 //            //{
 //            //   downstairsNeighbor = mixSpots[number - 1];
 //            //   if (downstairsNeighbor != null)
 //            //   {
 //            //      mayNext = false;
 //            //   }
 //            //}
 //            if (mayNext)
 //            {
 //               mixSpots[number] = spot;
 //            }
 //         }
 //         else
 //         {
 //            mayNext = false;
 //         }
 //      } while (!mayNext);
 //   }
 //   return mixSpots.ToList();
 //}
 private void distributeListNear100(List<Spot> spots, int Count, ref Spot[] mixSpots)
 {
     Spot temp;
     foreach (var spot in spots)
     {
         int number = _rnd.Next(Count - 1);
         do
         {
             temp = mixSpots[number];
             if (temp == null)
             {
                 mixSpots[number] = spot;
                 spot.Index = number;
             }
             else
             {
                 number++;
                 if (number >= Count)
                 {
                     number = _rnd.Next(Count - 1);
                 }
             }
         } while (temp != null);
     }
 }
 private void distributeListAllRandom(List<Spot> spots, int Count, ref Spot[] mixSpots)
 {
     Spot temp;
     foreach (var spot in spots)
     {
         do
         {
             int number = _rnd.Next(Count - 1);
             temp = mixSpots[number];
             if (temp == null)
             {
                 mixSpots[number] = spot;
                 spot.Index = number;
             }
         } while (temp != null);
     }
 }
 private static bool checkNeighborSomeColor(Spot neighbor, Spot spot)
 {
     if (neighbor != null)
     {
         // если сосед того же цвето, то поиск нового места проживания)
         if (neighbor.Proper.IdLayer == spot.Proper.IdLayer)
         {
             return false;
         }
     }
     return true;
 }