wordrec/chop.cpp File Reference

#include "chop.h"
#include "debug.h"
#include "outlines.h"
#include "olutil.h"
#include "tordvars.h"
#include "callcpp.h"
#include "plotedges.h"
#include "const.h"
#include <math.h>

Go to the source code of this file.

Defines

Functions


Define Documentation

#define length_product ( p1,
p2   ) 

Value:

(sqrt ((((float) (p1).x * (p1).x + (float) (p1).y * (p1).y) *    \
         ((float) (p2).x * (p2).x + (float) (p2).y * (p2).y))))
Compute the product of the length of two vectors.

The vectors must be of type POINT. This product is used in computing angles.

Definition at line 92 of file chop.cpp.

Referenced by angle_change().


Function Documentation

void add_point_to_list ( POINT_GROUP  point_list,
EDGEPT point 
)

Add an edge point to a POINT_GROUP containg a list of other points.

Definition at line 115 of file chop.cpp.

References chop_debug, HEAPENTRY::Data, HeapStore(), HEAPENTRY::Key, mark_outline(), MAX_NUM_POINTS, point_priority(), and SizeOfHeap.

Referenced by new_max_point(), new_min_point(), and prioritize_points().

00115                                                               {
00116   HEAPENTRY data;
00117 
00118   if (SizeOfHeap (point_list) < MAX_NUM_POINTS - 2) {
00119     data.Data = (char *) point;
00120     data.Key = point_priority (point);
00121     HeapStore(point_list, &data);
00122   }
00123 
00124 #ifndef GRAPHICS_DISABLED
00125   if (chop_debug)
00126     mark_outline(point);
00127 #endif
00128 }

int angle_change ( EDGEPT point1,
EDGEPT point2,
EDGEPT point3 
)

Return the change in angle (degrees) of the line segments between points one and two, and two and three.

Definition at line 136 of file chop.cpp.

References CROSS, length_product, PI, edgeptstruct::pos, SCALAR, TPOINT::x, and TPOINT::y.

00136                                                                  {
00137   VECTOR vector1;
00138   VECTOR vector2;
00139 
00140   int angle;
00141   float length;
00142 
00143   /* Compute angle */
00144   vector1.x = point2->pos.x - point1->pos.x;
00145   vector1.y = point2->pos.y - point1->pos.y;
00146   vector2.x = point3->pos.x - point2->pos.x;
00147   vector2.y = point3->pos.y - point2->pos.y;
00148   /* Use cross product */
00149   length = length_product (vector1, vector2);
00150   if ((int) length == 0)
00151     return (0);
00152   angle = (int) (asin (CROSS (vector1, vector2) / length) / PI * 180.0);
00153 
00154   /* Use dot product */
00155   if (SCALAR (vector1, vector2) < 0)
00156     angle = 180 - angle;
00157   /* Adjust angle */
00158   if (angle > 180)
00159     angle -= 360;
00160   if (angle <= -180)
00161     angle += 360;
00162   return (angle);
00163 }

void init_chop (  ) 

Create the required chopper variables.

Definition at line 170 of file chop.cpp.

Referenced by init_ms_debug().

00170                  {
00171   make_same_distance();
00172   make_vertical_creep();
00173   make_x_y_weight();
00174   make_chop_enable();
00175   make_chop_debug();
00176   make_split_dist();
00177   make_overlap_knob();
00178   make_sharpness_knob();
00179   make_width_change();
00180   make_good_split();
00181   make_ok_split();
00182   make_center_knob();
00183   make_split_length();
00184   make_min_points();
00185   make_inside_angle();
00186   make_outline_area();
00187 }

int is_little_chunk ( EDGEPT point1,
EDGEPT point2 
)

Return TRUE if one of the pieces resulting from this split would less than some number of edge points.

Definition at line 195 of file chop.cpp.

References FALSE, is_same_edgept(), is_small_area(), min_outline_points, edgeptstruct::next, and TRUE.

Referenced by constrained_split().

00195                                                     {
00196   EDGEPT *p = point1;            /* Iterator */
00197   int counter = 0;
00198 
00199   do {
00200                                  /* Go from P1 to P2 */
00201     if (is_same_edgept (point2, p)) {
00202       if (is_small_area (point1, point2))
00203         return (TRUE);
00204       else
00205         break;
00206     }
00207     p = p->next;
00208   }
00209   while ((p != point1) && (counter++ < min_outline_points));
00210   /* Go from P2 to P1 */
00211   p = point2;
00212   counter = 0;
00213   do {
00214     if (is_same_edgept (point1, p)) {
00215       return (is_small_area (point2, point1));
00216     }
00217     p = p->next;
00218   }
00219   while ((p != point2) && (counter++ < min_outline_points));
00220 
00221   return (FALSE);
00222 }

int is_small_area ( EDGEPT point1,
EDGEPT point2 
)

Test the area defined by a split accross this outline.

Definition at line 229 of file chop.cpp.

References CROSS, is_same_edgept(), min_outline_area, edgeptstruct::next, edgeptstruct::pos, edgeptstruct::vec, TPOINT::x, and TPOINT::y.

Referenced by is_little_chunk().

00229                                                   {
00230   EDGEPT *p = point1->next;      /* Iterator */
00231   int area = 0;
00232   TPOINT origin;
00233 
00234   do {
00235                                  /* Go from P1 to P2 */
00236     origin.x = p->pos.x - point1->pos.x;
00237     origin.y = p->pos.y - point1->pos.y;
00238     area += CROSS (origin, p->vec);
00239     p = p->next;
00240   }
00241   while (!is_same_edgept (point2, p));
00242 
00243   return (area < min_outline_area);
00244 }

void new_max_point ( EDGEPT local_max,
POINT_GROUP  points 
)

Found a new minimum point try to decide whether to save it or not.

Return the new value for the local minimum. If a point is saved then the local minimum is reset to NULL.

Definition at line 382 of file chop.cpp.

References add_point_to_list(), direction(), and point_priority().

Referenced by prioritize_points().

00382                                                           {
00383   INT16 dir;
00384 
00385   dir = direction (local_max);
00386 
00387   if (dir > 0) {
00388     add_point_to_list(points, local_max);
00389     return;
00390   }
00391 
00392   if (dir == 0 && point_priority (local_max) < 0) {
00393     add_point_to_list(points, local_max);
00394     return;
00395   }
00396 }

void new_min_point ( EDGEPT local_min,
POINT_GROUP  points 
)

Found a new minimum point try to decide whether to save it or not.

Return the new value for the local minimum. If a point is saved then the local minimum is reset to NULL.

Definition at line 358 of file chop.cpp.

References add_point_to_list(), direction(), and point_priority().

Referenced by prioritize_points().

00358                                                           {
00359   INT16 dir;
00360 
00361   dir = direction (local_min);
00362 
00363   if (dir < 0) {
00364     add_point_to_list(points, local_min);
00365     return;
00366   }
00367 
00368   if (dir == 0 && point_priority (local_min) < 0) {
00369     add_point_to_list(points, local_min);
00370     return;
00371   }
00372 }

EDGEPT* pick_close_point ( EDGEPT critical_point,
EDGEPT vertical_point,
int *  best_dist 
)

Choose the edge point that is closest to the critical point.

This point may not be exactly vertical from the critical point.

Definition at line 253 of file chop.cpp.

References edgept_dist, FALSE, is_exterior_point, edgeptstruct::next, NULL, edgeptstruct::pos, same_point, and TRUE.

Referenced by vertical_projection_point().

00255                                          {
00256   EDGEPT *best_point = NULL;
00257   int this_distance;
00258   int found_better;
00259 
00260   do {
00261     found_better = FALSE;
00262 
00263     this_distance = edgept_dist (critical_point, vertical_point);
00264     if (this_distance <= *best_dist) {
00265 
00266       if (!(same_point (critical_point->pos, vertical_point->pos) ||
00267         same_point (critical_point->pos, vertical_point->next->pos)
00268         || best_point != NULL
00269         && same_point (best_point->pos, vertical_point->pos) ||
00270       is_exterior_point (critical_point, vertical_point))) {
00271         *best_dist = this_distance;
00272         best_point = vertical_point;
00273         if (vertical_creep)
00274           found_better = TRUE;
00275       }
00276     }
00277     vertical_point = vertical_point->next;
00278   }
00279   while (found_better == TRUE);
00280 
00281   return (best_point);
00282 }

PRIORITY point_priority ( EDGEPT point  ) 

Assign a priority to and edge point that might be used as part of a split.

The argument should be of type EDGEPT.

Definition at line 106 of file chop.cpp.

References point_bend_angle.

Referenced by add_point_to_list(), grade_sharpness(), new_max_point(), new_min_point(), and prioritize_points().

00106                                        {
00107   return ((PRIORITY) point_bend_angle (point));
00108 }

void prioritize_points ( TESSLINE outline,
POINT_GROUP  points 
)

Find a list of edge points from the outer outline of this blob.

For each of these points assign a priority. Sort these points using a heap structure so that they can be visited in order.

Definition at line 292 of file chop.cpp.

References add_point_to_list(), cprintf(), debug_5, direction(), is_inside_angle, olinestruct::loop, new_max_point(), new_min_point(), edgeptstruct::next, NULL, point_priority(), edgeptstruct::pos, edgeptstruct::prev, edgeptstruct::vec, TPOINT::x, and TPOINT::y.

Referenced by pick_good_seam().

00292                                                               {
00293   EDGEPT *this_point;
00294   EDGEPT *local_min = NULL;
00295   EDGEPT *local_max = NULL;
00296 
00297   this_point = outline->loop;
00298   local_min = this_point;
00299   local_max = this_point;
00300   do {
00301     if (debug_5)
00302       cprintf ("(%3d,%3d)  min=%3d, max=%3d, dir=%2d, ang=%2.0f\n",
00303         this_point->pos.x, this_point->pos.y,
00304         (local_min ? local_min->pos.y : 999),
00305       (local_max ? local_max->pos.y : 999),
00306       direction (this_point), point_priority (this_point));
00307 
00308     if (this_point->vec.y < 0) {
00309                                  /* Look for minima */
00310       if (local_max != NULL)
00311         new_max_point(local_max, points);
00312       else if (is_inside_angle (this_point))
00313         add_point_to_list(points, this_point);
00314       local_max = NULL;
00315       local_min = this_point->next;
00316     }
00317     else if (this_point->vec.y > 0) {
00318                                  /* Look for maxima */
00319       if (local_min != NULL)
00320         new_min_point(local_min, points);
00321       else if (is_inside_angle (this_point))
00322         add_point_to_list(points, this_point);
00323       local_min = NULL;
00324       local_max = this_point->next;
00325     }
00326     else {
00327       /* Flat area */
00328       if (local_max != NULL) {
00329         if (local_max->prev->vec.y != 0) {
00330           new_max_point(local_max, points);
00331         }
00332         local_max = this_point->next;
00333         local_min = NULL;
00334       }
00335       else {
00336         if (local_min->prev->vec.y != 0) {
00337           new_min_point(local_min, points);
00338         }
00339         local_min = this_point->next;
00340         local_max = NULL;
00341       }
00342     }
00343 
00344                                  /* Next point */
00345     this_point = this_point->next;
00346   }
00347   while (this_point != outline->loop);
00348 }

void vertical_projection_point ( EDGEPT split_point,
EDGEPT target_point,
EDGEPT **  best_point 
)

Find projection for split point.

Parameters:
split_point Split point
target_point FIX: point of intersection of projection with edge?
best_point Modified by function
Returns:
None, best_point is modified
For one point on the outline, find the corresponding point on the other side of the outline that is a likely projection for a split point.

This is done by iterating through the edge points until the X value of the point being looked at is greater than the X value of the split point. Ensure that the point found is not right next to the split point.

Note:
v1.02 used to RETURN the best_point

Definition at line 418 of file chop.cpp.

References edgept_dist, LARGE_DISTANCE, near_point(), ELIST_LINK::next, edgeptstruct::next, NULL, pick_close_point(), edgeptstruct::pos, same_point, and TPOINT::x.

Referenced by try_vertical_splits().

00419                                                     {
00420   EDGEPT *p;                     /* Iterator */
00421   EDGEPT *this_edgept;           /* Iterator */
00422   int x = split_point->pos.x;    /* X value of vertical */
00423   int best_dist = LARGE_DISTANCE;/* Best point found */
00424 
00425   if (*best_point != NULL)
00426     best_dist = edgept_dist(split_point, *best_point);
00427 
00428   p = target_point;
00429   /* Look at each edge point */
00430   do {
00431     if ((((p->pos.x <= x) && (x <= p->next->pos.x)) ||
00432       ((p->next->pos.x <= x) && (x <= p->pos.x))) &&
00433       !same_point (split_point->pos, p->pos) &&
00434       !same_point (split_point->pos, p->next->pos)
00435     && (*best_point == NULL || !same_point ((*best_point)->pos, p->pos))) {
00436 
00437       this_edgept = near_point (split_point, p, p->next);
00438 
00439       if (*best_point == NULL)
00440         best_dist = edgept_dist (split_point, this_edgept);
00441 
00442       this_edgept =
00443         pick_close_point(split_point, this_edgept, &best_dist);
00444       if (this_edgept)
00445         *best_point = this_edgept;
00446     }
00447 
00448     p = p->next;
00449   }
00450   while (p != target_point);
00451 }


Generated on Wed Feb 28 19:49:28 2007 for Tesseract by  doxygen 1.5.1