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 |