creates a horizontal alignment using a vector of PI points and curve radii returns a list of object definitions, curve segments, and a composite curve
| 73 | // creates a horizontal alignment using a vector of PI points and curve radii |
| 74 | // returns a list of object definitions, curve segments, and a composite curve |
| 75 | std::tuple<typename aggregate_of<Ifc4x3_add2::IfcObjectDefinition>::ptr, typename aggregate_of<Ifc4x3_add2::IfcSegment>::ptr, Ifc4x3_add2::IfcCompositeCurve*> _createHorizontalAlignment(IfcHierarchyHelper<Ifc4x3_add2>& file, const std::vector<std::pair<double, double>>& points, const std::vector<double>& radii,bool include_geometry) { |
| 76 | typename aggregate_of<Ifc4x3_add2::IfcObjectDefinition>::ptr horizontal_segments(new aggregate_of<Ifc4x3_add2::IfcObjectDefinition>()); // business logic |
| 77 | typename aggregate_of<Ifc4x3_add2::IfcSegment>::ptr horizontal_curve_segments(include_geometry ? new aggregate_of<Ifc4x3_add2::IfcSegment>() : nullptr); // geometry |
| 78 | |
| 79 | auto point_iter = points.begin(); |
| 80 | double xBT, yBT, xPI, yPI; |
| 81 | |
| 82 | boost::tie(xBT, yBT) = *point_iter; |
| 83 | |
| 84 | point_iter++; |
| 85 | boost::tie(xPI, yPI) = *point_iter; |
| 86 | |
| 87 | double xFT, yFT; |
| 88 | for (auto radius : radii) { |
| 89 | // back tangent |
| 90 | auto dxBT = xPI - xBT; |
| 91 | auto dyBT = yPI - yBT; |
| 92 | auto angleBT = atan2(dyBT, dxBT); |
| 93 | auto lengthBT = sqrt(dxBT * dxBT + dyBT * dyBT); |
| 94 | |
| 95 | // forward tangent |
| 96 | point_iter++; |
| 97 | std::tie(xFT, yFT) = *point_iter; |
| 98 | auto dxFT = xFT - xPI; |
| 99 | auto dyFT = yFT - yPI; |
| 100 | auto angleFT = atan2(dyFT, dxFT); |
| 101 | |
| 102 | auto delta = angleFT - angleBT; |
| 103 | |
| 104 | auto tangent = fabs(radius * tan(delta / 2)); |
| 105 | |
| 106 | auto lc = fabs(radius * delta); |
| 107 | |
| 108 | radius *= delta / fabs(delta); |
| 109 | |
| 110 | auto xPC = xPI - tangent * cos(angleBT); |
| 111 | auto yPC = yPI - tangent * sin(angleBT); |
| 112 | |
| 113 | auto xPT = xPI + tangent * cos(angleFT); |
| 114 | auto yPT = yPI + tangent * sin(angleFT); |
| 115 | |
| 116 | auto tangent_run = lengthBT - tangent; |
| 117 | |
| 118 | // create back tangent run |
| 119 | { |
| 120 | auto pt = file.addDoublet<Ifc4x3_add2::IfcCartesianPoint>(xBT, yBT); |
| 121 | auto design_parameters = new Ifc4x3_add2::IfcAlignmentHorizontalSegment(boost::none, boost::none, pt, angleBT, 0.0, 0.0, tangent_run, boost::none, Ifc4x3_add2::IfcAlignmentHorizontalSegmentTypeEnum::IfcAlignmentHorizontalSegmentType_LINE); |
| 122 | auto alignment_segment = new Ifc4x3_add2::IfcAlignmentSegment(IfcParse::IfcGlobalId(), nullptr, boost::none, boost::none, boost::none, nullptr, nullptr, design_parameters); |
| 123 | horizontal_segments->push(alignment_segment); |
| 124 | |
| 125 | if (include_geometry) { |
| 126 | horizontal_curve_segments->push(mapAlignmentHorizontalSegment(design_parameters).first); |
| 127 | } |
| 128 | } |
| 129 | |
| 130 | // create circular curve |
| 131 | { |
| 132 | auto pc = file.addDoublet<Ifc4x3_add2::IfcCartesianPoint>(xPC, yPC); |
no test coverage detected