| 196 glm::vec2{rectangle.right(), rectangle.top()}, |
196 glm::vec2{rectangle.right(), rectangle.top()}, |
| 197 glm::vec2{rectangle.right(), rectangle.bottom()} |
197 glm::vec2{rectangle.right(), rectangle.bottom()} |
| 198 }; |
198 }; |
| 199 } |
199 } |
| 200 |
200 |
| 201 bool isConvex(const Quadrilateral& quad) |
201 static convexity_e determine_convexity(const glm::vec3* begin, const glm::vec3* end) |
| 202 { |
202 { |
| 203 glm::vec3 crosses[4] = { |
203 auto test_concave_dot_product = [begin](const glm::vec3& vector) { |
| |
204 return glm::dot(*begin, vector) < 1e-6; |
| |
205 }; |
| |
206 if (std::any_of(begin + 1, end, test_concave_dot_product)) |
| |
207 { |
| |
208 return convexity_e::concave; |
| |
209 } |
| |
210 else |
| |
211 { |
| |
212 return convexity_e::convex; |
| |
213 } |
| |
214 } |
| |
215 |
| |
216 convexity_e quadrilateral_convexity(const Quadrilateral& quad) |
| |
217 { |
| |
218 const glm::vec3 crosses[4] = { |
| 204 glm::cross(quad.p4 - quad.p1, quad.p2 - quad.p1), |
219 glm::cross(quad.p4 - quad.p1, quad.p2 - quad.p1), |
| 205 glm::cross(quad.p1 - quad.p2, quad.p3 - quad.p2), |
220 glm::cross(quad.p1 - quad.p2, quad.p3 - quad.p2), |
| 206 glm::cross(quad.p2 - quad.p3, quad.p4 - quad.p3), |
221 glm::cross(quad.p2 - quad.p3, quad.p4 - quad.p3), |
| 207 glm::cross(quad.p3 - quad.p4, quad.p1 - quad.p4), |
222 glm::cross(quad.p3 - quad.p4, quad.p1 - quad.p4), |
| 208 }; |
223 }; |
| 209 return not std::any_of( |
224 return determine_convexity(&crosses[0], &crosses[4]); |
| 210 &crosses[1], |
225 } |
| 211 &crosses[4], |
226 |
| 212 [&crosses](const glm::vec3& vector) { |
227 convexity_e polygon_convexity(const std::vector<glm::vec3>& polygon) |
| 213 return glm::dot(crosses[0], vector) < 1e-6; |
|
| 214 }); |
|
| 215 } |
|
| 216 |
|
| 217 bool isConvex(const std::vector<glm::vec3>& polygon) |
|
| 218 { |
228 { |
| 219 const std::size_t n = polygon.size(); |
229 const std::size_t n = polygon.size(); |
| 220 std::vector<glm::vec3> crosses; |
230 std::vector<glm::vec3> crosses; |
| 221 crosses.resize(n); |
231 crosses.resize(n); |
| 222 for (std::size_t i = 0; i < n; i += 1) |
232 for (std::size_t i = 0; i < n; i += 1) |
| 224 const glm::vec3 v1 = polygon[(i + n - 1) % n]; |
234 const glm::vec3 v1 = polygon[(i + n - 1) % n]; |
| 225 const glm::vec3 v2 = polygon[i]; |
235 const glm::vec3 v2 = polygon[i]; |
| 226 const glm::vec3 v3 = polygon[(i + 1) % n]; |
236 const glm::vec3 v3 = polygon[(i + 1) % n]; |
| 227 crosses[i] = glm::cross(v1 - v2, v3 - v2); |
237 crosses[i] = glm::cross(v1 - v2, v3 - v2); |
| 228 } |
238 } |
| 229 return not std::any_of( |
239 return determine_convexity(&crosses[0], &crosses[n]); |
| 230 crosses.begin() + 1, |
|
| 231 crosses.end(), |
|
| 232 [&crosses](const glm::vec3& vector) |
|
| 233 { |
|
| 234 return glm::dot(crosses[0], vector) < 1e-6; |
|
| 235 }); |
|
| 236 } |
240 } |
| 237 |
241 |
| 238 /** |
242 /** |
| 239 * @brief Determines the winding of a 2d polygon |
243 * @brief Determines the winding of a 2d polygon |
| 240 * @param polygon |
244 * @param polygon |