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; }