fork(1) download
  1. /*
  2. i have an object moving in 2d space. the space is restricted by the screen size defined with HEIGHT,
  3. WIDTH.
  4. the start location of the object is at start_x, start_y. the object moves on a straight line until
  5. it hits the boundary of the screen. i know the moving direction (degrees) of the object, which lies
  6. between 0 and 360 degrees.
  7.  
  8. Q: how can i generate a random point which is on the path the object will move until it reaches the
  9. screen boundary?
  10.  
  11. figure: https://s...content-available-to-author-only...s.com/aww-imagedata/0353066c-5c8f-432f-88a5-9065c52adc07.png
  12. */
  13.  
  14. #include <iostream>
  15. #include <cmath>
  16. #include <cassert>
  17. using namespace std;
  18.  
  19. // range : [min, max]
  20. int random(int min, int max) {
  21. static bool first = true;
  22. if (first) {
  23. srand(time(NULL)); //seeding for the first time only!
  24. first = false;
  25. }
  26. return min + rand() % (max - min + 1);
  27. }
  28.  
  29. bool approximately_equal(float a, float b, float epsilon) {
  30. return fabs(a - b) <= ( (fabs(a) < fabs(b) ? fabs(b) : fabs(a)) * epsilon);
  31. }
  32.  
  33. bool test_is_point_on_path(int start_x, int start_y, int max_x, int max_y, int heading_dir, float point_x, float point_y) {
  34. float curr_x = start_x;
  35. float curr_y = start_y;
  36. float heading_rad = heading_dir * (M_PI / 180);
  37. int inc_Len = 1;
  38. float x_inc = cos(heading_rad) * inc_Len;
  39. float y_inc = sin(heading_rad) * inc_Len;
  40.  
  41. while (curr_x > 0 && curr_x < max_x &&
  42. curr_y > 0 && curr_y < max_y) {
  43.  
  44. if (approximately_equal(curr_x, point_x, 0.02) &&
  45. approximately_equal(curr_y, point_y, 0.02)) {
  46. return true;
  47. }
  48.  
  49. curr_x += x_inc;
  50. curr_y += y_inc;
  51. }
  52.  
  53. return false;
  54. }
  55.  
  56. std::pair<float,float> get_end_point(int start_x, int start_y, int max_x, int max_y, int heading_dir) {
  57. int len = 0;
  58. float end_x = 0;
  59. float prev_end_x = 0;
  60. float end_y = 0;
  61. float prev_end_y = 0;
  62. float heading_rad = heading_dir * (M_PI / 180);
  63.  
  64. while (true) {
  65. end_x = start_x + len * cos(heading_rad);
  66. end_y = start_y + len * sin(heading_rad);
  67.  
  68. if (end_x > max_x || end_x < 0 ||
  69. end_y > max_y || end_y < 0) {
  70. break;
  71. }
  72.  
  73. prev_end_x = end_x;
  74. prev_end_y = end_y;
  75. len++;
  76. }
  77.  
  78. return std::make_pair(prev_end_x, prev_end_y);
  79. }
  80.  
  81. std::pair<float,float> rand_point_on_path(float start_x, float start_y, float end_x, float end_y, int heading_dir) {
  82. float heading_rad = heading_dir * (M_PI / 180);
  83. float delta_x = abs(end_x - start_x);
  84. float delta_y = abs(end_y - start_y);
  85. float max_len = sqrt(delta_x * delta_x + delta_y * delta_y);
  86. int rand_len = random(0, max_len);
  87.  
  88. float calc_x = start_x + rand_len * cos(heading_rad);
  89. float calc_y = start_y + rand_len * sin(heading_rad);
  90.  
  91. return std::make_pair(calc_x, calc_y);
  92. }
  93.  
  94. int main() {
  95. int start_x = 200;
  96. int start_y = 100;
  97. int WIDTH = 500;
  98. int HEIGHT = 500;
  99. int dir = 45;
  100.  
  101. cout << "start_point_x: " << start_x << ", start_point_y: " << start_y << endl;
  102.  
  103. auto end_point = get_end_point(start_x, start_y, WIDTH, HEIGHT, dir);
  104. cout << "end_point_x: " << end_point.first << ", end_point_y: " << end_point.second << endl;
  105.  
  106. auto rand_point = rand_point_on_path(start_x, start_y, end_point.first, end_point.second, dir);
  107. cout << "rand_point_x: " << rand_point.first << ", rand_point_y: " << rand_point.second << endl;
  108.  
  109. assert(test_is_point_on_path(start_x, start_y, WIDTH, HEIGHT, dir, rand_point.first, rand_point.second) == true);
  110.  
  111. return 0;
  112. }
Success #stdin #stdout 0s 3460KB
stdin
Standard input is empty
stdout
start_point_x: 200, start_point_y: 100
end_point_x: 499.813, end_point_y: 399.813
rand_point_x: 451.73, rand_point_y: 351.73