/* 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; }