Korotkodul

геома ОК принадлежность точки многоугольнику

Apr 1st, 2022 (edited)
76
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 4.36 KB | None | 0 0
  1. #include <iostream>
  2. #include <cmath>
  3. #include <vector>
  4. #include <queue>
  5. #include <algorithm>
  6. #include <string>
  7. #include <stack>
  8. #include <set>
  9. #include <map>
  10. #define pii pair <int,int>
  11. #define pld pair <long double, long double>
  12. #define vec vector
  13. using namespace std;
  14. using ll = long long;
  15. using ld = long double;
  16. using db = double;
  17. void cv(vector <int> &v){
  18.     for (auto x: v) cout<<x<<' ';
  19.     cout<<"\n";
  20. }
  21.  
  22. void cvl(vector <ll> &v){
  23.     for (auto x: v) cout<<x<<' ';
  24.     cout<<"\n";
  25. }
  26.  
  27.  
  28. void cvv(vector <vector <int> > &v){
  29.     for (auto x: v) cv(x);
  30.     cout<<"\n";
  31. }
  32.  
  33. void cvb(vector <bool> v){
  34.     for (bool x: v) cout<<x<<' ';
  35.     cout<<"\n";
  36. }
  37.  
  38. void cvs(vector <string>  v){
  39.     for (auto a: v){
  40.         cout<<a<<"\n";
  41.     }
  42. }
  43.  
  44. bool eq(ld x, ld y){//equal
  45.     return fabs(x - y) < 0.01;
  46. }
  47.  
  48.  
  49. struct Rvec{
  50.     ld x, y;
  51.     void mk(Rvec a, Rvec b){//ab
  52.         x = b.x - a.x;
  53.         y = b.y - a.y;
  54.     }
  55.     void sh(){
  56.         cout<<x<<' '<<y<<"\n";
  57.     }
  58.  
  59.     ld len(){
  60.         return sqrtl( powl(x,2) + powl(y,2) );
  61.     }
  62. };
  63.  
  64.  
  65. ld vpr(Rvec a, Rvec b){//vector product
  66.     return a.x * b.y - a.y * b.x;
  67. }
  68.  
  69. int sgn(ld x){
  70.     if (x < 0){
  71.         return -1;
  72.     }
  73.     else if (x==0.0)return 0;
  74.     return 1;
  75. }
  76.  
  77. /*
  78. Есть отрезки AB, CD
  79.  
  80. 1.Проверяем, что C и D лежат по разные стороны  от AB.
  81. Берем векторные произведения :
  82. 1)AC * AB
  83. 2)AD * AB
  84. сравниваем знаки -- если по разные стороны, то зрнаки различаются
  85.  
  86.  
  87.  
  88. 2.Проверяем, что A и B лежат по разные стороны от CD
  89. Берем векторные произведения :
  90. 1)CA * CD
  91. 2)CB * CD
  92. сравниваем знаки -- если по разные стороны, то знаки различаются
  93.  
  94.  
  95. Если условия 1 и 2 выполнились, то отрезки пересекаются.
  96.  
  97. Если зоть одно не выполнилось -- то НЕ ПЕРЕСЕКАЮТСЯ
  98.  
  99. */
  100.  
  101.  
  102.  
  103. bool inter(Rvec A, Rvec B, Rvec C, Rvec D){//AB with CD
  104.     Rvec AB,AC,AD;
  105.     bool a=0,b=0;
  106.     AB.mk(A,B);
  107.     AC.mk(A,C);
  108.     AD.mk(A,D);
  109.  
  110.     if (sgn( vpr(AB, AC) ) != sgn( vpr(AB, AD) )){
  111.         a=1;
  112.     }
  113.     Rvec CD, CA, CB;
  114.     CD.mk(C, D);
  115.     CA.mk(C, A);
  116.     CB.mk(C, B);
  117.     if (sgn(vpr(CD, CA)) != sgn(vpr(CD, CB))){
  118.         b=1;
  119.     }
  120.     return a&&b;
  121. }
  122.  
  123. ld dst(Rvec a, Rvec b){
  124.     return sqrtl ( powl((a.x - b.x), 2) + powl((a.y - b.y), 2) );
  125. }
  126.  
  127. bool in(Rvec A, Rvec B, Rvec C){//A принадлежит BC?
  128.     Rvec BC; BC.mk(B,C);
  129.     /*cout<<"A:\n";
  130.     A.sh();
  131.     cout<<"B C:\n";
  132.     B.sh();
  133.     C.sh();
  134.     cout<<"dst(A, B) + dst(A, C) = "<<dst(A, B) + dst(A, C)<<"\n";
  135.     cout<<"BC.len() = "<<BC.len()<<"\n";*/
  136.     if (eq( dst(A, B) + dst(A, C) , BC.len())) {
  137.         return 1;
  138.     }
  139.     return 0;
  140. }
  141.  
  142.  
  143. int main()
  144. {
  145.     ios::sync_with_stdio(0);
  146.     cin.tie(0);
  147.     cout.tie(0);
  148.     cout.precision(4);
  149.     Rvec A,B;//B -- произвольная точка
  150.     int n;
  151.     cin>>n>>A.x>>A.y;
  152.     B = {A.x + 1e3, A.y + 1e1};
  153.     /*cout<<"A B\n";
  154.     A.sh();
  155.     B.sh();*/
  156.     vector <Rvec> v(n);
  157.     bool inv=0;
  158.     for (int i = 0; i < n; ++i){
  159.         cin>>v[i].x>>v[i].y;
  160.         if (v[i].x == A.x && v[i].y == A.y ){
  161.             inv=1;
  162.             //cout<<"INV\n";
  163.         }
  164.     }
  165.     if (inv){
  166.         cout<<"YES\n";
  167.         exit(0);
  168.     }
  169.     int cnt=0;
  170.     if (inter(A,B, v[n-1], v[0])){
  171.             cnt++;
  172.     }
  173.     /*cout<<"check IN sect\n";
  174.     v[n-1].sh();
  175.     v[0].sh();*/
  176.     if (in(A, v[n-1], v[0])){
  177.  
  178.             cout<<"YES\n";
  179.             exit(0);
  180.         }
  181.     //cout<<"check\n";
  182.     for (int i = 1; i < n ;++i){
  183.         if (inter(A,B, v[i-1], v[i])){
  184.             cnt++;
  185.  
  186.            /* v[i-1].sh();
  187.             v[i].sh();
  188.             cout<<"\n"; */
  189.         }
  190.  
  191.  
  192.         /*cout<<"check IN sect\n";
  193.         v[i-1].sh();
  194.         v[i].sh();*/
  195.         if (in(A, v[i-1], v[i])){
  196.             cout<<"YES\n";
  197.             exit(0);
  198.         }
  199.     }
  200.     //cout<<"cnt = "<<cnt<<"\n";
  201.     if (cnt % 2 == 1){
  202.         cout<<"YES\n";
  203.     }
  204.     else{
  205.         cout<<"NO\n";
  206.     }
  207. }//+ проверить принадлежность точки отрезку
  208. /*
  209. 3 2 3
  210. 1 1
  211. 10 2
  212. 2 8
  213.  
  214. 3 2 3
  215. 1 1
  216. 10 2
  217. -10 100
  218.  
  219.  
  220. 4 0 0
  221. 0 0
  222. 4 8
  223. 10 0
  224. 6 2
  225.  
  226. 5 10 0.1
  227. 4 8
  228. 11 0
  229. 8 0
  230. 6 2
  231. 0 0
  232. */
  233.  
Add Comment
Please, Sign In to add comment