| 4079 | } |
| 4080 | |
| 4081 | std::vector<std::vector<Point3d>> generateSkylightPattern(const std::vector<Space>& spaces, double directionOfRelativeNorth, |
| 4082 | double skylightToProjectedFloorRatio, double desiredWidth, double desiredHeight) { |
| 4083 | std::vector<std::vector<Point3d>> result; |
| 4084 | |
| 4085 | if (skylightToProjectedFloorRatio <= 0.0) { |
| 4086 | return result; |
| 4087 | } else if (skylightToProjectedFloorRatio >= 1.0) { |
| 4088 | return result; |
| 4089 | } |
| 4090 | |
| 4091 | if (desiredWidth <= 0) { |
| 4092 | return result; |
| 4093 | } |
| 4094 | |
| 4095 | if (desiredHeight <= 0) { |
| 4096 | return result; |
| 4097 | } |
| 4098 | |
| 4099 | if (spaces.empty()) { |
| 4100 | return result; |
| 4101 | } |
| 4102 | |
| 4103 | // rotate negative amount around the z axis, EnergyPlus defines rotation clockwise |
| 4104 | Transformation buildingToGridTransformation = Transformation::rotation(Vector3d(0, 0, 1), -openstudio::degToRad(directionOfRelativeNorth)); |
| 4105 | |
| 4106 | // rotate positive amount around the z axis, EnergyPlus defines rotation clockwise |
| 4107 | Transformation gridToBuildingTransformation = buildingToGridTransformation.inverse(); |
| 4108 | |
| 4109 | // find extents in grid coordinate system |
| 4110 | double xmin = std::numeric_limits<double>::max(); |
| 4111 | double xmax = std::numeric_limits<double>::min(); |
| 4112 | double ymin = std::numeric_limits<double>::max(); |
| 4113 | double ymax = std::numeric_limits<double>::min(); |
| 4114 | for (const Space& space : spaces) { |
| 4115 | Transformation spaceToBuildingTransformation = space.buildingTransformation(); |
| 4116 | Transformation transformation = buildingToGridTransformation * spaceToBuildingTransformation; |
| 4117 | for (const Surface& surface : space.surfaces()) { |
| 4118 | if (istringEqual("RoofCeiling", surface.surfaceType()) && istringEqual("Outdoors", surface.outsideBoundaryCondition())) { |
| 4119 | std::vector<Point3d> vertices = transformation * surface.vertices(); |
| 4120 | for (const Point3d& vertex : vertices) { |
| 4121 | xmin = std::min(xmin, vertex.x()); |
| 4122 | xmax = std::max(xmax, vertex.x()); |
| 4123 | ymin = std::min(ymin, vertex.y()); |
| 4124 | ymax = std::max(ymax, vertex.y()); |
| 4125 | } |
| 4126 | } |
| 4127 | } |
| 4128 | } |
| 4129 | if ((xmin > xmax) || (ymin > ymax)) { |
| 4130 | return result; |
| 4131 | } |
| 4132 | |
| 4133 | double floorPrintWidth = (xmax - xmin); |
| 4134 | double floorPrintHeight = (ymax - ymin); |
| 4135 | |
| 4136 | double numSkylightsX = std::sqrt(skylightToProjectedFloorRatio) * floorPrintWidth / desiredWidth; |
| 4137 | double numSkylightsY = std::sqrt(skylightToProjectedFloorRatio) * floorPrintHeight / desiredHeight; |
| 4138 | |