Пример #1
0
        private static void GetUnitDefinitions(string defPath, string mixPath, out List <BuildingUnit> unitList, out BuildingUnitMix desiredUnitMix)
        {
            unitList = new List <BuildingUnit>();
            var csv = File.ReadAllLines(defPath);

            for (int i = 1; i < csv.Length; i++)
            {
                var lineSplit = csv[i].Split(',');

                unitList.Add(new BuildingUnit(lineSplit[0], lineSplit[1], Convert.ToDouble(lineSplit[2]), Convert.ToDouble(lineSplit[3]), Convert.ToDouble(lineSplit[4]), Convert.ToDouble(lineSplit[5])));
            }

            desiredUnitMix = new BuildingUnitMix();
            csv            = File.ReadAllLines(mixPath);

            for (int i = 1; i < csv.Length; i++)
            {
                var lineSplit = csv[i].Split(',');

                desiredUnitMix.Add(lineSplit[0], Convert.ToDouble(lineSplit[2]));
            }
        }
Пример #2
0
        public static void GetBuildingLayout(List <BuildingUnit> unitList, BuildingUnitMix desiredUnitMix, Line2D mainCorridor, Line2D leftLeg, Line2D middleLeg, Line2D rightLeg, double unitDepth, double hallWidth, out List <Polygon2D> polyUnits, out List <string> unitNames, out List <Line2D> shearWallLines, out List <Line2D> lineList, out MainCorridor mainCorridorOutput)
        {
            var corridors = new List <Corridor>();

            var mainCorridorObject = new MainCorridor();
            var location           = CorridorLocation.Main;

            var corridorLineList = new List <UnitsLine>();

            var leftLegObject = new Corridor();

            if (leftLeg.Length > unitDepth + hallWidth / 2)
            {
                var leftLine2D = CreateLine2D(leftLeg);
                location      = CorridorLocation.LeftLeg;
                leftLegObject = new Corridor(leftLine2D, unitDepth, hallWidth, location);
                corridorLineList.AddRange(leftLegObject.GetLines());
            }

            var midLegObject = new Corridor();

            if (middleLeg.Length > unitDepth + hallWidth / 2)
            {
                var midLine2D = CreateLine2D(middleLeg);
                location     = CorridorLocation.MiddleLeg;
                midLegObject = new Corridor(midLine2D, unitDepth, hallWidth, location);
                corridorLineList.AddRange(midLegObject.GetLines());
            }

            var rightLegObject = new Corridor();

            if (rightLeg.Length > unitDepth + hallWidth / 2)
            {
                var rightLine2D = CreateLine2D(rightLeg);
                location       = CorridorLocation.RightLeg;
                rightLegObject = new Corridor(rightLine2D, unitDepth, hallWidth, location);
                corridorLineList.AddRange(rightLegObject.GetLines());
            }

            var mainLine2D = CreateLine2D(mainCorridor);

            location = CorridorLocation.Main;
            mainCorridorObject.CenterLine       = mainLine2D;
            mainCorridorObject.UnitDepth        = unitDepth;
            mainCorridorObject.HallWidth        = hallWidth;
            mainCorridorObject.CorridorLocation = location;

            mainCorridorObject.LeftLeg   = leftLegObject;
            mainCorridorObject.MiddleLeg = midLegObject;
            mainCorridorObject.RightLeg  = rightLegObject;

            mainCorridorObject.CalculateMainLines();


            var currentPercentage = new BuildingUnitMix();

            foreach (var kvp in desiredUnitMix)
            {
                currentPercentage.Add(kvp.Key, 0);
            }
            corridorLineList.AddRange(mainCorridorObject.GetLines());

            corridorLineList.OrderBy(x => x.Line.Length);
            double usedLength = 0;

            var unitPriority = new List <string>()
            {
                "C",
                "B",
                "A",
                "S"
            };

            var totalUnitList = new List <Tuple <string, double> >();

            polyUnits      = new List <Polygon2D>();
            unitNames      = new List <string>();
            shearWallLines = new List <Line2D>();
            foreach (var corridorLine in corridorLineList)
            {
                var corridorLength = corridorLine.Line.Length;
                var units          = FittingAlgorithm.CreateUnitLine(unitList, desiredUnitMix, corridorLength, ref currentPercentage, unitPriority, ref totalUnitList, ref usedLength);

                var buildingUnits = new List <BuildingUnit>();

                double startLength = 0;
                var    lineVector  = corridorLine.Line.Direction;

                var angle = new Vector2D(1, 0).SignedAngleTo(lineVector);


                foreach (var unit in units)
                {
                    var matchingUnit = unitList.Single(x => (x.Type == unit.Item1 && x.Width == unit.Item2));

                    matchingUnit.Rotation = angle;
                    matchingUnit.Location = corridorLine.Line.StartPoint + startLength * lineVector;

                    var unitPolygon = matchingUnit.GetPolygon();

                    var unitWallLines = matchingUnit.GetShearWallLines();

                    foreach (var unitLine in unitWallLines)
                    {
                        shearWallLines.Add(new Line2D(new Point2D(unitLine.StartPoint.X, unitLine.StartPoint.Y), new Point2D(unitLine.EndPoint.X, unitLine.EndPoint.Y)));
                    }
                    var unitPoints = unitPolygon.ToPolyLine2D().Vertices;

                    var unitPolyline = new Polygon2D(unitPoints);
                    polyUnits.Add(unitPolyline);
                    unitNames.Add(matchingUnit.Type);



                    buildingUnits.Add(matchingUnit);

                    startLength += matchingUnit.Width;
                }

                corridorLine.BuildingUnits = buildingUnits;
            }

            lineList = new List <Line2D>();
            foreach (var corridorLine in corridorLineList)
            {
                lineList.Add(new Line2D(new Point2D(corridorLine.Line.StartPoint.X, corridorLine.Line.StartPoint.Y), new Point2D(corridorLine.Line.EndPoint.X, corridorLine.Line.EndPoint.Y)));
            }

            mainCorridorOutput = mainCorridorObject;
        }
Пример #3
0
        public static List <Tuple <string, double> > CreateUnitLine(List <BuildingUnit> unitList,
                                                                    BuildingUnitMix desiredUnitMix, double corridorLength, ref BuildingUnitMix currentPercentage,
                                                                    List <string> unitPriority, ref List <Tuple <string, double> > totalUnitList, ref double usedLength)
        {
            var unitLine = new List <Tuple <string, double> >();

            var corridorLengthRemaining = corridorLength;

            var minWidth = unitList.Select(x => x.Width).Min();
            var failInt  = 0;

            while (corridorLengthRemaining > 0.001)
            {
                foreach (var unit in unitPriority)
                {
                    if (currentPercentage[unit] < desiredUnitMix[unit])
                    {
                        var availableUnits = unitList.Where(x => x.Type == unit).ToList();
                        var unitLength     = availableUnits.Select(x => x.Width).Min();

                        if (unitLength > corridorLengthRemaining)
                        {
                            continue;
                        }

                        var unitArea = availableUnits.Select(x => x.Area()).Min();

                        usedLength += unitLength;
                        unitLine.Add(new Tuple <string, double>(unit, unitLength));
                        totalUnitList.Add(new Tuple <string, double>(unit, unitLength));

                        corridorLengthRemaining -= unitLength;

                        break;
                    }
                }

                foreach (var unitCheck in unitPriority)
                {
                    var totalUnitLineLength = totalUnitList.Where(x => x.Item1 == unitCheck).Select(x => x.Item2).Sum();

                    currentPercentage[unitCheck] = totalUnitLineLength / usedLength;
                }

                if (corridorLengthRemaining < minWidth)
                {
                    for (int i = 0; i < unitLine.Count; i++)
                    {
                        var unit = unitLine[i];

                        //if (currentPercentage[unit.Item1] < desiredUnitMix[unit.Item1])
                        //{
                        var availableUnits = unitList.Where(x => x.Type == unit.Item1).ToList();
                        var currentUnit    = availableUnits.Single(x => x.Width == unit.Item2);
                        var currentIndex   = availableUnits.IndexOf(currentUnit);

                        unitLine[i] = new Tuple <string, double>(availableUnits[currentIndex + 1].Type, availableUnits[currentIndex + 1].Width);
                        var addedLength = 36;
                        usedLength += addedLength;

                        foreach (var unitCheck in unitPriority)
                        {
                            var totalUnitLineLength = totalUnitList.Where(x => x.Item1 == unitCheck).Select(x => x.Item2).Sum();

                            currentPercentage[unitCheck] = totalUnitLineLength / usedLength;
                        }

                        corridorLengthRemaining -= addedLength;
                        //}

                        if (corridorLengthRemaining < 0.001)
                        {
                            break;
                        }
                    }
                }

                failInt += 1;

                if (failInt > 100)
                {
                    throw new Exception("Solution not found.");
                }
            }

            return(unitLine);
        }