60 pts_.
push_back(PointWidth(pt, halfwidth));
76 int pt_count = pts_.
size();
78 if (skip_first >= pt_count) skip_first = pt_count - 1;
81 for (
int i = skip_first; i < end_i; ++i) {
82 starts[start_count++] = &pts_[i].pt;
85 if (skip_last >= pt_count) skip_last = pt_count - 1;
88 for (
int i = pt_count - 1 - skip_last; i >= end_i; --i) {
89 ends[end_count++] = &pts_[i].pt;
103 double best_uq = -1.0;
105 for (
int i = 0; i < start_count; ++i) {
106 ICOORD* start = starts[i];
107 for (
int j = 0; j < end_count; ++j) {
109 if (*start != *end) {
110 ComputeDistances(*start, *end);
112 double dist = EvaluateLineFit();
113 if (dist < best_uq || best_uq < 0.0) {
122 return best_uq > 0.0 ? sqrt(best_uq) : best_uq;
132 double min_dist,
double max_dist,
133 bool debug,
ICOORD* line_pt) {
134 ComputeConstrainedDistances(
direction, min_dist, max_dist);
136 if (pts_.
empty() || distances_.empty()) {
141 int median_index = distances_.choose_nth_item(distances_.size() / 2);
142 *line_pt = distances_[median_index].data;
144 tprintf(
"Constrained fit to dir %g, %g = %d, %d :%d distances:\n",
146 line_pt->
x(), line_pt->
y(), distances_.size());
147 for (
int i = 0; i < distances_.size(); ++i) {
148 tprintf(
"%d: %d, %d -> %g\n", i, distances_[i].data.x(),
149 distances_[i].data.y(), distances_[i].key);
151 tprintf(
"Result = %d\n", median_index);
154 double dist_origin =
direction * *line_pt;
155 for (
int i = 0; i < distances_.size(); ++i) {
156 distances_[i].key -= dist_origin;
158 return sqrt(EvaluateLineFit());
172 double error =
Fit(&start, &end);
173 if (end.
x() != start.
x()) {
174 *m =
static_cast<float>(end.
y() - start.
y()) / (end.
x() - start.
x());
175 *c = start.
y() - *m * start.
x();
192 double cos = 1.0 / sqrt(1.0 + m * m);
197 *c = line_pt.
y() - line_pt.
x() * m;
202 double DetLineFit::EvaluateLineFit() {
204 double dist = ComputeUpperQuartileError();
211 dist = NumberOfMisfittedPoints(threshold);
218 double DetLineFit::ComputeUpperQuartileError() {
219 int num_errors = distances_.size();
220 if (num_errors == 0)
return 0.0;
222 for (
int i = 0; i < num_errors; ++i) {
223 if (distances_[i].key < 0) distances_[i].key = -distances_[i].key;
226 int index = distances_.choose_nth_item(3 * num_errors / 4);
227 double dist = distances_[index].key;
230 return square_length_ > 0.0 ? dist * dist / square_length_ : 0.0;
234 int DetLineFit::NumberOfMisfittedPoints(
double threshold)
const {
236 int num_dists = distances_.size();
238 for (
int i = 0; i < num_dists; ++i) {
239 if (distances_[i].key > threshold)
249 void DetLineFit::ComputeDistances(
const ICOORD& start,
const ICOORD& end) {
250 distances_.truncate(0);
252 line_vector -= start;
253 square_length_ = line_vector.
sqlength();
256 int prev_abs_dist = 0;
258 for (
int i = 0; i < pts_.
size(); ++i) {
259 ICOORD pt_vector = pts_[i].pt;
261 int dot = line_vector % pt_vector;
263 int dist = line_vector * pt_vector;
264 int abs_dist = dist < 0 ? -dist : dist;
265 if (abs_dist > prev_abs_dist && i > 0) {
267 int separation = abs(dot - prev_dot);
268 if (separation < line_length * pts_[i].halfwidth ||
269 separation < line_length * pts_[i - 1].halfwidth)
272 distances_.push_back(DistPointPair(dist, pts_[i].pt));
273 prev_abs_dist = abs_dist;
282 double min_dist,
double max_dist) {
283 distances_.truncate(0);
286 for (
int i = 0; i < pts_.
size(); ++i) {
287 FCOORD pt_vector = pts_[i].pt;
290 if (min_dist <= dist && dist <= max_dist)
291 distances_.push_back(DistPointPair(dist, pts_[i].pt));
int IntCastRounded(double x)
double Fit(ICOORD *pt1, ICOORD *pt2)
void Add(const ICOORD &pt)
double ConstrainedFit(const FCOORD &direction, double min_dist, double max_dist, bool debug, ICOORD *line_pt)
const int kMaxRealDistance
bool SufficientPointsForIndependentFit() const
inT16 x() const
access function
float sqlength() const
find sq length
int direction(EDGEPT *point)
void set_y(inT16 yin)
rewrite function
void set_x(inT16 xin)
rewrite function
const int kMinPointsForErrorCount
inT16 y() const
access_function