geometry.cpp 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. #include <iostream>
  2. #ifdef HAS_OPENCV3
  3. #include <opencv2/core.hpp> //Any OPENCV3 code
  4. #else
  5. #include <opencv2/core/core.hpp> //Any Opencv2 code
  6. #endif
  7. using namespace cv;
  8. #include "geometry.h"
  9. double dist(Point a, Point b)
  10. {
  11. return sqrt((double)pow(a.x-b.x,2)+pow(a.y-b.y,2));
  12. }
  13. double inner_angle(Point a, Point middle, Point b)
  14. {
  15. Point v1 = a - middle;
  16. Point v2 = b - middle;
  17. double v1_length = dist(Point(0, 0), v1);
  18. double v2_length = dist(Point(0, 0), v2);
  19. return acos( (v1.x*v2.x + v1.y*v2.y) / (v1_length*v2_length) );
  20. }
  21. CoordinateSystem::CoordinateSystem(double angle, Point a)
  22. {
  23. theta = angle;
  24. origin = a;
  25. precompute();
  26. assert(map(a) == Point(0,0));
  27. assert(unmap(Point(0,0)) == a);
  28. }
  29. CoordinateSystem::CoordinateSystem(Point a, Point b)
  30. {
  31. theta = atan2(b.y-a.y, b.x-a.x);
  32. origin = a;
  33. precompute();
  34. assert(map(a) == Point(0,0));
  35. assert(unmap(Point(0,0)) == a);
  36. assert(map(b).y == 0);
  37. assert(map(b).x > 0);
  38. }
  39. void CoordinateSystem::precompute() {
  40. double costheta = cos(theta);
  41. double sintheta = sin(theta);
  42. R(0,0) = costheta;
  43. R(0,1) = -sintheta;
  44. R(1,0) = sintheta;
  45. R(1,1) = costheta;
  46. Rt(0,0) = costheta;
  47. Rt(0,1) = sintheta;
  48. Rt(1,0) = -sintheta;
  49. Rt(1,1) = costheta;
  50. }
  51. Point CoordinateSystem::map(Point tomap) {
  52. //that's the algorithm: res = Rt*(tomap - origin)
  53. cv::Vec<double,2> p_as_vector;
  54. Point p;
  55. p = tomap - origin;
  56. p_as_vector[0] = p.x;
  57. p_as_vector[1] = p.y;
  58. cv::Vec<double,2> res_as_vector = Rt*p_as_vector;
  59. return Point(res_as_vector);
  60. }
  61. Point CoordinateSystem::unmap(Point tounmap) {
  62. cv::Vec<double,2> q_as_vector;
  63. q_as_vector[0] = tounmap.x;
  64. q_as_vector[1] = tounmap.y;
  65. Point RQ = Point(R*q_as_vector);
  66. return Point(RQ + origin);
  67. }
  68. Point
  69. map_point(double theta, Point origin, Point tomap)
  70. {
  71. auto cs = CoordinateSystem(theta, origin);
  72. return cs.map(tomap);
  73. }
  74. Point
  75. unmap_point(double theta, Point origin, Point tounmap)
  76. {
  77. return CoordinateSystem(theta, origin).unmap(tounmap);
  78. }
  79. //that's the algorithm: res = Rt*(tomap - origin)
  80. cv::Vec<double,3>
  81. get_line(Point p, Point q)
  82. {
  83. cv::Vec<double,3> line; //the three positions are a,b,c as in: ax + by + c = 0
  84. Point vector = q-p;
  85. line(0) = - vector.y;
  86. line(1) = vector.x;
  87. line(2) = vector.y * p.x - vector.x * p.y;
  88. assert(is_in_line(line, p));
  89. assert(is_in_line(line, q));
  90. return line;
  91. }
  92. bool
  93. is_in_line(cv::Vec<double,3> line, Point p)
  94. {
  95. return line(0)*p.x + line(1)*p.y + line(2) == 0;
  96. }
  97. bool
  98. is_above_line(cv::Vec<double,3> line, Point p)
  99. {
  100. return line(0)*p.x + line(1)*p.y + line(2) > 0;
  101. }