Advertisement
Guest User

Untitled

a guest
May 24th, 2019
72
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.08 KB | None | 0 0
  1. #pragma once
  2.  
  3. #include <vector>
  4. #include <utility>
  5. #include <iostream>
  6. #include <cassert>
  7.  
  8. #include "vec2.hpp"
  9.  
  10. template <typename T>
  11. int orientation(vec2<T> p1, vec2<T> p2, vec2<T> p3) {
  12. T val = (p2.y - p1.y) * (p3.x - p2.x) -
  13. (p2.x - p1.x) * (p3.y - p2.y);
  14. if (val == 0) return 0;
  15. if (val < 0) return -1;
  16. return 1;
  17. }
  18.  
  19. /* p has to be coolinear to the segment s */
  20. template <typename T>
  21. bool on_segment(std::pair<vec2<T>, vec2<T>> s, vec2<T> p) {
  22. if (p.x <= std::max(s.first.x, s.second.x) && p.x >= std::min(s.first.x, s.second.x) &&
  23. p.y <= std::max(s.first.y, s.second.y) && p.y >= std::min(s.first.y, s.second.y)) {
  24. return true;
  25. }
  26. return false;
  27. }
  28.  
  29. template <typename T>
  30. std::vector<vec2<T>>
  31. intersect(std::pair<vec2<T>, vec2<T>> l1, std::pair<vec2<T>,vec2<T>> l2) {
  32. if (l2 < l1) {
  33. std::swap(l1, l2);
  34. }
  35.  
  36. auto [p1, p2] = l1;
  37. auto [p3, p4] = l2;
  38.  
  39. if ( cross((p2 - p1), (p4 - p3)) == T(0l)) {
  40. if (orientation(p1, p3, p2)) {
  41. return {};
  42. }
  43.  
  44. auto v1 = p2 - p1;
  45. T denom = dot(p2 - p1, p2 - p1);
  46. T alpha1 = dot(p3 - p1, p2 - p1);
  47. T alpha2 = dot(p4 - p1, p2 - p1);
  48. if (alpha1 > alpha2) {
  49. std::swap(alpha1, alpha2);
  50. }
  51. //check if segments overlap
  52. std::pair<T, T> isec = { std::max(T(0), alpha1),
  53. std::min(denom, alpha2)};
  54. if (isec.second < isec.first) return {};
  55. if (isec.first == isec.second)
  56. return {p1 + (isec.first/denom) * v1};
  57.  
  58. return {p1 + (isec.first/ denom) * v1,
  59. p1 + (isec.second / denom) * v1};
  60. } else {
  61. /* find t and u*/
  62. T t(cross((p4 - p1), (p4 - p3)).numer, cross((p2 - p1), (p4 - p3)).numer);
  63. T s(cross((p2 - p3), (p2 - p1)).numer, cross((p4 - p3), (p2 - p1)).numer);
  64. auto v1 = p2 - p1;
  65. //check if s and t is between 0 and 1
  66. if (t < T(0l) || t > T(1l)) return {};
  67. if (s < T(0l) || s > T(1l)) return {};
  68.  
  69. return {p3 + s * (p4 - p3)};
  70. }
  71. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement