1
0

line_fit.cpp 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  1. #include <algorithm>
  2. #include <math.h>
  3. #include "line_fit.h"
  4. fit_item::fit_item()
  5. :x(0)
  6. ,y(0)
  7. ,xx(0)
  8. ,xy(0)
  9. {
  10. }
  11. fit_item&fit_item::set(double x,double y)
  12. {
  13. this->x=x;
  14. this->y=y;
  15. xx=x*x;
  16. xy=x*y;
  17. return *this;
  18. }
  19. fit_batch::fit_batch()
  20. {
  21. tool.reserve(8);
  22. }
  23. fit_batch::~fit_batch()
  24. {
  25. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  26. delete f;
  27. });
  28. }
  29. void fit_batch::add_tool(double max_x_span,int min_point)
  30. {
  31. tool.push_back(new card_fit(*this,max_x_span,min_point));
  32. }
  33. void fit_batch::add_tool(double max_x_span,int min_point,int max_point)
  34. {
  35. tool.push_back(new card_fit_lastn(*this,max_x_span,min_point,max_point));
  36. }
  37. void fit_batch::log()
  38. {
  39. // printf("xo=%lf,yo=%.3lf\n",xo,yo);
  40. //for(int i=0,len=size();i<len;i++)
  41. // at(i).log();
  42. printf("epos-bpos:%d, xo:%f, yo:%f\n",epos - bpos, xo, yo);
  43. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  44. f->log();
  45. });
  46. }
  47. void fit_batch::reset_data()
  48. {
  49. xo=yo=0;
  50. clear();
  51. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  52. f->reset();
  53. });
  54. }
  55. double fit_batch::add(double x,double y)
  56. {
  57. if(x==0 && y==0)
  58. return 0;
  59. if(empty())
  60. {
  61. xo=x; yo=y;
  62. std::for_each(tool.begin(),tool.end(),[this](card_fit*f){
  63. f->xo=xo;
  64. f->yo=yo;
  65. });
  66. }
  67. grow().set(x-xo,y-yo);
  68. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  69. f->add_last();
  70. f->fit();
  71. });
  72. return 0;
  73. }
  74. #if 0
  75. void fit_batch::replace(double x,double y)
  76. {
  77. if(empty())
  78. return;
  79. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  80. f->remove_last();
  81. });
  82. rat(0).set(x-xo,y-yo);
  83. std::for_each(tool.begin(),tool.end(),[](card_fit*f){
  84. f->add_last();
  85. f->fit();
  86. });
  87. }
  88. #endif
  89. double fit_batch::x(int index)const
  90. {
  91. return (*this)(index).x + xo;
  92. }
  93. double fit_batch::y(int index)const
  94. {
  95. return (*this)(index).y + yo;
  96. }
  97. fit_result::fit_result()
  98. :k(0)
  99. ,kb(0)
  100. ,ke(0)
  101. ,ka(0)
  102. ,num_point(0)
  103. ,min_point(0)
  104. ,max_x_span(0)
  105. {
  106. }
  107. fit_result::fit_result(double _max_x_span,int min_point_)
  108. :k(0)
  109. ,kb(0)
  110. ,ke(0)
  111. ,ka(0)
  112. ,num_point(0)
  113. ,min_point(min_point_)
  114. ,max_x_span(_max_x_span)
  115. {
  116. }
  117. void fit_result::reset()
  118. {
  119. k=kb=ke=ka=0;
  120. xo=yo=0;
  121. num_point=0;
  122. }
  123. card_fit::~card_fit()
  124. {
  125. }
  126. card_fit::card_fit(const fit_batch&d_,double _max_x_span,int min_point_)
  127. :fit_result(_max_x_span,min_point_)
  128. ,d(d_)
  129. {
  130. }
  131. void card_fit::dec_(const fit_item&i)
  132. {
  133. A -= i.xx;
  134. B -= i.x;
  135. C -= i.xy;
  136. D -= i.y;
  137. }
  138. void card_fit::add_(const fit_item&i)
  139. {
  140. A += i.xx;
  141. B += i.x;
  142. C += i.xy;
  143. D += i.y;
  144. }
  145. void card_fit::add_last()
  146. {
  147. ++num_point;
  148. add_(d(0));
  149. }
  150. #if 0
  151. void card_fit::remove_last()
  152. {
  153. --num_point;
  154. dec_(d(0));
  155. }
  156. #endif
  157. void card_fit::reset()
  158. {
  159. fit_result::reset();
  160. A=B=C=D=0;
  161. }
  162. double fit_result::testk(double x,double y)const
  163. {
  164. return k * (x-xo) + kb - (y-yo);
  165. }
  166. double fit_result::differ_k(double x,double y)const
  167. {
  168. return fabs(k*x+kb-y);
  169. }
  170. bool card_fit::check_x_span()
  171. {
  172. int i=size()-1;
  173. for(;i>0;i--)
  174. {
  175. double off=d(0).x-d(i).x;
  176. if(off>max_x_span+0.5)
  177. {
  178. --num_point;
  179. dec_(d(i));
  180. continue;
  181. }
  182. break;
  183. }
  184. return num_point>=min_point;
  185. }
  186. bool card_fit::fit()
  187. {
  188. if(!check_x_span())
  189. return false;
  190. int count=size();
  191. double temp = count*A - B*B;
  192. kb = (A*D - B*C) / temp;
  193. k = (count*C - B*D) / temp;
  194. double sum=0;
  195. for (int i=0; i<count; i++)
  196. sum+=differ_k(d(i).x,d(i).y);
  197. ke = sum / count;
  198. return true;
  199. }