#ifndef _LINE_FIT_ #define _LINE_FIT_ #include #include #include "zlist.h" struct fit_item { double x,y,xx,xy; fit_item(); fit_item&set(double x,double y); void log()const { printf("x=%.3lf,y=%.3lf,xx=%.3lf,xy=%.3lf\n",x,y,xx,xy); } }; struct card_fit; struct fit_batch:zlist { double xo=0,yo=0; std::vector tool; public: fit_batch(); ~fit_batch(); int tool_size()const { return tool.size(); } card_fit&operator[](int i) { return *tool[i]; } const card_fit&operator[](int i) const { return *tool[i]; } void add_tool(double max_x_span,int min_point); void add_tool(double max_x_span,int min_point,int max_point); void reset_data(); double add(double x,double y); void replace(double x,double y); void remove_bad(int tool_id); double x(int index)const; double y(int index)const; void rlog(int i)const { rat(i).log(); } void log(); }; struct fit_result { double k,kb,ke,ka; double xo,yo; int num_point; int min_point; double max_x_span; fit_result(); fit_result(double max_x_span,int min_point); void reset(); int size()const { return num_point; } bool is_valid()const { return num_point>=min_point; } void log() { printf("%5s, %d, k=(%.3f,%.3f,%.3f)\n",is_valid()?"true":"false", size(),k,kb,ke); } double testk(double x,double y)const; double differ_k(double x,double y)const; }; struct card_fit:fit_result { const fit_batch&d; double A = 0, B = 0, C = 0, D = 0; card_fit(const fit_batch&d,double _max_x_span,int min_point); virtual ~card_fit(); void reset(); void dec_(const fit_item&i); void add_(const fit_item&i); virtual void add_last(); virtual bool check_x_span(); virtual bool fit(); }; struct card_fit_stop:card_fit { card_fit_stop(const fit_batch&d_,double _max_x_span,int min_point) :card_fit(d_,_max_x_span,min_point) { } virtual void add_last() { } virtual bool fit() { return false; } }; struct card_fit_lastn:card_fit { int max_point; card_fit_lastn(const fit_batch&d_,double _max_x_span,int min_point,int max_point_) :card_fit(d_,_max_x_span,min_point) ,max_point(max_point_) { } bool check_x_span() { int i=size()-1; for(;i>0;i--) { double off=d(0).x-d(i).x; if(off>max_x_span+0.5 || i>=max_point) { --num_point; dec_(d(i)); continue; } break; } return num_point>=min_point; } }; #endif