1
0

line_fit.cpp 3.2 KB

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