line_fit.cpp 3.4 KB

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