path.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370
  1. #ifndef _CARD_PATH_HPP_
  2. #define _CARD_PATH_HPP_
  3. #include "point.h"
  4. NAMESPACE_POINT_BEGIN (NAMESPACE_POINT)
  5. struct line:point
  6. {
  7. point pt;
  8. double a,b,c;
  9. double cos;
  10. double sin;
  11. double length;
  12. int direct;
  13. line()
  14. {
  15. reset();
  16. }
  17. std::string to_string()const
  18. {
  19. char buf[256];
  20. int len=sprintf(buf,"[(%.3f,%.3f),(%.3f,%.3f),%.3f]",x,y,pt.x,pt.y,cos);
  21. return std::string(buf,len);
  22. }
  23. bool empty()const
  24. {
  25. return cos+sin==0;
  26. }
  27. line& reset()
  28. {
  29. memset(this,0,sizeof(*this));
  30. return *this;
  31. }
  32. void set_next(const point&pt)
  33. {
  34. set_next(pt.x,pt.y);
  35. }
  36. void set_next(double x,double y)
  37. {
  38. if(dist(x,y)<1)
  39. return;
  40. pt.set(x,y);
  41. auto abc=get_abc(pt);
  42. a=std::get<0>(abc);
  43. b=std::get<1>(abc);
  44. c=std::get<2>(abc);
  45. cos=cos_k(pt);
  46. sin=sin_k(pt);
  47. length=dist(pt);
  48. }
  49. bool test(const point&p)const
  50. {
  51. return test(p.x,p.y);
  52. }
  53. bool test(double x,double y)const
  54. {
  55. return fabs(a*x+b*y+c)<1;
  56. }
  57. int push(const point&pt)
  58. {
  59. return push(pt.x,pt.y);
  60. }
  61. int push(double x,double y)
  62. {
  63. if(!empty())
  64. {
  65. if(test(x,y))
  66. {
  67. pt.set(x,y);
  68. return 0;
  69. }
  70. return -1;
  71. }
  72. set_next(x,y);
  73. return 1;
  74. }
  75. point map(double length)
  76. {
  77. return point(x+length*cos,y+length*sin);
  78. }
  79. };
  80. struct vec
  81. {
  82. };
  83. struct path
  84. {
  85. };
  86. //所有的顶点
  87. struct vertexs
  88. {
  89. std::vector<point> v;
  90. };
  91. //整个地图的路径信息
  92. struct map_path
  93. {
  94. };
  95. //一维、二维坐标进行转换的工具类
  96. //使用this->add_point按照路径顺序加入途径点
  97. //使用this->map进行一维、二维坐标之间的相互转换
  98. struct card_path
  99. {
  100. private:
  101. const site* last_site;
  102. zlist<line,64> &path;
  103. card_path(const card_path&);
  104. private:
  105. static inline bool eq(double x1,double x2)
  106. {
  107. return fabs(x1-x2)<0.1; //小于10厘米的误差认为是一个点
  108. }
  109. public:
  110. /*
  111. 输入起始点,返回途经点
  112. */
  113. int find_path(const point&from,const point&to,std::array<point,8>&ret)
  114. {
  115. return 0;
  116. }
  117. /*
  118. 输入路径上的二维点(x,y),输出该点的一维坐标
  119. return -1. : (x,y) 不在路径上或者当前对象不包含合法路径
  120. return >=0 : (x,y) 一维坐标
  121. */
  122. double map(double x,double y)const
  123. {
  124. double rc=0.;
  125. for(int i=0,len=path.size();i<len;i++)
  126. {
  127. const line&p=path[i];
  128. if(p.test(x,y))
  129. {
  130. return rc+p.dist(x,y);
  131. }
  132. rc+=p.length;
  133. }
  134. assert(false);
  135. return -1.;
  136. }
  137. double map(const point&p)const
  138. {
  139. return map(p.x, p.y);
  140. }
  141. /*
  142. 输入一维坐标(dist),转换为二维坐标输出(point)
  143. 如果给定一维坐标超出当前路径长度,返回 point::invalid_point()
  144. */
  145. point map(double length)
  146. {
  147. if(empty())
  148. return point();
  149. for(int i=0,len=path.size()-1;i<len;i++)
  150. {
  151. line&v=path[i];
  152. if(length<=v.length)
  153. return v.map(length);
  154. length-=v.length;
  155. }
  156. return path(0).map(length);
  157. }
  158. public:
  159. card_path()
  160. :last_site(nullptr)
  161. ,path(*new zlist<line,64>())
  162. {
  163. }
  164. ~card_path()
  165. {
  166. delete &path;
  167. }
  168. bool empty() const
  169. {
  170. return path.empty() || path[0].empty();
  171. }
  172. std::string to_string()const
  173. {
  174. std::string rc;
  175. for(int i=0,len=path.size();i<len;i++)
  176. {
  177. rc+=path[i].to_string();
  178. rc+=", ";
  179. }
  180. return std::move(rc);
  181. }
  182. void log()const
  183. {
  184. printf("path-point:%s\n",to_string().c_str());
  185. }
  186. int test(const point&p,int start=0)
  187. {
  188. for(int i=start,len=path.size();i<len;i++)
  189. {
  190. if(path[i].test(p))
  191. return i;
  192. }
  193. return -1;
  194. }
  195. void enter_site(const site*sit)
  196. {
  197. if(last_site==nullptr)
  198. last_site=sit;
  199. if(last_site==sit||empty())
  200. return;
  201. point pt=last_site->intersection(*sit);
  202. last_site=sit;
  203. if(pt.empty()||pt.dist(last_point)>25)
  204. return;
  205. path(0).set_next(pt.x,pt.y);
  206. path.grow().reset().set(pt);
  207. }
  208. //加入路径坐标
  209. bool add(const point&pt)
  210. {
  211. if(pt.empty())
  212. return false;
  213. if(pt.dist(last_point)<1)
  214. return false;
  215. last_point=pt;
  216. if(path.empty())
  217. {
  218. path.grow().reset().set(pt);
  219. return true;
  220. }
  221. int rc=path(0).push(pt);
  222. if(rc==0)
  223. return true;
  224. if(rc<0)
  225. {
  226. path.grow().reset().set(pt);
  227. }
  228. return true;
  229. }
  230. void set_header(const point&p)
  231. {
  232. if(p.empty())
  233. return;
  234. int i=test(p);
  235. if(i>=0)
  236. {
  237. path.skip(i);
  238. path[0].set(p);
  239. if(!path[0].pt.empty())
  240. path[0].set_next(path[0].pt);
  241. }
  242. }
  243. /*
  244. 输入路径上的二维点(x,y),输出该点的一维坐标
  245. return -1. : (x,y) 不在路径上或者当前对象不包含合法路径
  246. return >=0 : (x,y) 一维坐标
  247. */
  248. double map(double x,double y)const
  249. {
  250. double rc=0.;
  251. for(int i=0,len=path.size();i<len;i++)
  252. {
  253. const line&p=path[i];
  254. if(p.test(x,y))
  255. {
  256. return rc+p.dist(x,y);
  257. }
  258. rc+=p.length;
  259. }
  260. assert(false);
  261. return -1.;
  262. }
  263. double map(const point&p)const
  264. {
  265. return map(p.x, p.y);
  266. }
  267. /*
  268. 输入一维坐标(dist),转换为二维坐标输出(point)
  269. 如果给定一维坐标超出当前路径长度,返回 point::invalid_point()
  270. */
  271. point map(double length)
  272. {
  273. if(empty())
  274. return point();
  275. for(int i=0,len=path.size()-1;i<len;i++)
  276. {
  277. line&v=path[i];
  278. if(length<=v.length)
  279. return v.map(length);
  280. length-=v.length;
  281. }
  282. return path(0).map(length);
  283. }
  284. };
  285. NAMESPACE_POINT_END(NAMESPACE_POINT)
  286. #endif