Example #1
0
/* the main pattern recognition function, called after finalize_stroke() */
void recognize_patterns(void)
{
  struct Item *it;
  struct Inertia s, ss[4];
  struct RecoSegment *rs;
  int n, i;
  int brk[5];
  double score;
  
  if (!undo || undo->type!=ITEM_STROKE) return;
  if (undo->next != last_item_checker) reset_recognizer(); // reset queue
  if (last_item_checker!=NULL && ui.cur_layer != last_item_checker->layer) reset_recognizer();

  it = undo->item;
  calc_inertia(it->path->coords, 0, it->path->num_points-1, &s);
#ifdef RECOGNIZER_DEBUG
  printf("DEBUG: Mass=%.0f, Center=(%.1f,%.1f), I=(%.0f,%.0f, %.0f), "
     "Rad=%.2f, Det=%.4f \n", 
     s.mass, center_x(s), center_y(s), I_xx(s), I_yy(s), I_xy(s), I_rad(s), I_det(s));
#endif

  // first see if it's a polygon
  n = find_polygonal(it->path->coords, 0, it->path->num_points-1, MAX_POLYGON_SIDES, brk, ss);
  if (n>0) {
    optimize_polygonal(it->path->coords, n, brk, ss);
#ifdef RECOGNIZER_DEBUG
    printf("DEBUG: Polygon, %d edges: ", n);
    for (i=0; i<n; i++)
      printf("DEBUG: %d-%d (M=%.0f, det=%.4f) ", brk[i], brk[i+1], ss[i].mass, I_det(ss[i]));
    printf("\n");
#endif
    /* update recognizer segment queue (most recent at end) */
    while (n+recognizer_queue_length > MAX_POLYGON_SIDES) {
      // remove oldest polygonal stroke
      i=1;
      while (i<recognizer_queue_length && recognizer_queue[i].startpt!=0) i++;
      recognizer_queue_length-=i;
      g_memmove(recognizer_queue, recognizer_queue+i, 
              recognizer_queue_length * sizeof(struct RecoSegment));
    }
#ifdef RECOGNIZER_DEBUG
    printf("DEBUG: Queue now has %d + %d edges\n", recognizer_queue_length, n);
#endif
    rs = recognizer_queue + recognizer_queue_length;
    recognizer_queue_length += n;
    for (i=0; i<n; i++) {
      rs[i].item = it;
      rs[i].startpt = brk[i];
      rs[i].endpt = brk[i+1];
      get_segment_geometry(it->path->coords, brk[i], brk[i+1], ss+i, rs+i);
    }  
    if (try_rectangle()) { reset_recognizer(); return; }
    if (try_arrow()) { reset_recognizer(); return; }
    if (try_closed_polygon(3)) { reset_recognizer(); return; }
    if (try_closed_polygon(4)) { reset_recognizer(); return; }
    if (n==1) { // current stroke is a line
      if (fabs(rs->angle)<SLANT_TOLERANCE) { // nearly horizontal
        rs->angle = 0.;
        rs->y1 = rs->y2 = rs->ycenter;
      }
      if (fabs(rs->angle)>M_PI/2-SLANT_TOLERANCE) { // nearly vertical
        rs->angle = (rs->angle>0)?(M_PI/2):(-M_PI/2);
        rs->x1 = rs->x2 = rs->xcenter;
      }
      realloc_cur_path(2);
      ui.cur_path.num_points = 2;
      ui.cur_path.coords[0] = rs->x1;
      ui.cur_path.coords[1] = rs->y1;
      ui.cur_path.coords[2] = rs->x2;
      ui.cur_path.coords[3] = rs->y2;
      remove_recognized_strokes(rs, 1);
      rs->item = insert_recognized_curpath();
    }
    last_item_checker = undo;
    return;
  }

  // not a polygon: maybe a circle ?
  reset_recognizer();
  if (I_det(s)>CIRCLE_MIN_DET) {
    score = score_circle(it->path->coords, 0, it->path->num_points-1, &s);
#ifdef RECOGNIZER_DEBUG
    printf("DEBUG: Circle score: %.2f\n", score);
#endif
    if (score < CIRCLE_MAX_SCORE) {
      make_circle_shape(center_x(s), center_y(s), I_rad(s));
      recognizer_queue[0].item = it;
      remove_recognized_strokes(recognizer_queue, 1);
      insert_recognized_curpath();
    }
  }
}
double Log_data_grid::get_support(int nodeid) const{
  const Log_data::Segment_geometry& geom = get_segment_geometry( nodeid);
  return geom.length;
}