#ifndef _ANT_LIST_HPP_ #define _ANT_LIST_HPP_ #include #include #include #include #include #include #include "line.h" #include #include "point.h" NAMESPACE_POINT_BEGIN(NAMESPACE_POINT) struct ant:point { std::array,2> m_path;//映射的天线坐标、路径坐标、夹角 std::array&operator[](int i) { return m_path[i]; } const std::array&operator[](int i)const { return m_path[i]; } }; struct site:point { site(int id=-1); mutable double m_height; int m_id; bool m_path_empty; std::array m_ant; std::array m_line; mutable double m_ant_dist; mutable double m_ant_dist_sum_new; mutable int m_ant_dist_cnt_new; double m_scale; void count_ant_dist(double dist_tof1, double dist_tof2)const { if(dist_tof1<10 || dist_tof2<10) return; double dist = fabs(dist_tof1 - dist_tof2); if(dist>5) return; m_ant_dist_sum_new += dist; m_ant_dist_cnt_new++; if(m_ant_dist_cnt_new >= 2500) { m_ant_dist = m_ant_dist_sum_new / m_ant_dist_cnt_new; m_ant_dist_sum_new = 0; m_ant_dist_cnt_new = 0; } } /* mutable double m_test_dist=0; mutable int m_test_cnt=0; void test_dist(double d)const { if(fabs(m_ant_dist)<0.001)return; if(d>10)return; m_test_dist+=d; m_test_cnt++; }*/ /* const point&operator[](int ant_id)const { return m_ant[ant_id]; } */ double ant_dist()const { return m_ant[0].dist(m_ant[1]); } void mapping(const point &p,point &tmp) const { point rp; double d,dmin=1e4; for(auto&line:m_line) { if(line.empty()) continue; rp=line.line::projection(p); d=p.dist(rp); if(d5) tmp.set(0,0); } void sort_path(); bool is_path_empty()const { return m_path_empty; } bool have_valid_path()const { return m_id!=-1 && m_ant[0].dist(m_ant[1])>0.1 && (dist(path(0))>1 || dist(path(1))>1); } std::string to_string()const { char buf[128]; int len=sprintf(buf,"id=%d, ant=[(%.2f,%.2f),(%.2f,%.2f)],path=[(%.2f,%.2f),(%.2f,%.2f)],%d" ,m_id ,m_ant[0].x,m_ant[0].y ,m_ant[1].x,m_ant[1].y ,m_ant[0].m_path[0][1].x,m_ant[0].m_path[0][1].y ,m_ant[0].m_path[1][1].x,m_ant[0].m_path[1][1].y ,check_k() ); return std::move(std::string(buf,len)); } const point&path(int i)const { return m_ant[0].m_path[i][1]; } bool check_k()const { if(is_path_empty()) return false; return eq(path(0).cos_k(*this),cos_k(path(1)),0.1); } //Cannot handle a non straight line. point intersection(const site&o)const { //The cover area is not a straight line, giving up if(!check_k() || !o.check_k()) return point(); //The same slope, directly back to the empty if(eq(cos_k(path(0)),o.cos_k(o.path(0)),0.0001)) return point(); auto abc1= get_abc(path(0)); auto abc2=o.get_abc(o.path(0)); point pt( (std::get<2>(abc1)*std::get<1>(abc2)-std::get<2>(abc2)*std::get<1>(abc1)) /(std::get<0>(abc2)*std::get<1>(abc1)-std::get<0>(abc1)*std::get<1>(abc2)) , (std::get<2>(abc1)*std::get<0>(abc2)-std::get<2>(abc2)*std::get<0>(abc1)) /(std::get<1>(abc2)*std::get<0>(abc1)-std::get<1>(abc1)*std::get<0>(abc2)) ); // printf("cp=(%lf,%lf)\n",pt.x,pt.y); return pt; } double dist_to_site(const site&o)const { point pt=intersection(o); return dist(pt)+pt.dist(o); } double getSolPoint(const ant&a,int path,double dist) const { double real_dist = 0; double last_d = 0; double next_d = dist; std::for_each(a[path].begin()+3,a[path].end(),[&next_d,&dist,&real_dist,&last_d](const point & p){ if(!p.empty() && next_d) { double dis = p.x-last_d; last_d = p.x; if(dist > p.x) { real_dist += dis*dis/(dis+p.y); next_d = dist-p.x; } else { real_dist += next_d*dis/(dis+p.y); next_d = 0; } } else if(next_d != dist && next_d) { real_dist += next_d; next_d = 0; } }); return !real_dist?dist:real_dist; } void solving(point**o, int ant_id, double dist)const { point*r=*o; const ant&a=m_ant[ant_id]; if(dist<50 && dist>0) { if(dist0.001) { double delta = (m_ant_dist - ant_dist())/2; if(p1.dist(*this)>p2.dist(*this)) { rd1+=delta; rd2-=delta; } else { rd1-=delta; rd2+=delta; } point tmp1=point(a[0][0].x+rd1*a[0][2].x, a[0][0].y+rd1*a[0][2].y); point tmp2=point(a[1][0].x+rd2*a[1][2].x, a[1][0].y+rd2*a[1][2].y); point mapped1,mapped2; mapping(tmp1,mapped1); mapping(tmp2,mapped2); *r++=mapped1; *r++=mapped2; } else { point mapped1,mapped2; mapping(p1,mapped1); mapping(p2,mapped2); *r++=mapped1; *r++=mapped2; } *o=r; } }; struct sit_list { std::array m_list; public: sit_list(); void load(const char*ant_file,const char*path_file) { read_sit_list(ant_file); read_ant_path(path_file); } std::string to_string()const { std::string rt; rt.reserve(4096); for(auto s:m_list) { if(s.m_id==-1) continue; rt+=s.to_string(); rt+="\n"; } return std::move(rt); } void read_sit_list(const char*fname); void read_ant_path(const char*fname); void init_sit_list(int32_t readerid,int32_t antid, double ax, double ay,double scale); void init_sit_list(); void init_ant_path(int32_t readerid,int32_t antid, double ax, double ay,std::vector::iterator &b,std::vector::iterator& e); void init_ant_path(); const site& operator[](int id) const; }; NAMESPACE_POINT_END(NAMESPACE_POINT) #endif