| 228 | } |
| 229 | |
| 230 | std::tuple<typename aggregate_of<Ifc4x3_add2::IfcObjectDefinition>::ptr, typename aggregate_of<Ifc4x3_add2::IfcSegment>::ptr, Ifc4x3_add2::IfcGradientCurve*> _createVerticalAlignment(IfcHierarchyHelper<Ifc4x3_add2>& file, Ifc4x3_add2::IfcCompositeCurve* composite_curve,const std::vector<std::pair<double, double>>& vpoints, const std::vector<double>& vclengths, bool include_geometry) { |
| 231 | typename aggregate_of<Ifc4x3_add2::IfcObjectDefinition>::ptr vertical_segments(new aggregate_of<Ifc4x3_add2::IfcObjectDefinition>()); // business logic |
| 232 | typename aggregate_of<Ifc4x3_add2::IfcSegment>::ptr vertical_curve_segments(new aggregate_of<Ifc4x3_add2::IfcSegment>()); // geometry |
| 233 | |
| 234 | auto point_iter = vpoints.begin(); |
| 235 | double xPBG, yPBG, xPVI, yPVI; |
| 236 | |
| 237 | boost::tie(xPBG, yPBG) = *point_iter; |
| 238 | |
| 239 | point_iter++; |
| 240 | boost::tie(xPVI, yPVI) = *point_iter; |
| 241 | |
| 242 | double xPFG, yPFG; |
| 243 | for (auto length : vclengths) { |
| 244 | // back gradient |
| 245 | auto dxBG = xPVI - xPBG; |
| 246 | auto dyBG = yPVI - yPBG; |
| 247 | auto start_slope = tan(atan2(dyBG,dxBG)); |
| 248 | |
| 249 | // forward gradient |
| 250 | point_iter++; |
| 251 | std::tie(xPFG, yPFG) = *point_iter; |
| 252 | auto dxFG = xPFG - xPVI; |
| 253 | auto dyFG = yPFG - yPVI; |
| 254 | auto end_slope = tan(atan2(dyFG,dxFG)); |
| 255 | |
| 256 | double xEVC = xPVI + length / 2; |
| 257 | double yEVC = yPVI + end_slope * length / 2; |
| 258 | |
| 259 | // create gradient |
| 260 | { |
| 261 | auto gradient_length = dxBG - length/2; |
| 262 | auto design_parameters = new Ifc4x3_add2::IfcAlignmentVerticalSegment(boost::none, boost::none, xPBG, gradient_length, yPBG, start_slope, start_slope, boost::none, Ifc4x3_add2::IfcAlignmentVerticalSegmentTypeEnum::IfcAlignmentVerticalSegmentType_CONSTANTGRADIENT); |
| 263 | auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters); |
| 264 | vertical_segments->push(alignment_segment); |
| 265 | if (include_geometry) { |
| 266 | vertical_curve_segments->push(mapAlignmentVerticalSegment(design_parameters).first); |
| 267 | } |
| 268 | } |
| 269 | |
| 270 | // create vertical curve |
| 271 | { |
| 272 | double k = (end_slope - start_slope) / length; |
| 273 | double xBVC = xPVI - length / 2; |
| 274 | double yBVC = yPVI - start_slope * length / 2; |
| 275 | |
| 276 | auto design_parameters = new Ifc4x3_add2::IfcAlignmentVerticalSegment(boost::none, boost::none, xBVC, length, yBVC, start_slope, end_slope, 1 / k, Ifc4x3_add2::IfcAlignmentVerticalSegmentTypeEnum::IfcAlignmentVerticalSegmentType_PARABOLICARC); |
| 277 | auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters); |
| 278 | vertical_segments->push(alignment_segment); |
| 279 | if (include_geometry) { |
| 280 | vertical_curve_segments->push(mapAlignmentVerticalSegment(design_parameters).first); |
| 281 | } |
| 282 | } |
| 283 | |
| 284 | xPBG = xEVC; |
| 285 | yPBG = yEVC; |
| 286 | xPVI = xPFG; |
| 287 | yPVI = yPFG; |
no test coverage detected