private void PlaceSideSymbolsConnectionLine(ISchemeSymbol symbol, Sheet sheet, Graphic graphic, double lineHeight, int sheetId, Dictionary<int, double> abscissesByCableId, double centerX, List<CableSymbol> cableSymbols, double turnY, Level level) { int symbolsCount = cableSymbols.Count; if (symbolsCount > 0) { cableSymbols.Sort((bs1, bs2) => Math.Abs(bs1.PlacedPosition.X - centerX).CompareTo(Math.Abs(bs2.PlacedPosition.X - centerX))); // сортировка по удаленности от центра foreach (CableSymbol cableSymbol in cableSymbols) { CableLayout cableLayout = symbol.CableLayoutById[cableSymbol.CableId]; double layoutY = cableLayout.PlacedPoints.First().Y; if (cableLayout.StartOffsets.Count > 1) layoutY = (level == Level.Top) ? sheet.MoveDown(layoutY, radius) : sheet.MoveUp(layoutY, radius); double absciss = abscissesByCableId[cableSymbol.CableId]; double symbolX = cableSymbol.PlacedPosition.X; double symbolY = (level == Level.Top) ? sheet.MoveUp(cableSymbol.PlacedPosition.Y, cableSymbol.Size.Height / 2) : sheet.MoveDown(cableSymbol.PlacedPosition.Y, cableSymbol.Size.Height / 2); if (absciss == symbolX) graphic.CreateLine(sheetId, absciss, layoutY, absciss, symbolY, lineHeight, connectionColorIndex); else { graphic.CreateLine(sheetId, absciss, layoutY, absciss, turnY, lineHeight, connectionColorIndex); graphic.CreateLine(sheetId, absciss, turnY, symbolX, turnY, lineHeight, connectionColorIndex); graphic.CreateLine(sheetId, symbolX, turnY, symbolX, symbolY, lineHeight, connectionColorIndex); } turnY = sheet.MoveUp(turnY, gridStep); } } }
private void CreateTurningConnectingLine(Sheet sheet, Graphic graphic, double lineHeight, int sheetId, Dictionary<int, double> abscissesByCableId, double lastCableLayoutY, CableSymbol cableSymbol, ISchemeSymbol symbol) { double absciss = abscissesByCableId[cableSymbol.CableId]; double symbolX, turnX; if (absciss > cableSymbol.PlacedPosition.X) { symbolX = sheet.MoveRight(cableSymbol.PlacedPosition.X, cableSymbol.Size.Width / 2); turnX = sheet.MoveLeft(symbol.PlacedPosition.X, symbol.LeftMargin + gridStep); } else { symbolX = sheet.MoveLeft(cableSymbol.PlacedPosition.X, cableSymbol.Size.Width / 2); turnX = sheet.MoveRight(symbol.PlacedPosition.X, symbol.RightMargin + gridStep); } double symbolY = cableSymbol.PlacedPosition.Y; graphic.CreateLine(sheetId, absciss, lastCableLayoutY, turnX, lastCableLayoutY, lineHeight, connectionColorIndex); graphic.CreateLine(sheetId, turnX, lastCableLayoutY, turnX, symbolY, lineHeight, connectionColorIndex); graphic.CreateLine(sheetId, turnX, symbolY, symbolX, symbolY, lineHeight, connectionColorIndex); }
private Dictionary<int, double> GetAbscissesByCableId(List<int> maxPositions, List<List<double>> connectionAbscisses, List<CableSymbol> symbols, List<CableLayout> layouts, ISchemeSymbol symbolGroup) { List<int> positions = new List<int>(maxPositions.Count); maxPositions.ForEach(mp=>positions.Add(0)); List<int> optimalPositions = new List<int>(positions); int lastIndex = maxPositions.Count - 1; Dictionary<int, Tuple<double, double>> minMaxByCableId = new Dictionary<int, Tuple<double, double>>(layouts.Count); foreach (CableLayout cableLayout in symbolGroup.CableLayoutById.Values) minMaxByCableId.Add(cableLayout.Id, new Tuple<double,double>(cableLayout.PlacedPoints.Min(p=>p.X), cableLayout.PlacedPoints.Max(p=>p.X))); int minFine = Int32.MaxValue; int variantCount = 1; foreach (int maxPosition in maxPositions) { variantCount *= maxPosition; if (variantCount > 1000000) break; } if (variantCount < 1000000) do { int fine = GetFine(positions, connectionAbscisses, symbols, layouts, symbolGroup, minMaxByCableId); if (fine < minFine) { minFine = fine; optimalPositions = new List<int>(positions); } } while (NextVariant(positions, maxPositions, lastIndex)); else optimalPositions = positions; Dictionary<int, double> abscissesByCableId = new Dictionary<int, double>(); for (int i = 0; i < optimalPositions.Count; i++) { double absciss = connectionAbscisses[i][optimalPositions[i]]; int cableId = symbols[i].CableId; abscissesByCableId.Add(cableId, absciss); } return abscissesByCableId; }
private static int GetFine(List<int> positions, List<List<double>> connectionAbscisses, List<CableSymbol> cableSymbols, List<CableLayout> bottomLayouts, ISchemeSymbol symbol, Dictionary<int, Tuple<double, double>> minMaxByCableId) { int fine; int positionsCount = positions.Count; List<double> abscisses = new List<double>(positionsCount); for (int i = 0; i < positionsCount; i++) abscisses.Add(connectionAbscisses[i][positions[i]]); int overlayCount = positionsCount - abscisses.Distinct().Count(); int intersectionCount = 0; for (int i = 0; i < positionsCount; i++) { double placedX = cableSymbols[i].PlacedPosition.X; double absciss = abscisses[i]; if (placedX < absciss) intersectionCount+= abscisses.Where(a => (a > placedX && a < absciss)).Count(); else intersectionCount += abscisses.Where(a => (a < placedX && a > absciss)).Count(); } int horizontalIntersectionCount = 0; double distanceFromCenterSum = 0; for (int i = 0; i < positionsCount; i++) { int cableId = cableSymbols[i].CableId; CableLayout layout = symbol.CableLayoutById[cableId]; double layoutOffset = layout.verticalOffset; IEnumerable<int> layoutOuterOffsetIds = bottomLayouts.Where(bl => bl.verticalOffset > layoutOffset).Select(bl=>bl.Id); double absciss = abscisses[i]; horizontalIntersectionCount += layoutOuterOffsetIds.Where(id => minMaxByCableId[id].Item1 < absciss && minMaxByCableId[id].Item2 > absciss).Count(); distanceFromCenterSum += GetDistanceFromFreeSpaceCenter(minMaxByCableId, layoutOuterOffsetIds, cableId, absciss); } int straightConenctionCount = 0; for (int i = 0; i < positionsCount; i++) if (cableSymbols[i].PlacedPosition.X == abscisses[i]) straightConenctionCount++; fine = overlayCount * 10000 + intersectionCount * 1000 + horizontalIntersectionCount * 100 - straightConenctionCount * 10 + (int)distanceFromCenterSum; return fine; }