card_path.cpp 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764
  1. #include "stdafx.h"
  2. #include <stdio.h>
  3. #include <algorithm>
  4. #include <unordered_map>
  5. #include <set>
  6. #include <memory>
  7. #include <atomic>
  8. #include <thread>
  9. #include "zlist.h"
  10. #include "line.h"
  11. #include "ant.h"
  12. #include "card_path.h"
  13. #include "ProcessRemodule.h"
  14. NAMESPACE_POINT_BEGIN (NAMESPACE_POINT)
  15. static const double PI=3.1416;
  16. inline bool eq(double a,double b,double e=0.0001)
  17. {
  18. return fabs(a-b)<e;
  19. }
  20. struct vertex:point
  21. {
  22. float level;
  23. int sid0,sid1;
  24. vertex()
  25. :level(0)
  26. ,sid0(0)
  27. ,sid1(0)
  28. {}
  29. vertex(const point&pt,float level_=0,int site_id0=0,int site_id1=0)
  30. :point(pt)
  31. ,level(level_)
  32. ,sid0(site_id0)
  33. ,sid1(site_id1)
  34. {
  35. }
  36. std::string to_string()const
  37. {
  38. char buf[128];
  39. sprintf(buf,"%.2f,%.3lf,%d,%d,%.2lf",x,y,sid0,sid1,level/PI*180);
  40. return buf;
  41. }
  42. };
  43. struct vertex_list;
  44. struct base_path:std::array<int,2>
  45. {
  46. int sid;
  47. base_path(int i1=-1,int i2=-1)
  48. {
  49. at(0)=i1;
  50. at(1)=i2;
  51. }
  52. bool operator<( const base_path&o)const
  53. {
  54. int c=at(0)-o.at(0);
  55. if(c!=0)
  56. return c<0;
  57. return at(1)-o.at(1)<0;
  58. }
  59. point cross(const vertex_list&v_list, const base_path&o)const;
  60. bool contains(const vertex_list&v_list, const point&o, double e)const;
  61. double arg(const vertex_list&v)const;
  62. int type(const vertex_list&v)const;
  63. line_v as_line(const vertex_list&v)const;
  64. int level(const vertex_list&v)const;
  65. };
  66. struct vertex_list
  67. {
  68. std::vector<vertex> v;
  69. std::string to_string()const
  70. {
  71. std::string ret;
  72. ret.reserve(1024);
  73. char buf[128];
  74. for(int i=0,len=v.size();i<len;i++)
  75. {
  76. sprintf(buf,"vertex:%3d,%s\n",i,v[i].to_string().c_str());
  77. ret+=buf;
  78. }
  79. return std::move(ret);
  80. }
  81. void log()
  82. {
  83. printf("%s",to_string().c_str());
  84. }
  85. static unsigned hash(const point&p)
  86. {
  87. return (((((unsigned)p.x)>>2)<<16) + (((unsigned)p.y)>>2));
  88. }
  89. int find(const point&p,double x=1)const
  90. {
  91. int rc=-1;
  92. double t;
  93. for(int i=0,len=v.size();i<len;i++)
  94. {
  95. t=p.dist(v[i]);
  96. if(t<x)
  97. {
  98. rc=i;
  99. x=t;
  100. }
  101. }
  102. return rc;
  103. }
  104. int add(const point&p,float level=0,int sid0=0,int sid1=0)
  105. {
  106. int i=find(p);
  107. if(i<0)
  108. {
  109. v.push_back(vertex(p,level,sid0,sid1));
  110. return v.size()-1;
  111. }
  112. vertex&v0=v[i];
  113. v0.level=max(v0.level,level);
  114. return i;
  115. }
  116. int size()const
  117. {
  118. return v.size();
  119. }
  120. const vertex&operator[](int i)const
  121. {
  122. return v[i];
  123. }
  124. vertex&operator[](int i)
  125. {
  126. return v[i];
  127. }
  128. };
  129. int base_path::level(const vertex_list&v)const
  130. {
  131. const vertex&p0=v[at(0)];
  132. const vertex&p1=v[at(1)];
  133. return p0.level+p1.level;
  134. }
  135. line_v base_path::as_line(const vertex_list&v)const
  136. {
  137. const vertex&p0=v[at(0)];
  138. const vertex&p1=v[at(1)];
  139. return line_v(p0,p1);
  140. }
  141. double base_path::arg(const vertex_list&v)const
  142. {
  143. return as_line(v).arg();
  144. }
  145. bool base_path::contains(const vertex_list&v, const point&o, double e)const
  146. {
  147. return as_line(v).contain(o,e);
  148. }
  149. point base_path::cross(const vertex_list&v, const base_path&o)const
  150. {
  151. line_v l0=as_line(v);
  152. line_v l1=o.as_line(v);
  153. return l0.crossing(l1);
  154. }
  155. #if 0
  156. void log_path(const std::vector<base_path>&path,const vertex_list&v_list)
  157. {
  158. printf("%s\n","----------------------------------------------------------------");
  159. for(int i=0,len=path.size();i<len;i++)
  160. {
  161. double c=path[i].arg(v_list)/PI*180;
  162. printf("base_path %.6lf, %03d,(%d,%s),(%d,%s)\n",c,i,path[i][0],v_list[path[i][0]].to_string().c_str(),path[i][1],v_list[path[i][1]].to_string().c_str());
  163. }
  164. }
  165. #endif
  166. static std::vector<base_path> init_path(const sit_list&sites,vertex_list&v)
  167. {
  168. std::vector<base_path> ret;
  169. for(uint32_t i=0;i<sites.m_list.size();i++)
  170. {
  171. auto&s=sites[i];
  172. if(!s.have_valid_path())
  173. continue;
  174. if(s.path(0).empty()||s.path(1).empty())
  175. continue;
  176. line x(s.path(0),s.path(1));
  177. if(x.contain(s,2.5))
  178. {
  179. int p0=v.add(point::min_(s.path(0),s.path(1)),0,s.m_id);
  180. int p1=v.add(point::max_(s.path(0),s.path(1)),0,s.m_id);
  181. ret.push_back(base_path(p0,p1));
  182. ret.back().sid=s.m_id;
  183. continue;
  184. }
  185. for(int j=0;j<2;j++)
  186. {
  187. if(!s.path(j).empty() && s.dist(s.path(j))<2)
  188. continue;
  189. point p=s.path(j);
  190. int p0=v.add(point::min_(s,p),0,s.m_id);
  191. int p1=v.add(point::max_(s,p),0,s.m_id);
  192. ret.push_back(base_path(p0,p1));
  193. ret.back().sid=s.m_id;
  194. }
  195. }
  196. std::sort(ret.begin(),ret.end());
  197. ret.erase(std::unique(ret.begin(),ret.end()),ret.end());
  198. std::sort(ret.begin(),ret.end(),[&v](base_path&p1,base_path&p2){
  199. double arg=p1.arg(v)-p2.arg(v);
  200. if(fabs(arg)<0.1)
  201. {
  202. return v[p1[0]]<v[p2[0]];
  203. }
  204. return arg<0;
  205. });
  206. // log_path(ret,v);
  207. for(int i=0,len=ret.size();i<len;i++)
  208. {
  209. line_v li=ret[i].as_line(v);
  210. for(int j=i+1;j<len;j++)
  211. {
  212. line_v lj=ret[j].as_line(v);
  213. if(!lj.is_same(li,2.5))
  214. continue;
  215. line_v ij=lj.projection(li);
  216. if(ij.empty())
  217. continue;
  218. point p0=point::min_(v[ret[j][0]],v[ret[i][0]]);
  219. point p1=point::max_(v[ret[j][1]],v[ret[i][1]]);
  220. ret[j][0]=v.add(p0,0);
  221. ret[j][1]=v.add(p1,0);
  222. ret[i][0]=0;
  223. ret[i][1]=0;
  224. break;
  225. }
  226. }
  227. ret.erase(std::remove_if(ret.begin(),ret.end(),[&v](const base_path&p){
  228. return p[0]==0||p[1]==0;
  229. }),ret.end());
  230. #ifdef __DEBUG__
  231. std::sort(ret.begin(),ret.end(),[&v](base_path&p1,base_path&p2){
  232. double arg=p1.arg(v)-p2.arg(v);
  233. if(fabs(arg)<0.1)
  234. {
  235. return v[p1[0]]<v[p2[0]];
  236. }
  237. return arg<0;
  238. });
  239. log_path(ret,v);
  240. #endif
  241. std::vector<std::vector<int>> p0(ret.size());
  242. std::vector<base_path> ret2;
  243. for(int i=0,len=ret.size();i<len;i++)
  244. {
  245. p0[i].push_back(ret[i][0]);
  246. for(int j=i+1;j<len;j++)
  247. {
  248. if(i==j) continue;
  249. point cr=ret[i].cross(v,ret[j]);
  250. if(cr.empty())
  251. continue;
  252. double arg=fabs(ret[i].as_line(v).arg()-ret[j].as_line(v).arg());
  253. while(arg>PI/2)
  254. arg-=PI/2;
  255. if(arg/PI*180<5)
  256. continue;
  257. int id=v.add(cr,arg,v[ret[i][0]].sid0,v[ret[j][0]].sid0);
  258. p0[i].push_back(id);
  259. p0[j].push_back(id);
  260. }
  261. p0[i].push_back(ret[i][1]);
  262. std::sort(p0[i].begin(),p0[i].end(),[&v](int i0,int i1){
  263. return v[i0]<v[i1];
  264. });
  265. auto it=std::unique(p0[i].begin(),p0[i].end());
  266. p0[i].erase(it,p0[i].end());
  267. for(int j=1,cnt=p0[i].size();j<cnt;j++)
  268. ret2.push_back(base_path(p0[i][j-1],p0[i][j]));
  269. }
  270. ret2.erase(std::remove_if(ret2.begin(),ret2.end(),[&v](base_path&p){
  271. point&p0=v[p[0]];
  272. point&p1=v[p[1]];
  273. return p0.dist(p1)<0.1;
  274. }),ret2.end());
  275. std::sort(ret2.begin(),ret2.end());
  276. ret2.erase(std::unique(ret2.begin(),ret2.end()),ret2.end());
  277. /*
  278. ret.clear();
  279. for(int i=0,len=ret2.size();i<len;i++)
  280. {
  281. std::vector<line_v> tmp;
  282. tmp.push_back(ret2[i].as_line(v));
  283. for(int j=0;j<len;j++)
  284. {
  285. if(i==j) continue;
  286. if(ret[j].level(v)<ret[i].level(v))
  287. continue;
  288. line l1=ret2[j].as_line(v);
  289. }
  290. }
  291. std::sort(ret2.begin(),ret2.end(),[&v](base_path&p1,base_path&p2){
  292. return p1.arg(v)<p2.arg(v);
  293. });
  294. */
  295. return std::move(ret2);
  296. }
  297. #if 0
  298. struct ghash
  299. {
  300. static std::tuple<int,int> decode(unsigned h)
  301. {
  302. const uint64_t S=0x8000000000000000;
  303. int x=0,y=0;
  304. for(int i=0;i<64;i++)
  305. {
  306. x<<=1;
  307. y<<=1;
  308. if(h&S)
  309. x|=1;
  310. h<<=1;
  311. if(h&S)
  312. y|=1;
  313. h<<=1;
  314. }
  315. return std::make_tuple(x-2147483648,y-2147483648);
  316. }
  317. static uint64_t encode(int64_t x, int64_t y)
  318. {
  319. return encode_(x+2147483648,y+2147483648);
  320. }
  321. public: //test
  322. static void test_code(int64_t x,int64_t y)
  323. {
  324. uint64_t h=ghash::encode(x,y);
  325. auto t=ghash::decode(h);
  326. //printf("src x=%X,y=%X hash=%X,check x=%X,y=%X\n",x,y,h,std::get<0>(t),std::get<1>(t));
  327. }
  328. static void test()
  329. {
  330. for(int i=0;i<10;i++)
  331. {
  332. test_code((4<<i)-1,(4<<i)-1);
  333. test_code((4<<i)-1,(4<<i));
  334. test_code((4<<i)-1,(4<<i)-1);
  335. test_code((4<<i),(4<<i)-1);
  336. }
  337. }
  338. private:
  339. static unsigned encode_(unsigned short x, unsigned short y)
  340. {
  341. const unsigned S=0x8000;
  342. unsigned r=0;
  343. for(int i=0;i<16;i++)
  344. {
  345. r<<=2;
  346. if(x&S)
  347. {
  348. r|=(y&S)?3:2;
  349. }
  350. else
  351. {
  352. if(y&S) r|=1;
  353. }
  354. x<<=1;
  355. y<<=1;
  356. }
  357. return r;
  358. }
  359. };
  360. #endif
  361. struct geolist
  362. {
  363. std::unordered_map<uint64_t,int> geo2path;
  364. public:
  365. static uint64_t encode(double x0,double y0)
  366. {
  367. uint64_t x=(uint32_t)(x0*10);
  368. uint64_t y=(uint32_t)(y0*10);
  369. return (x<<32)|y;
  370. }
  371. int find(double x,double y)const
  372. {
  373. uint64_t h=encode(x,y);
  374. auto it=geo2path.find(h);
  375. if(it==geo2path.end())
  376. return -1;
  377. return it->second;
  378. }
  379. void add(double x,double y,int id)
  380. {
  381. uint64_t h=encode(x,y);
  382. geo2path.insert(std::make_pair(h,id));
  383. }
  384. int size()
  385. {
  386. return geo2path.size();
  387. }
  388. void print()
  389. {
  390. for(auto it=geo2path.begin();it!=geo2path.end();++it)
  391. {
  392. std::cout<<it->first<<"\n";
  393. }
  394. }
  395. geolist()
  396. {
  397. }
  398. ~geolist()
  399. {
  400. }
  401. };
  402. struct graph
  403. {
  404. vertex_list v;
  405. std::vector<std::vector<int>> d;
  406. std::vector<std::array<int,2>> l;
  407. geolist geo;
  408. graph()
  409. {}
  410. void init(const vertex_list&v_,const std::vector<base_path>&bp)
  411. {
  412. for(auto&p:bp)
  413. {
  414. int from=v.add(v_[p[0]]);
  415. int to=v.add(v_[p[1]]);
  416. std::array<int,2> tf = {from,to};
  417. l.push_back(tf);
  418. int id=l.size()-1;
  419. line_v lv(v[from],v[to]);
  420. debug_print_syslog(0,"line:%s\n",lv.to_string().c_str());
  421. double cos=lv.cos_k();
  422. double sin=lv.sin_k();
  423. double x,y;
  424. for(double r=0,len=lv.length();r<len+0.1;r+=0.05)
  425. {
  426. x=lv[0].x+r*cos;
  427. y=lv[0].y+r*sin;
  428. // printf("x=%lf,y=%lf\n",x,y);
  429. for(int i=-2;i<=2;i++)
  430. for(int j=-2;j<=2;j++)
  431. {
  432. geo.add(x+i/10.,y+j/10.,id);
  433. }
  434. }
  435. add(from,to);
  436. }
  437. }
  438. std::vector<line_v> find_possible_path(const point&from,double dist) const
  439. {
  440. std::vector<line_v> ret;
  441. int start_pt_id=v.find(from,dist);
  442. if(start_pt_id==-1)
  443. return std::move(ret);
  444. point start_pt=v[start_pt_id];
  445. for(uint32_t i=0;i<d[start_pt_id].size();i++)
  446. {
  447. ret.push_back(line_v(start_pt,v[d[start_pt_id][i]]));
  448. }
  449. return std::move(ret);
  450. }
  451. void add(int from,int to)
  452. {
  453. if((int)d.size()<=from) d.resize(from+1);
  454. if((int)d.size()<=to) d.resize(to+1);
  455. d[from].push_back(to);
  456. d[to].push_back(from);
  457. }
  458. bool find(std::vector<int>&ret,int from,std::array<int,2>&to,std::set<int>&ex,int level)
  459. {
  460. if(level--<0)
  461. return false;
  462. ret.push_back(from);
  463. for(int p:d[from]) //ÔÚµ±Ç°Â·¾¶
  464. {
  465. if(ex.find(p)!=ex.end()) //ÕÒ¹ý
  466. continue;
  467. if(p==to[0]||p==to[1])
  468. return true;
  469. // {
  470. // ret.push_back(p);
  471. // return true;
  472. // }
  473. }
  474. ex.insert(from);
  475. for(int p:d[from])
  476. {
  477. if(ex.find(p)!=ex.end())
  478. continue;
  479. if(find(ret,p,to,ex,level)) //ÕÒµ½
  480. {
  481. return true;
  482. }
  483. }
  484. ret.pop_back();
  485. return false;
  486. }
  487. bool is_at_path(const point&pt)const
  488. {
  489. return geo.find(pt.x,pt.y)>=0;
  490. }
  491. std::vector<point> find(const point&from,const point&to)
  492. {
  493. std::vector<point> tmp;
  494. tmp.resize(0);
  495. int f=geo.find(from.x,from.y);
  496. int t=geo.find(to.x,to.y);
  497. if(f<0 || t<0 || f==t)
  498. return tmp;
  499. std::vector<int> ret;
  500. int size=v.size();
  501. std::vector<double> mat(size+1,-1);
  502. std::vector<double> trace(size+1,-1);
  503. std::vector<bool> val(size+2,false);
  504. mat[l[t][0]]=to.dist(v[l[t][0]]);
  505. mat[l[t][1]]=to.dist(v[l[t][1]]);
  506. int f0=l[f][0],f1=l[f][1];
  507. for(int i=0;i<2;i++)
  508. {
  509. if(mat[f0]!=-1 && mat[f1]!=-1)
  510. break;
  511. for(int j=0;j<size;j++)
  512. if(mat[j]!=-1)val[j]=true;
  513. for(int j=0;j<size;j++)
  514. {
  515. if(val[j]==false)continue;
  516. for(unsigned int k=0;k<d[j].size();k++)
  517. {
  518. double dist=v[j].dist(v[d[j][k]]);
  519. if(mat[d[j][k]]==-1 || mat[j]+dist < mat[d[j][k]])
  520. {
  521. mat[d[j][k]] = mat[j]+dist;
  522. trace[d[j][k]] = j;
  523. }
  524. }
  525. }
  526. }
  527. mat[f0]=mat[f0]+from.dist(v[l[f][0]]);
  528. mat[f1]=mat[f1]+from.dist(v[l[f][1]]);
  529. std::vector<point> rc;
  530. if(mat[f0]!=-1 && (mat[f1]==-1 || mat[f0] < mat[f1]))
  531. {
  532. int temp=f0;
  533. while(temp!=-1)
  534. {
  535. rc.push_back(v[temp]);
  536. temp=trace[temp];
  537. }
  538. return std::move(rc);
  539. }
  540. else if(mat[f1]!=-1)
  541. {
  542. int temp=f1;
  543. while(temp!=-1)
  544. {
  545. rc.push_back(v[temp]);
  546. temp=trace[temp];
  547. }
  548. return std::move(rc);
  549. }
  550. return tmp;
  551. }
  552. };
  553. std::atomic<int> g_init_flag(0);
  554. graph g_graph;
  555. void card_path::init(const sit_list&sites)
  556. {
  557. int expect=0;
  558. if(g_init_flag.compare_exchange_strong(expect,1))
  559. {
  560. vertex_list v_list;
  561. v_list.add(point(0,0),0,-1);
  562. std::vector<base_path> opath=init_path(sites,v_list);
  563. g_graph.init(v_list,opath);
  564. ++g_init_flag;
  565. }
  566. while(g_init_flag.load()!=2)
  567. {
  568. std::this_thread::sleep_for (std::chrono::seconds(1));
  569. }
  570. }
  571. card_path&card_path::inst()
  572. {
  573. static card_path path;
  574. return path;
  575. }
  576. std::vector<point> card_path::find_path(const point&from,const point&to)const
  577. {
  578. return g_graph.find(from,to);
  579. }
  580. bool card_path::is_at_path(const point&pt)const
  581. {
  582. return g_graph.is_at_path(pt);
  583. }
  584. std::vector<line_v> card_path::find_possible_path(const point&from,double dist) const
  585. {
  586. return std::move(g_graph.find_possible_path(from,dist));
  587. }
  588. NAMESPACE_POINT_END(NAMESPACE_POINT)
  589. #ifdef __DEBUG__
  590. int main()
  591. {
  592. std::unique_ptr<sit_list> sites(new sit_list());
  593. sites->load("data_reader_antenna.txt","dat_reader_path_tof.txt");
  594. card_path cp;
  595. cp.init(*sites);
  596. {
  597. std::vector<point> rc=cp.find_path(point(4707.635909,107.789284),point(4652.845741, 54.043673));
  598. for(int i=0;i<rc.size();i++)
  599. printf("x=%lf,y=%lf\n",rc[i].x,rc[i].y);
  600. }
  601. printf("%s\n","---------------------");
  602. {
  603. std::vector<point> rc=cp.find_path(point(4220,-75),point(4947.25, -156.76));
  604. for(int i=0;i<rc.size();i++)
  605. printf("x=%lf,y=%lf\n",rc[i].x,rc[i].y);
  606. }
  607. printf("%s\n","---------------------");
  608. {
  609. std::vector<point> rc=cp.find_path(point(4220,-75),point(4727, 200));
  610. for(int i=0;i<rc.size();i++)
  611. printf("x=%lf,y=%lf\n",rc[i].x,rc[i].y);
  612. }
  613. return 0;
  614. }
  615. #endif