//gets the mid point of the furnitures in point3d public static List <Point3d> GetLightingPointsRandomly(List <Cell> cellList, Random ran, double height = 0, double maxNum = 20, double recompute = 5) { double count = 0; List <Point3d> ptList = new List <Point3d>(), lightPtList = new List <Point3d>(); for (int i = 0; i < cellList.Count; i++) { Point3d pt3d = ConvertToPoint3d(cellList[i].CenterPoint, height); ptList.Add(pt3d); } //Random ran = new Random(); for (int i = 0; i < ptList.Count; i++) { count += 1; if (count < maxNum) { double num = BasicUtility.RandomBetweenNumbers(ran, 0, 5); if (num < 3) { lightPtList.Add(ptList[i]); } } } return(lightPtList); }
internal static Dictionary <string, object> FindPreferredProgs(List <string> progIdList, List <string> progAdjList) { 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 <int> numIdList = new List <int>(); for (int i = 0; i < progAdjId.Count; 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); return(new Dictionary <string, object> { { "ProgIdList", (progIdList) }, { "ProgAdjList", (progAdjList) }, { "ProgAdjWeightList", (adjWeightList) } }); }
//gets a poly and recursively splits it till acceptabledimension is met and makes a polyorganized list internal static void MakePolysOfProportion(Polygon2d poly, List <Polygon2d> polyOrganizedList, List <Polygon2d> polycoverList, double acceptableWidth, double targetArea) { BuildLayout.RECURSE += 1; List <double> spanListXY = PolygonUtility.GetSpansXYFromPolygon2d(poly.Points); double spanX = spanListXY[0], spanY = spanListXY[1]; double aspRatio = spanX / spanY; double lowRange = 0.3, highRange = 2; double maxValue = 0.70, minValue = 0.35; double threshDistanceX = acceptableWidth; double threshDistanceY = acceptableWidth; Random ran = new Random(); bool square = true; double div; div = BasicUtility.RandomBetweenNumbers(BuildLayout.RANGENERATE, maxValue, minValue); if (spanX > threshDistanceX && spanY > threshDistanceY) { square = false; } else { if (aspRatio > lowRange && aspRatio < highRange) { square = false; } else { square = true; } } if (square) { polyOrganizedList.Add(poly); } else { Dictionary <string, object> splitResult; //poly is rectangle so split it into two and add if (spanX > spanY) { double dis = spanY * div; int dir = 1; //splitResult = BasicSplitPolyIntoTwo(poly, 0.5, dir); splitResult = SplitObject.SplitByDistance(poly, ran, dis, dir, BuildLayout.SPACING2); //splitResult = SplitByDistanceFromPoint(poly, dis, dir); } else { double dis = spanX * div; int dir = 0; //splitResult = BasicSplitPolyIntoTwo(poly, 0.5, dir); splitResult = SplitObject.SplitByDistance(poly, ran, dis, dir, BuildLayout.SPACING2); //splitResult = SplitByDistanceFromPoint(poly, dis, dir); } List <Polygon2d> polyAfterSplit = (List <Polygon2d>)splitResult["PolyAfterSplit"]; if (ValidateObject.CheckPolyList(polyAfterSplit)) { double areaPolA = PolygonUtility.AreaPolygon(polyAfterSplit[0]); double areaPolB = PolygonUtility.AreaPolygon(polyAfterSplit[1]); if (areaPolA > targetArea) { polycoverList.Add(polyAfterSplit[0]); } if (areaPolB > targetArea) { polycoverList.Add(polyAfterSplit[1]); } List <double> spanA = PolygonUtility.GetSpansXYFromPolygon2d(polyAfterSplit[0].Points); List <double> spanB = PolygonUtility.GetSpansXYFromPolygon2d(polyAfterSplit[1].Points); //Trace.WriteLine("RECURSE is : " + RECURSE); if (BuildLayout.RECURSE < 1500) { if ((spanA[0] > 0 && spanA[1] > 0) || (spanB[0] > 0 && spanB[1] > 0)) { if (spanA[0] > acceptableWidth && spanA[1] > acceptableWidth) { MakePolysOfProportion(polyAfterSplit[0], polyOrganizedList, polycoverList, acceptableWidth, targetArea); } else { polyOrganizedList.Add(polyAfterSplit[0]); double areaPoly = PolygonUtility.AreaPolygon(polyAfterSplit[0]); } //end of 1st if if (spanB[0] > acceptableWidth && spanB[1] > acceptableWidth) { MakePolysOfProportion(polyAfterSplit[1], polyOrganizedList, polycoverList, acceptableWidth, targetArea); } else { polyOrganizedList.Add(polyAfterSplit[1]); } //end of 2nd if } else { polyOrganizedList.Add(polyAfterSplit[0]); polyOrganizedList.Add(polyAfterSplit[1]); } } } // end of if loop , checkingpolylists } } // end of function
//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) } }); }
//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); }
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) } }); }