src/ccstruct/detlinefit.cpp
double DetLineFit::Fit(int skip_first, int skip_last, ICOORD *pt1, ICOORD *pt2) {
  // Do something sensible with no points.
  if (pts_.empty()) {
    pt1->set_x(0);
    pt1->set_y(0);
    *pt2 = *pt1;
    return 0.0;
  }
  // Count the points and find the first and last kNumEndPoints.
  int pt_count = pts_.size();
  ICOORD *starts[kNumEndPoints];
  if (skip_first >= pt_count) {
    skip_first = pt_count - 1;
  }
  int start_count = 0;
  int end_i = std::min(skip_first + kNumEndPoints, pt_count);
  for (int i = skip_first; i < end_i; ++i) {
    starts[start_count++] = &pts_[i].pt;
  }
  ICOORD *ends[kNumEndPoints];
  if (skip_last >= pt_count) {
    skip_last = pt_count - 1;
  }
  int end_count = 0;
  end_i = std::max(0, pt_count - kNumEndPoints - skip_last);
  for (int i = pt_count - 1 - skip_last; i >= end_i; --i) {
    ends[end_count++] = &pts_[i].pt;
  }
  // 1 or 2 points need special treatment.
  if (pt_count <= 2) {
    *pt1 = *starts[0];
    if (pt_count > 1) {
      *pt2 = *ends[0];
    } else {
      *pt2 = *pt1;
    }
    return 0.0;
  }
  // Although with between 2 and 2*kNumEndPoints-1 points, there will be
  // overlap in the starts, ends sets, this is OK and taken care of by the
  // if (*start != *end) test below, which also tests for equal input points.
  double best_uq = -1.0;
  // Iterate each pair of points and find the best fitting line.
  for (int i = 0; i < start_count; ++i) {
    ICOORD *start = starts[i];
    for (int j = 0; j < end_count; ++j) {
      ICOORD *end = ends[j];
      if (*start != *end) {
        ComputeDistances(*start, *end);
        // Compute the upper quartile error from the line.
        double dist = EvaluateLineFit();
        if (dist < best_uq || best_uq < 0.0) {
          best_uq = dist;
          *pt1 = *start;
          *pt2 = *end;
        }
      }
    }
  }
  // Finally compute the square root to return the true distance.
  return best_uq > 0.0 ? sqrt(best_uq) : best_uq;
}
// Fits a line to the points, ignoring the skip_first initial points and the
// skip_last final points, returning the fitted line as a pair of points,
// and the upper quartile error.
Fits a line to the points, ignoring the skip_first initial points and the
skip_last final points, returning the fitted line as a pair of points,
and the upper quartile error.
Fits a line to the points ignoring the skip_first initial points and the skip_last final points returning the fitted line as a pair of points and the upper quartile error .
double DetLineFit::Fit(int skip_first, int skip_last, ICOORD *pt1, ICOORD *pt2) {
  if (pts_.empty()) {
    pt1->set_x(0);
    pt1->set_y(0);
    *pt2 = *pt1;
    return 0.0;
  }
  int pt_count = pts_.size();
  ICOORD *starts[kNumEndPoints];
  if (skip_first >= pt_count) {
    skip_first = pt_count - 1;
  }
  int start_count = 0;
  int end_i = std::min(skip_first + kNumEndPoints, pt_count);
  for (int i = skip_first; i < end_i; ++i) {
    starts[start_count++] = &pts_[i].pt;
  }
  ICOORD *ends[kNumEndPoints];
  if (skip_last >= pt_count) {
    skip_last = pt_count - 1;
  }
  int end_count = 0;
  end_i = std::max(0, pt_count - kNumEndPoints - skip_last);
  for (int i = pt_count - 1 - skip_last; i >= end_i; --i) {
    ends[end_count++] = &pts_[i].pt;
  }
  if (pt_count <= 2) {
    *pt1 = *starts[0];
    if (pt_count > 1) {
      *pt2 = *ends[0];
    } else {
      *pt2 = *pt1;
    }
    return 0.0;
  }
  double best_uq = -1.0;
  for (int i = 0; i < start_count; ++i) {
    ICOORD *start = starts[i];
    for (int j = 0; j < end_count; ++j) {
      ICOORD *end = ends[j];
      if (*start != *end) {
        ComputeDistances(*start, *end);
        double dist = EvaluateLineFit();
        if (dist < best_uq || best_uq < 0.0) {
          best_uq = dist;
          *pt1 = *start;
          *pt2 = *end;
        }
      }
    }
  }
  return best_uq > 0.0 ? sqrt(best_uq) : best_uq;
}
double DetLineFit :: Fit ( int skip_first , int skip_last , ICOORD * pt1 , ICOORD * pt2 ) { if ( pts_ . empty ( ) ) { pt1 -> set_x ( 0 ) ; pt1 -> set_y ( 0 ) ; * pt2 = * pt1 ; return 0.0 ; } int pt_count = pts_ . size ( ) ; ICOORD * starts [ kNumEndPoints ] ; if ( skip_first >= pt_count ) { skip_first = pt_count - 1 ; } int start_count = 0 ; int end_i = std :: min ( skip_first + kNumEndPoints , pt_count ) ; for ( int i = skip_first ; i < end_i ; ++ i ) { starts [ start_count ++ ] = & pts_ [ i ] . pt ; } ICOORD * ends [ kNumEndPoints ] ; if ( skip_last >= pt_count ) { skip_last = pt_count - 1 ; } int end_count = 0 ; end_i = std :: max ( 0 , pt_count - kNumEndPoints - skip_last ) ; for ( int i = pt_count - 1 - skip_last ; i >= end_i ; -- i ) { ends [ end_count ++ ] = & pts_ [ i ] . pt ; } if ( pt_count <= 2 ) { * pt1 = * starts [ 0 ] ; if ( pt_count > 1 ) { * pt2 = * ends [ 0 ] ; } else { * pt2 = * pt1 ; } return 0.0 ; } double best_uq = -1.0 ; for ( int i = 0 ; i < start_count ; ++ i ) { ICOORD * start = starts [ i ] ; for ( int j = 0 ; j < end_count ; ++ j ) { ICOORD * end = ends [ j ] ; if ( * start != * end ) { ComputeDistances ( * start , * end ) ; double dist = EvaluateLineFit ( ) ; if ( dist < best_uq || best_uq < 0.0 ) { best_uq = dist ; * pt1 = * start ; * pt2 = * end ; } } } } return best_uq > 0.0 ? sqrt ( best_uq ) : best_uq ; }
Fits a line to the points, ignoring the skip_first initial points and the
skip_last final points, returning the fitted line as a pair of points,
and the upper quartile error.
Fits a line to the points ignoring the skip_first initial points and the skip_last final points returning the fitted line as a pair of points and the upper quartile error .
// Do something sensible with no points. // Count the points and find the first and last kNumEndPoints. // 1 or 2 points need special treatment. // Although with between 2 and 2*kNumEndPoints-1 points, there will be // overlap in the starts, ends sets, this is OK and taken care of by the // if (*start != *end) test below, which also tests for equal input points. // Iterate each pair of points and find the best fitting line. // Compute the upper quartile error from the line. // Finally compute the square root to return the true distance.