Cleans a polygon by shrinking and expanding. Can return multiple polygons
| 136 | |
| 137 | // Cleans a polygon by shrinking and expanding. Can return multiple polygons |
| 138 | std::vector<BoostPolygon> removeSpikesEx(const BoostPolygon& polygon) { |
| 139 | |
| 140 | //const double buffer_distance = 1.0; |
| 141 | //const int points_per_circle = 36; |
| 142 | constexpr bool extraLogging = false; |
| 143 | // The amount to shrink and expand the polygons by |
| 144 | constexpr double offsetBy = 0.01; |
| 145 | constexpr double tol = offsetBy; |
| 146 | // Sets the limit to how far miters are extended for sharp corners |
| 147 | constexpr double mitreLimit = 100; |
| 148 | const boost::geometry::strategy::buffer::distance_symmetric<coordinate_type> expand(offsetBy * scaleBy); |
| 149 | const boost::geometry::strategy::buffer::distance_symmetric<coordinate_type> shrink(-offsetBy * scaleBy); |
| 150 | const boost::geometry::strategy::buffer::join_miter join_strategy(mitreLimit * scaleBy); |
| 151 | const boost::geometry::strategy::buffer::end_flat end_strategy; |
| 152 | const boost::geometry::strategy::buffer::side_straight side_strategy; |
| 153 | const boost::geometry::strategy::buffer::point_circle point_strategy; |
| 154 | |
| 155 | BoostMultiPolygon resultExpand; |
| 156 | BoostMultiPolygon resultShrink; |
| 157 | BoostMultiPolygon result; |
| 158 | |
| 159 | // Used for extra logging |
| 160 | BoostMultiPolygon shrinkExpand; |
| 161 | // cppcheck-suppress knownConditionTrueFalse |
| 162 | if constexpr (extraLogging) { |
| 163 | shrinkExpand.push_back(polygon); |
| 164 | } |
| 165 | |
| 166 | // Shrink the polygon |
| 167 | boost::geometry::buffer(polygon, resultShrink, shrink, side_strategy, join_strategy, end_strategy, point_strategy); |
| 168 | // cppcheck-suppress knownConditionTrueFalse |
| 169 | if constexpr (extraLogging) { |
| 170 | shrinkExpand.push_back(resultShrink[0]); |
| 171 | } |
| 172 | |
| 173 | // Inflate the polygon |
| 174 | boost::geometry::buffer(resultShrink, resultExpand, expand, side_strategy, join_strategy, end_strategy, point_strategy); |
| 175 | // cppcheck-suppress knownConditionTrueFalse |
| 176 | if constexpr (extraLogging) { |
| 177 | shrinkExpand.push_back(resultExpand[0]); |
| 178 | } |
| 179 | |
| 180 | // Very small tolerance to remove artifacts from the inflate |
| 181 | constexpr double tol1 = 0.001; |
| 182 | boost::geometry::simplify(resultExpand, result, tol1 * scaleBy); |
| 183 | // cppcheck-suppress knownConditionTrueFalse |
| 184 | if constexpr (extraLogging) { |
| 185 | shrinkExpand.push_back(result[0]); |
| 186 | LOG_FREE(Debug, "Shrink/Expand", shrinkExpand); |
| 187 | } |
| 188 | |
| 189 | std::vector<BoostPolygon> solution; |
| 190 | if (result.empty()) { |
| 191 | // There's no result because the polygon was completely removed so return nothing |
| 192 | return solution; |
| 193 | } else if (result.size() == 1 && result[0].outer().size() == polygon.outer().size()) { |
| 194 | // Number of vertices didn't change so no spikes were removed |
| 195 | solution.push_back(polygon); |
no test coverage detected