fork(1) download
  1. #include <algorithm>
  2. #include <iostream>
  3.  
  4. struct point
  5. {
  6. int x, y;
  7. };
  8.  
  9. inline point operator-(point const & a, point const & b)
  10. {
  11. const point result = {a.x - b.x, a.y - b.y};
  12. return result;
  13. }
  14.  
  15. inline long squared_distance(point const & a, point const & b)
  16. {
  17. const point d = b - a;
  18. return d.x * d.x + d.y * d.y;
  19. }
  20.  
  21. point project_to_units(point const & o, point const & e)
  22. {
  23. const int dx = std::abs(e.x - o.x);
  24. const int dy = std::abs(e.y - o.y);
  25. point result = {e.x, e.y};
  26. if (dy < dx) {
  27. result.x = o.x + (e.y - o.y);
  28. } else if (dx < dy) {
  29. result.y = o.y + (e.x - o.x);
  30. }
  31. return result;
  32. }
  33.  
  34. struct closer_to
  35. {
  36. const point o;
  37.  
  38. closer_to(point const & p) : o(p) {}
  39.  
  40. bool operator()(point const & a, point const & b) const
  41. {
  42. return squared_distance(o, a) < squared_distance(o, b);
  43. }
  44. };
  45.  
  46. point approximate(const point o, const point e)
  47. {
  48. const point points[] = {
  49. {e.x, o.y}, // projection to X
  50. {o.x, e.y}, // projection to Y
  51. project_to_units(o, e) // projection to [(2n+1)*pi / 4] axis
  52. };
  53. return *std::min_element(points, points + 3, closer_to(e));
  54. }
  55.  
  56.  
  57. std::ostream & operator<<(std::ostream & os, point const & p)
  58. {
  59. os << "(" << p.x << ", " << p.y << ")";
  60. return os;
  61. }
  62.  
  63. int main()
  64. {
  65. const point o = {0, 0};
  66.  
  67. const point points[] = {
  68. {-1, -1}, {1, 3}, {2, 2}, {2, 3}
  69. };
  70.  
  71. std::cout << "center: " << o << std::endl;
  72.  
  73. for (std::size_t i = 0; i < sizeof(points)/sizeof(points[0]); ++i) {
  74. const point a = approximate(o, points[i]);
  75. std::cout << "point " << points[i] << ", approx " << a << std::endl;
  76. }
  77. return 0;
  78. }
  79.  
  80.  
Success #stdin #stdout 0s 3340KB
stdin
Standard input is empty
stdout
center: (0, 0)
point (-1, -1), approx (-1, -1)
point (1, 3), approx (0, 3)
point (2, 2), approx (2, 2)
point (2, 3), approx (2, 2)