fork download
  1. #include <boost/geometry.hpp>
  2. #include <boost/geometry/geometries/point.hpp>
  3. #include <boost/geometry/geometries/linestring.hpp>
  4. #include <iostream>
  5. #include <cmath>
  6.  
  7. namespace bg = boost::geometry;
  8.  
  9. typedef bg::model::point<double, 2, bg::cs::geographic<bg::degree>> point_type;
  10. typedef bg::model::linestring<point_type> linestring_type;
  11.  
  12. // Конвертация географических координат в ECEF (Earth-Centered, Earth-Fixed)
  13. void geo_to_ecef(double lat, double lon, double& x, double& y, double& z) {
  14. const double R = 6378137.0; // Радиус Земли в метрах
  15. const double lat_rad = lat * M_PI / 180.0;
  16. const double lon_rad = lon * M_PI / 180.0;
  17.  
  18. x = R * cos(lat_rad) * cos(lon_rad);
  19. y = R * cos(lat_rad) * sin(lon_rad);
  20. z = R * sin(lat_rad);
  21. }
  22.  
  23. bool are_collinear(const linestring_type& line1, const linestring_type& line2) {
  24. if (line1.size() < 2 || line2.size() < 2) {
  25. return false;
  26. }
  27.  
  28. // Получаем начальную и конечную точки каждой линии
  29. const point_type& A = line1.front();
  30. const point_type& B = line1.back();
  31. const point_type& C = line2.front();
  32. const point_type& D = line2.back();
  33.  
  34. // Конвертируем в ECEF координаты
  35. double Ax, Ay, Az, Bx, By, Bz, Cx, Cy, Cz, Dx, Dy, Dz;
  36. geo_to_ecef(bg::get<0>(A), bg::get<1>(A), Ax, Ay, Az);
  37. geo_to_ecef(bg::get<0>(B), bg::get<1>(B), Bx, By, Bz);
  38. geo_to_ecef(bg::get<0>(C), bg::get<1>(C), Cx, Cy, Cz);
  39. geo_to_ecef(bg::get<0>(D), bg::get<1>(D), Dx, Dy, Dz);
  40.  
  41. // Вычисляем векторы направлений
  42. double ABx = Bx - Ax;
  43. double ABy = By - Ay;
  44. double ABz = Bz - Az;
  45. double CDx = Dx - Cx;
  46. double CDy = Dy - Cy;
  47. double CDz = Dz - Cz;
  48.  
  49. // Нормализуем векторы
  50. double len_AB = sqrt(ABx*ABx + ABy*ABy + ABz*ABz);
  51. double len_CD = sqrt(CDx*CDx + CDy*CDy + CDz*CDz);
  52. ABx /= len_AB; ABy /= len_AB; ABz /= len_AB;
  53. CDx /= len_CD; CDy /= len_CD; CDz /= len_CD;
  54.  
  55. // Вычисляем векторное произведение
  56. double crossx = ABy*CDz - ABz*CDy;
  57. double crossy = ABz*CDx - ABx*CDz;
  58. double crossz = ABx*CDy - ABy*CDx;
  59. double cross_mag = sqrt(crossx*crossx + crossy*crossy + crossz*crossz);
  60.  
  61. // Если величина векторного произведения близка к нулю, линии колинеарны
  62. return cross_mag < 1e-9;
  63. }
  64.  
  65. int main() {
  66. linestring_type line1, line2;
  67.  
  68. // Инициализация первой линии с заданными координатами
  69. bg::append(line1, point_type(45.094734, 37.565922));
  70. bg::append(line1, point_type(45.094696, 37.566153));
  71.  
  72. // Инициализация второй линии
  73. // Для примера используем другую линию, которую можно заменить
  74. bg::append(line2, point_type(45.094972, 37.565076));
  75. bg::append(line2, point_type(45.094934, 37.565307));
  76.  
  77. // Проверка колинеарности
  78. if (are_collinear(line1, line2)) {
  79. std::cout << "Линии колинеарны." << std::endl;
  80. } else {
  81. std::cout << "Линии не колинеарны." << std::endl;
  82. }
  83.  
  84. return 0;
  85. }
Success #stdin #stdout 0s 5256KB
stdin
Standard input is empty
stdout
Линии не колинеарны.