//subdivide a given poly into smaller parts till acceptable width is met, returns list of polydept grids and list of polys to compute circulation
        public static List <List <Polygon2d> > SplitRecursivelyToSubdividePoly(List <Polygon2d> polyList, double acceptableWidth = 10, double circulationFreq = 10, double ratio = 0.5, bool tag = false)
        {
            if (!ValidateObject.CheckPolyList(polyList))
            {
                return(null);
            }

            int count = 0;
            Queue <Polygon2d>        polyQueue = new Queue <Polygon2d>();
            List <List <Polygon2d> > polyAllReturn = new List <List <Polygon2d> >();
            List <Polygon2d>         polyBrokenList = new List <Polygon2d>(), polyCirculationList = new List <Polygon2d>();
            double totalArea = 0; // cirFac = Math.Ceiling(acceptableWidth/ circulationFreq);
            double cirFac = circulationFreq;

            for (int i = 0; i < polyList.Count; i++)
            {
                totalArea += PolygonUtility.AreaPolygon(polyList[i]);
                polyQueue.Enqueue(polyList[i]);
            }
            Random rand = new Random();
            double targetArea = totalArea / cirFac;

            while (polyQueue.Count > 0)
            {
                Polygon2d currentPoly = polyQueue.Dequeue();
                Dictionary <string, object> splitObj = SplitByRatio(currentPoly, ratio, 0);
                if (tag)
                {
                    ratio = BasicUtility.RandomBetweenNumbers(rand, 0.7, 0.35);
                }
                if (splitObj == null)
                {
                    continue;
                }
                List <Polygon2d> polySplitList = (List <Polygon2d>)splitObj["PolyAfterSplit"];
                if (ValidateObject.CheckPolyList(polySplitList) && polySplitList.Count > 1)
                {
                    polySplitList = PolygonUtility.SmoothPolygonList(polySplitList, 2);
                    Polygon2d bbox1 = Polygon2d.ByPoints(ReadData.FromPointsGetBoundingPoly(polySplitList[0].Points));
                    Polygon2d bbox2 = Polygon2d.ByPoints(ReadData.FromPointsGetBoundingPoly(polySplitList[1].Points));
                    if (!ValidateObject.CheckPoly(bbox1) || !ValidateObject.CheckPoly(bbox2))
                    {
                        continue;
                    }

                    if (PolygonUtility.AreaPolygon(polySplitList[0]) > targetArea)
                    {
                        polyCirculationList.Add(polySplitList[0]);
                    }
                    if (PolygonUtility.AreaPolygon(polySplitList[1]) > targetArea)
                    {
                        polyCirculationList.Add(polySplitList[1]);
                    }

                    if (bbox1.Lines[0].Length < acceptableWidth || bbox1.Lines[1].Length < acceptableWidth)
                    {
                        polyBrokenList.Add(polySplitList[0]);
                    }
                    else
                    {
                        polyQueue.Enqueue(polySplitList[0]);
                    }
                    if (bbox2.Lines[0].Length < acceptableWidth || bbox2.Lines[1].Length < acceptableWidth)
                    {
                        polyBrokenList.Add(polySplitList[1]);
                    }
                    else
                    {
                        polyQueue.Enqueue(polySplitList[1]);
                    }
                }
                if (ValidateObject.CheckPolyList(polySplitList) && polySplitList.Count < 2)
                {
                    Polygon2d bbox1 = Polygon2d.ByPoints(ReadData.FromPointsGetBoundingPoly(polySplitList[0].Points));
                    if (!ValidateObject.CheckPoly(bbox1))
                    {
                        continue;
                    }
                    if (bbox1.Lines[0].Length < acceptableWidth || bbox1.Lines[1].Length < acceptableWidth)
                    {
                        polyBrokenList.Add(polySplitList[0]);
                    }
                    if (PolygonUtility.AreaPolygon(polySplitList[0]) > targetArea)
                    {
                        polyCirculationList.Add(polySplitList[0]);
                    }
                    else
                    {
                        polyQueue.Enqueue(polySplitList[0]);
                    }
                }
                count += 1;
            }

            for (int i = 0; i < polyQueue.Count; i++)
            {
                polyBrokenList.Add(polyQueue.Dequeue());
            }
            polyAllReturn.Add(polyBrokenList);
            polyAllReturn.Add(polyCirculationList);
            return(polyAllReturn);
        }
        public static Dictionary <string, object> MakeProgCirculationPolys(List <Line2d> circulationNetwork, List <Polygon2d> polyProgList, double circulationWidth = 8, double circulationFrequency = 0.5, int designSeed = 10)
        {
            if (!ValidateObject.CheckPolyList(polyProgList))
            {
                return(null);
            }
            if (circulationNetwork == null || circulationNetwork.Count == 0)
            {
                return(null);
            }
            List <Line2d> flatLineList    = new List <Line2d>();
            List <bool>   IsDuplicateList = new List <bool>();

            polyProgList = PolygonUtility.SmoothPolygonList(polyProgList, 5);

            //flatten all the polys in each depts to make it one list
            List <Polygon2d> circulationPolyList = new List <Polygon2d>();
            List <Polygon2d> updatedProgPolyList = new List <Polygon2d>();
            List <int>       deptIdList          = new List <int>();
            double           allowedCircRatio    = 4;
            List <double>    areaProgPolyList    = new List <double>();

            for (int i = 0; i < polyProgList.Count; i++)
            {
                areaProgPolyList.Add(PolygonUtility.AreaPolygon(polyProgList[i]));
            }

            double maxArea = areaProgPolyList.Max();

            areaProgPolyList.Sort();
            int    value      = (int)(areaProgPolyList.Count / 3);
            double areaThresh = areaProgPolyList[value];
            Random ran        = new Random(designSeed);

            for (int i = 0; i < circulationNetwork.Count; i++)
            {
                Line2d splitter   = circulationNetwork[i];
                double someNumber = BasicUtility.RandomBetweenNumbers(ran, 1, 0);
                if (someNumber > circulationFrequency)
                {
                    continue;
                }
                for (int j = 0; j < polyProgList.Count; j++)
                {
                    Polygon2d progPoly = polyProgList[j];
                    double    areaPoly = PolygonUtility.AreaPolygon(progPoly);

                    Point2d midPt       = LineUtility.LineMidPoint(splitter);
                    Point2d nudgedMidPt = LineUtility.NudgeLineMidPt(splitter, progPoly, 0.5);
                    bool    checkInside = GraphicsUtility.PointInsidePolygonTest(progPoly, nudgedMidPt);

                    if (checkInside)
                    {
                        Dictionary <string, object> splitResult    = SplitObject.SplitByLine(progPoly, splitter, circulationWidth);
                        List <Polygon2d>            polyAfterSplit = (List <Polygon2d>)(splitResult["PolyAfterSplit"]);
                        if (ValidateObject.CheckPolyList(polyAfterSplit))
                        {
                            double areaA = PolygonUtility.AreaPolygon(polyAfterSplit[0]), areaB = PolygonUtility.AreaPolygon(polyAfterSplit[1]);
                            if (areaA < areaB)
                            {
                                if (polyAfterSplit[0].Points != null)
                                {
                                    if (ValidateObject.CheckPolyBBox(polyAfterSplit[0], allowedCircRatio))
                                    {
                                        circulationPolyList.Add(polyAfterSplit[0]);
                                    }
                                }
                                updatedProgPolyList.Add(polyAfterSplit[1]);
                            }
                            else
                            {
                                if (polyAfterSplit[1].Points != null)
                                {
                                    if (ValidateObject.CheckPolyBBox(polyAfterSplit[1], allowedCircRatio))
                                    {
                                        circulationPolyList.Add(polyAfterSplit[1]);
                                    }
                                }
                                updatedProgPolyList.Add(polyAfterSplit[0]);
                            }
                        } // end of if loop checking polylist
                    }     // end of check inside
                }         // end of for loop j
            }             // end of for loop i

            return(new Dictionary <string, object>
            {
                { "ProgCirculationPoly", (circulationPolyList) }
            });
        }
Exemple #3
0
        //compute glare  values
        public static List <List <double> > ComputeGlareValues(List <Point3d> floorPoints, List <Point3d> furniturePoints,
                                                               List <Point3d> lightPoints, double threshDist = 10, double lightSize = 3, double numSpecialLights = 2, double recompute = 1)
        {
            int           pos      = 0;
            List <double> posList  = new List <double>();
            List <double> distList = new List <double>();
            List <double> ugrList  = new List <double>();
            int           count    = 0;
            double        numD     = BasicUtility.RandomBetweenNumbers(new Random(), 0.1, 0.35);

            for (int i = 0; i < numSpecialLights; i++)
            {
                posList.Add(lightPoints.Count * (i + 1) * numD);
            }

            pos = (int)(lightPoints.Count * 0.20);
            for (int i = 0; i < floorPoints.Count; i++)
            {
                List <Point3d> selectedPts = new List <Point3d>();
                Point2d        pt2FloorPt  = ConvertToPoint2d(floorPoints[i]);
                for (int j = 0; j < furniturePoints.Count; j++)
                {
                    Point2d pt2Furniture = ConvertToPoint2d(furniturePoints[j]);
                    double  distance     = PointUtility.DistanceBetweenPoints(pt2Furniture, pt2FloorPt);
                    distList.Add(distance);
                    if (distance < threshDist)
                    {
                        selectedPts.Add(furniturePoints[j]);
                    }
                }// end of j for loop
                if (selectedPts.Count > 0)
                {
                    lightPoints.AddRange(selectedPts);
                }
                double ugrValue = CalculateUGR(lightPoints, floorPoints[i], posList, lightSize, recompute);
                ugrList.Add(ugrValue);
                count += 1;
            }
            List <double> val2 = new List <double>(), val3 = new List <double>();

            for (int n = 0; n < ugrList.Count; n++)
            {
                val2.Add(0); val3.Add(0);
            }
            List <double>         ugrListNormalized = BasicUtility.NormalizeList(ugrList, 0, 255);
            List <List <double> > result            = new List <List <double> >();

            result.Add(ugrListNormalized);
            result.Add(val2);
            result.Add(val3);
            result.Add(distList);
            result.Add(new List <double> {
                count
            });
            result.Add(ugrList);
            result.Add(new List <double> {
                lightSize
            });
            result.Add(posList);
            return(result);
        }
        [MultiReturn(new[] { "DeptData", "LeftOverPolys" })]//"CirculationPolys", "OtherDeptMainPoly"
        public static Dictionary <string, object> PlaceDepartments2D(List <DeptData> deptData, List <Polygon2d> buildingOutline, List <double> kpuDepthList, List <double> kpuWidthList,
                                                                     double acceptableWidth, double polyDivision = 8, int designSeed = 50, bool noExternalWall = false,
                                                                     bool unlimitedKPU = true, bool mode3D = false, double totalBuildingHeight = 60, double avgFloorHeight = 15)
        {
            if (polyDivision >= 1 && polyDivision < 30)
            {
                BuildLayout.SPACING = polyDivision; BuildLayout.SPACING2 = polyDivision;
            }
            double          circulationFreq = 8;
            List <DeptData> deptDataInp     = deptData;

            deptData = deptDataInp.Select(x => new DeptData(x)).ToList(); // example of deep copy

            Dictionary <string, object> deptArrangement = new Dictionary <string, object>();
            double count = 0, eps = 5;
            Random rand = new Random();
            bool   deptPlaced = false;
            Random ran = new Random(designSeed);
            bool   stackOptionsDept = deptData[0].StackingOptions;
            bool   stackOptionsProg = deptData[0].ProgramsInDept[0].StackingOptions;

            while (deptPlaced == false && count < BuildLayout.MAXCOUNT)//MAXCOUNT
            {
                double parameter = BasicUtility.RandomBetweenNumbers(ran, 0.9, 0.5);
                if (!stackOptionsDept)
                {
                    parameter = 0;
                }
                //parameter = 0;
                Trace.WriteLine("PLACE DEPT STARTS , Lets arrange dept again ++++++++++++++++ : " + count);
                deptArrangement = BuildLayout.DeptPlacer(deptData, buildingOutline, kpuDepthList, kpuWidthList, acceptableWidth, circulationFreq, designSeed, noExternalWall, unlimitedKPU, stackOptionsDept, stackOptionsProg, parameter);
                if (deptArrangement != null)
                {
                    List <DeptData>          deptDataUpdated = (List <DeptData>)deptArrangement["DeptData"];
                    List <List <Polygon2d> > deptAllPolys    = new List <List <Polygon2d> >();
                    for (int i = 0; i < deptDataUpdated.Count; i++)
                    {
                        deptAllPolys.Add(deptDataUpdated[i].PolyAssignedToDept);
                    }
                    List <Polygon2d> deptPolysTogether = new List <Polygon2d>();
                    for (int i = 0; i < deptAllPolys.Count; i++)
                    {
                        if (ValidateObject.CheckPolyList(deptAllPolys[i]))
                        {
                            deptPolysTogether.AddRange(deptAllPolys[i]);
                        }
                    }

                    if (deptAllPolys.Count > 0)
                    {
                        Trace.WriteLine("dept arrangement not null, lets check further");
                    }
                    for (int i = 0; i < deptAllPolys.Count; i++)
                    {
                        List <Polygon2d> eachDeptPoly = deptAllPolys[i];
                        if (ValidateObject.CheckPolyList(eachDeptPoly))
                        {
                            deptPlaced = true;
                        }
                        else
                        {
                            deptPlaced = false; Trace.WriteLine("dept arrangement bad polys, rejected"); break;
                        }
                        bool orthoResult = ValidateObject.CheckPolygon2dListOrtho(deptPolysTogether, eps);
                        Trace.WriteLine("The poly formed is : " + orthoResult);
                        if (orthoResult)
                        {
                            deptPlaced = true;
                        }
                        else
                        {
                            deptPlaced = false; Trace.WriteLine("dept arrangement non orthogonal, rejected"); break;
                        }
                    }
                }
                else
                {
                    deptPlaced  = false;
                    designSeed += 1;
                    Trace.WriteLine("DeptPlacer returned null, rejected for: " + count);
                }
                count += 1;
                Trace.WriteLine(" EXIT PLACE DEPARTMENTS +++++++++++++++++++++++++++++++++");
            }// end of while loop
            return(deptArrangement);
        }
        //sorts a deptdata based on area
        internal static List <DeptData> SortDeptData(List <DeptData> deptDataInp, List <string> preferredDept)
        {
            List <DeptData> deptData = deptDataInp.Select(x => new DeptData(x)).ToList(); // example of deep copy
            SortedDictionary <double, DeptData> sortedD = new SortedDictionary <double, DeptData>();
            List <double> areaList = new List <double>(), weightList = new List <double>();
            List <string> deptFound = new List <string>();

            //Queue<string> preferredDeptQueue = new Queue<string>();
            for (int i = 0; i < preferredDept.Count; i++)
            {
                weightList.Add(10000000 - (i + 1) * 1000);
            }



            for (int i = 0; i < deptData.Count; i++)
            {
                bool match = false;
                for (int j = 0; j < preferredDept.Count; j++)
                {
                    if (preferredDept[j] == deptData[i].DepartmentName)
                    {
                        areaList.Add(weightList[j]);
                        match = true;
                        deptFound.Add(preferredDept[j]);
                        deptData[i].DeptAdjacencyWeight = weightList[j];
                        break;
                    }
                }
                if (!match)
                {
                    areaList.Add(0); deptFound.Add(""); deptData[i].DeptAdjacencyWeight = areaList[i];
                }
            }// end of forloop

            for (int i = 0; i < deptData.Count; i++)
            {
                double surpluss = 0;
                double eps      = i * BasicUtility.RandomBetweenNumbers(new Random(i), 50, 10);

                if (deptData[i].DepartmentType.IndexOf(BuildLayout.KPU.ToLower()) != -1 || deptData[i].DepartmentType.IndexOf(BuildLayout.KPU.ToUpper()) != -1)
                {
                    surpluss = 1000000000 + eps + areaList[i];
                }
                else
                {
                    surpluss = areaList[i];
                }


                double area = 0.25 * deptData[i].DeptAreaNeeded + surpluss;
                deptData[i].DeptAdjacencyWeight = area;
                sortedD.Add(area, deptData[i]);
            }

            List <DeptData> sortedDepartmentData = new List <DeptData>();

            foreach (KeyValuePair <double, DeptData> p in sortedD)
            {
                sortedDepartmentData.Add(p.Value);
            }
            sortedDepartmentData.Reverse();
            return(sortedDepartmentData);
        }
Exemple #6
0
        internal static Dictionary <string, object> FindPreferredProgs(double circulationFactor = 1, int caseStudy = 0, string programDocumentPath = "", bool stackingOptionsProg = false)
        {
            double                dim = 5;
            StreamReader          reader;
            List <string>         progIdList       = new List <string>();
            List <string>         programList      = new List <string>();
            List <string>         deptNameList     = new List <string>();
            List <string>         progQuantList    = new List <string>();
            List <string>         areaEachProgList = new List <string>();
            List <string>         prefValProgList  = new List <string>();
            List <string>         progAdjList      = new List <string>();
            List <string>         progTypeList     = new List <string>();
            List <List <string> > dataStack        = new List <List <string> >();
            List <ProgramData>    programDataStack = new List <ProgramData>();
            Stream                res;

            if (programDocumentPath == "")
            {
                //string[] csvText = Properties.Resources.PROGRAMCSV.Split('\n');
                if (caseStudy == 1)
                {
                    res = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("SpacePlanning.src.Asset.MayoProgram_1.csv");
                }
                else if (caseStudy == 2)
                {
                    res = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("SpacePlanning.src.Asset.OtherProgram.csv");
                }
                else if (caseStudy == 3)
                {
                    res = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("SpacePlanning.src.Asset.ProgramDocument_Reg.csv");
                }
                else if (caseStudy == 4)
                {
                    res = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("SpacePlanning.src.Asset.OtherProgram.csv");
                }
                else if (caseStudy == 5)
                {
                    res = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("SpacePlanning.src.Asset.MULTIDEPT.csv");
                }
                else
                {
                    res = System.Reflection.Assembly.GetExecutingAssembly().GetManifestResourceStream("SpacePlanning.src.Asset.ProgramDocument.csv");
                }

                reader = new StreamReader(res);
            }
            else
            {
                reader = new StreamReader(File.OpenRead(@programDocumentPath));
            }
            int readCount = 0;


            //StreamReader reader = new StreamReader(res);
            string docInfo = reader.ReadToEnd();

            string[] csvText = docInfo.Split('\n');
            //Trace.WriteLine(csvText);
            foreach (string s in csvText)
            {
                if (s.Length == 0)
                {
                    continue;
                }
                var values = s.Split(',');
                if (readCount == 0)
                {
                    readCount += 1; continue;
                }
                progIdList.Add(values[0]);
                programList.Add(values[1]);
                deptNameList.Add(values[2]);
                progQuantList.Add(values[3]);
                prefValProgList.Add(values[6]);
                progTypeList.Add(values[7]);
                progAdjList.Add(values[8]);
                List <Cell> dummyCell = new List <Cell> {
                    new Cell(Point2d.ByCoordinates(0, 0), 0, 0, 0, true)
                };

                ProgramData progData = new ProgramData(Convert.ToInt32(values[0]), values[1], values[2], Convert.ToInt32(Convert.ToDouble(values[3])),
                                                       Convert.ToDouble(values[4]), Convert.ToInt32(values[6]), progAdjList, dummyCell, dim, dim, values[7], stackingOptionsProg); // prev multipled circulationfactor with unit area of prog
                programDataStack.Add(progData);
            }// end of for each statement

            List <string> progAdjId = new List <string>();

            for (int i = 0; i < progIdList.Count; i++)
            {
                string        adjacency = progAdjList[i];
                List <string> adjList   = adjacency.Split('.').ToList();
                progAdjId.AddRange(adjList);
            }
            List <string> strList   = new List <string>();
            List <int>    numIdList = new List <int>();

            for (int i = 0; i < progAdjId.Count; i++)
            {
                strList.Add(progAdjId[i]);
                int value = 0;
                try { value = Int32.Parse(progAdjId[i]); }
                catch { value = (int)BasicUtility.RandomBetweenNumbers(new Random(i), progAdjId.Count - 1, 0); }
                numIdList.Add(value);
                progAdjId[i] = value.ToString();
            }
            List <double> adjWeightList = new List <double>();

            for (int i = 0; i < progIdList.Count; i++)
            {
                int count = 0;
                for (int j = 0; j < progAdjId.Count; j++)
                {
                    if (i == numIdList[j])
                    {
                        count += 1;
                    }
                }
                adjWeightList.Add(count);
            }

            adjWeightList = BasicUtility.NormalizeList(adjWeightList, 0, 10);
            string x = "";

            return(new Dictionary <string, object>
            {
                { "ProgIdList", (progIdList) },
                { "ProgramList", (programList) },
                { "DeptNameList", (deptNameList) },
                { "ProgQuantList", (progQuantList) },
                { "AreaEachProgList", (areaEachProgList) },
                { "ProgPrefValList", (prefValProgList) },
                { "ProgAdjList", (progAdjList) },
                { "ProgAdjWeightList", (adjWeightList) }
            });
        }