line_fit.cpp 6.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358
  1. #include <algorithm>
  2. #include <math.h>
  3. #include "line_fit.h"
  4. #include "line.h"
  5. fit_item::fit_item()
  6. :x(0)
  7. ,y(0)
  8. ,xx(0)
  9. ,xy(0)
  10. {
  11. }
  12. fit_item&fit_item::set(double x,double y)
  13. {
  14. this->x=x;
  15. this->y=y;
  16. xx=x*x;
  17. xy=x*y;
  18. return *this;
  19. }
  20. fit_batch::fit_batch()
  21. {
  22. tool.reserve(8);
  23. }
  24. fit_batch::~fit_batch()
  25. {
  26. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  27. delete f;
  28. });
  29. }
  30. void fit_batch::add_tool(double max_x_span,int min_point)
  31. {
  32. tool.push_back(new card_fit(*this,max_x_span,min_point));
  33. }
  34. void fit_batch::add_tool(double max_x_span,int min_point,int max_point)
  35. {
  36. tool.push_back(new card_fit_lastn(*this,max_x_span,min_point,max_point));
  37. }
  38. void fit_batch::log()
  39. {
  40. // printf("xo=%lf,yo=%.3lf\n",xo,yo);
  41. //for(int i=0,len=size();i<len;i++)
  42. // at(i).log();
  43. printf("epos-bpos:%d, xo:%f, yo:%f\n",epos - bpos, xo, yo);
  44. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  45. f->log();
  46. });
  47. }
  48. void fit_batch::reset_data()
  49. {
  50. xo=yo=0;
  51. clear();
  52. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  53. f->reset();
  54. });
  55. }
  56. double fit_batch::add(double x,double y)
  57. {
  58. if(x==0 && y==0)
  59. return 0;
  60. if(empty())
  61. {
  62. xo=x; yo=y;
  63. std::for_each(tool.begin(),tool.end(),[this](card_fit*f){
  64. f->xo=xo;
  65. f->yo=yo;
  66. });
  67. }
  68. grow().set(x-xo,y-yo);
  69. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  70. f->add_last();
  71. f->fit();
  72. });
  73. return 0;
  74. }
  75. #if 0
  76. void fit_batch::replace(double x,double y)
  77. {
  78. if(empty())
  79. return;
  80. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  81. f->remove_last();
  82. });
  83. rat(0).set(x-xo,y-yo);
  84. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  85. f->add_last();
  86. f->fit();
  87. });
  88. }
  89. #endif
  90. double fit_batch::x(int index)const
  91. {
  92. return (*this)(index).x + xo;
  93. }
  94. double fit_batch::y(int index)const
  95. {
  96. return (*this)(index).y + yo;
  97. }
  98. fit_result::fit_result()
  99. :k(0)
  100. ,kb(0)
  101. ,ke(0)
  102. ,ka(0)
  103. ,num_point(0)
  104. ,min_point(0)
  105. ,max_x_span(0)
  106. {
  107. }
  108. fit_result::fit_result(double _max_x_span,int min_point_)
  109. :k(0)
  110. ,kb(0)
  111. ,ke(0)
  112. ,ka(0)
  113. ,num_point(0)
  114. ,min_point(min_point_)
  115. ,max_x_span(_max_x_span)
  116. {
  117. }
  118. void fit_result::reset()
  119. {
  120. k=kb=ke=ka=0;
  121. xo=yo=0;
  122. num_point=0;
  123. }
  124. card_fit::~card_fit()
  125. {
  126. }
  127. card_fit::card_fit(const fit_batch&d_,double _max_x_span,int min_point_)
  128. :fit_result(_max_x_span,min_point_)
  129. ,d(d_)
  130. {
  131. }
  132. void card_fit::dec_(const fit_item&i)
  133. {
  134. A -= i.xx;
  135. B -= i.x;
  136. C -= i.xy;
  137. D -= i.y;
  138. }
  139. void card_fit::add_(const fit_item&i)
  140. {
  141. A += i.xx;
  142. B += i.x;
  143. C += i.xy;
  144. D += i.y;
  145. }
  146. void card_fit::add_last()
  147. {
  148. ++num_point;
  149. add_(d(0));
  150. }
  151. #if 0
  152. void card_fit::remove_last()
  153. {
  154. --num_point;
  155. dec_(d(0));
  156. }
  157. #endif
  158. void card_fit::reset()
  159. {
  160. fit_result::reset();
  161. A=B=C=D=0;
  162. }
  163. double fit_result::testk(double x,double y)const
  164. {
  165. return k * (x-xo) + kb - (y-yo);
  166. }
  167. double fit_result::differ_k(double x,double y)const
  168. {
  169. return fabs(k*x+kb-y);
  170. }
  171. bool card_fit::check_x_span()
  172. {
  173. int i=size()-1;
  174. for(;i>0;i--)
  175. {
  176. double off=d(0).x-d(i).x;
  177. if(off>max_x_span+0.5)
  178. {
  179. --num_point;
  180. dec_(d(i));
  181. continue;
  182. }
  183. break;
  184. }
  185. return num_point>=min_point;
  186. }
  187. bool card_fit::fit()
  188. {
  189. if(!check_x_span())
  190. return false;
  191. int count=size();
  192. double temp = count*A - B*B;
  193. kb = (A*D - B*C) / temp;
  194. k = (count*C - B*D) / temp;
  195. double sum=0;
  196. for (int i=0; i<count; i++)
  197. sum+=differ_k(d(i).x,d(i).y);
  198. ke = sum / count;
  199. return true;
  200. }
  201. #ifdef _LINE_FIT_TEST
  202. #include "line_fit.h"
  203. int a(int x)
  204. {
  205. return x*2+1;
  206. }
  207. double y(int x)
  208. {
  209. return 0.25*x+13.2;
  210. }
  211. int main()
  212. {
  213. fit_batch f;
  214. f.add_tool(100,5);
  215. //y=2x+1;
  216. //f.add(30,a(30));
  217. for(int i=0;i<15;i++)
  218. {
  219. f.add(i*10,a(i*10));
  220. }
  221. f.add(20,45);
  222. f.log();
  223. f.reset_data();
  224. f.add(20,45);
  225. for(int i=14;i>=0;i--)
  226. f.add(i,a(i));
  227. f.log();
  228. printf("%f",f[0].testk(30,a(30)+20));
  229. f.reset_data();
  230. f.add(6721.744000,1273.000000);
  231. f.add(6721.742000,1273.000000);
  232. f.log();
  233. f.add(6721.592000,1273.000000);
  234. f.add(6721.545000,1273.000000);
  235. f.add(6721.259000,1273.000000);
  236. f.add(6721.395000,1273.000000);
  237. f.add(6721.378000,1273.000000);
  238. f.add(6721.081000,1273.000000);
  239. f.add(6721.043000,1273.000000);
  240. f.add(6720.991000,1273.000000);
  241. f.add(6720.485000,1273.000000);
  242. f.add(6720.633000,1273.000000);
  243. f.add(6720.562000,1273.000000);
  244. f.add(6720.443000,1273.000000);
  245. f.add(6720.145000,1273.000000);
  246. f.add(6719.575000,1273.000000);
  247. f.add(6710.775000,1273.000000);
  248. f.add(6710.384000,1273.000000);
  249. f.add(6710.030000,1273.000000);
  250. f.add(6709.847000,1273.000000);
  251. f.add(6710.098000,1273.000000);
  252. f.add(6706.457000,1273.000000);
  253. f.add(6706.419000,1273.000000);
  254. f.add(6706.608000,1273.000000);
  255. f.add(6706.513000,1273.000000);
  256. f.add(6706.438000,1273.000000);
  257. f.add(6706.239000,1273.000000);
  258. f.add(6706.048000,1273.000000);
  259. f.add(6705.962000,1273.000000);
  260. f.add(6705.707000,1273.000000);
  261. f.add(6705.839000,1273.000000);
  262. f.add(6705.594000,1273.000000);
  263. f.add(6705.417000,1273.000000);
  264. f.add(6705.136000,1273.000000);
  265. f.add(6705.608000,1273.000000);
  266. f.add(6705.505000,1273.000000);
  267. f.add(6705.422000,1273.000000);
  268. f.add(6705.640000,1273.000000);
  269. f.add(6705.280000,1273.000000);
  270. f.log();
  271. zlist<int,128> m_test;
  272. for(int i= 1 ;i<=20;i++)
  273. {
  274. m_test.grow()=i;
  275. if(i%5==0)
  276. {
  277. int x=0;
  278. for(int j=0;j<5;j++)
  279. {
  280. x+=m_test(j);
  281. }
  282. m_test.rskip(5);
  283. m_test.grow()=x;
  284. }
  285. }
  286. for(int i=0;i<m_test.size();i++)
  287. printf("%d\n",m_test(i));
  288. line_r l(point(1,y(1)),point(13,y(13)));
  289. if(l.contain(point(4,y(4))))printf("contain:%d,%f\n",4,y(4));
  290. if(l.contain(point(5,y(5))))printf("contain:%d,%f\n",5,y(5));
  291. if(l.contain(point(-5,y(-5))))printf("contain:%d,%f\n",-5,y(-5));
  292. point p=l.projection(point(17,y(17)+1.5));
  293. printf("projection:%f,%f\n",p.x,p.y);
  294. p=l.projection(point(-17,y(-17)+1.5));
  295. printf("projection:%f,%f\n",p.x,p.y);
  296. printf("line:%s\n",l.to_string().c_str());
  297. line_r ll=l;
  298. printf("line:%s\n",ll.to_string().c_str());
  299. bool b=l.is_same_direction(ll);
  300. if(b)printf("%s [is same direction]%s\n",l.to_string().c_str(),ll.to_string().c_str());
  301. line_r l2(point(4,y(4)),point(7,y(7)));
  302. b=l.is_same_direction(l2);
  303. if(b)printf("%s [is same direction]%s\n",l.to_string().c_str(),l2.to_string().c_str());
  304. line_r l3(point(19,y(19)),point(31,y(31)));
  305. b=l.is_same_direction(l3);
  306. if(b)printf("%s [is same direction]%s\n",l.to_string().c_str(),l3.to_string().c_str());
  307. line_r l4(point(19,y(19)),point(4,y(4)));
  308. b=l.is_same_direction(l4);
  309. if(!b)printf("%s [is not same direction]%s\n",l.to_string().c_str(),l4.to_string().c_str());
  310. return 0;
  311. }
  312. #endif