Tesseract
3.02
|
00001 /* -*-C-*- 00002 ******************************************************************************** 00003 * 00004 * File: outlines.c (Formerly outlines.c) 00005 * Description: Combinatorial Splitter 00006 * Author: Mark Seaman, OCR Technology 00007 * Created: Thu Jul 27 08:59:01 1989 00008 * Modified: Wed Jul 10 14:56:49 1991 (Mark Seaman) marks@hpgrlt 00009 * Language: C 00010 * Package: N/A 00011 * Status: Experimental (Do Not Distribute) 00012 * 00013 * (c) Copyright 1989, Hewlett-Packard Company. 00014 ** Licensed under the Apache License, Version 2.0 (the "License"); 00015 ** you may not use this file except in compliance with the License. 00016 ** You may obtain a copy of the License at 00017 ** http://www.apache.org/licenses/LICENSE-2.0 00018 ** Unless required by applicable law or agreed to in writing, software 00019 ** distributed under the License is distributed on an "AS IS" BASIS, 00020 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 00021 ** See the License for the specific language governing permissions and 00022 ** limitations under the License. 00023 * 00024 ******************************************************************************** 00025 * Revision 1.2 89/09/15 09:24:41 09:24:41 marks (Mark Seaman) 00026 * First released version of Combinatorial splitter code 00027 **/ 00028 /*---------------------------------------------------------------------- 00029 I n c l u d e s 00030 ----------------------------------------------------------------------*/ 00031 #include "outlines.h" 00032 #include "wordrec.h" 00033 00034 #ifdef __UNIX__ 00035 #include <assert.h> 00036 #endif 00037 00038 namespace tesseract { 00039 /*---------------------------------------------------------------------- 00040 F u n c t i o n s 00041 ----------------------------------------------------------------------*/ 00042 /********************************************************************** 00043 * crosses_outline 00044 * 00045 * Check to see if this line crosses over this outline. If it does 00046 * return TRUE. 00047 **********************************************************************/ 00048 int Wordrec::crosses_outline(EDGEPT *p0, /* Start of line */ 00049 EDGEPT *p1, /* End of line */ 00050 EDGEPT *outline) { /* Outline to check */ 00051 EDGEPT *pt = outline; 00052 do { 00053 if (is_crossed (p0->pos, p1->pos, pt->pos, pt->next->pos)) 00054 return (TRUE); 00055 pt = pt->next; 00056 } 00057 while (pt != outline); 00058 return (FALSE); 00059 } 00060 00061 00062 /********************************************************************** 00063 * is_crossed 00064 * 00065 * Return TRUE when the two line segments cross each other. Find out 00066 * where the projected lines would cross and then check to see if the 00067 * point of intersection lies on both of the line segments. If it does 00068 * then these two segments cross. 00069 **********************************************************************/ 00070 int Wordrec::is_crossed(TPOINT a0, TPOINT a1, TPOINT b0, TPOINT b1) { 00071 int b0a1xb0b1, b0b1xb0a0; 00072 int a1b1xa1a0, a1a0xa1b0; 00073 00074 TPOINT b0a1, b0a0, a1b1, b0b1, a1a0; 00075 00076 b0a1.x = a1.x - b0.x; 00077 b0a0.x = a0.x - b0.x; 00078 a1b1.x = b1.x - a1.x; 00079 b0b1.x = b1.x - b0.x; 00080 a1a0.x = a0.x - a1.x; 00081 b0a1.y = a1.y - b0.y; 00082 b0a0.y = a0.y - b0.y; 00083 a1b1.y = b1.y - a1.y; 00084 b0b1.y = b1.y - b0.y; 00085 a1a0.y = a0.y - a1.y; 00086 00087 b0a1xb0b1 = CROSS (b0a1, b0b1); 00088 b0b1xb0a0 = CROSS (b0b1, b0a0); 00089 a1b1xa1a0 = CROSS (a1b1, a1a0); 00090 /*a1a0xa1b0=CROSS(a1a0,a1b0); */ 00091 a1a0xa1b0 = -CROSS (a1a0, b0a1); 00092 00093 return ((b0a1xb0b1 > 0 && b0b1xb0a0 > 0) 00094 || (b0a1xb0b1 < 0 && b0b1xb0a0 < 0)) 00095 && ((a1b1xa1a0 > 0 && a1a0xa1b0 > 0) || (a1b1xa1a0 < 0 && a1a0xa1b0 < 0)); 00096 } 00097 00098 00099 /********************************************************************** 00100 * is_same_edgept 00101 * 00102 * Return true if the points are identical. 00103 **********************************************************************/ 00104 int Wordrec::is_same_edgept(EDGEPT *p1, EDGEPT *p2) { 00105 return (p1 == p2); 00106 } 00107 00108 00109 /********************************************************************** 00110 * near_point 00111 * 00112 * Find the point on a line segment that is closest to a point not on 00113 * the line segment. Return that point in near_pt. Returns whether 00114 * near_pt was newly created. 00115 **********************************************************************/ 00116 bool Wordrec::near_point(EDGEPT *point, 00117 EDGEPT *line_pt_0, EDGEPT *line_pt_1, 00118 EDGEPT **near_pt) { 00119 TPOINT p; 00120 00121 float slope; 00122 float intercept; 00123 00124 float x0 = line_pt_0->pos.x; 00125 float x1 = line_pt_1->pos.x; 00126 float y0 = line_pt_0->pos.y; 00127 float y1 = line_pt_1->pos.y; 00128 00129 if (x0 == x1) { 00130 /* Handle vertical line */ 00131 p.x = (inT16) x0; 00132 p.y = point->pos.y; 00133 } 00134 else { 00135 /* Slope and intercept */ 00136 slope = (y0 - y1) / (x0 - x1); 00137 intercept = y1 - x1 * slope; 00138 00139 /* Find perpendicular */ 00140 p.x = (inT16) ((point->pos.x + (point->pos.y - intercept) * slope) / 00141 (slope * slope + 1)); 00142 p.y = (inT16) (slope * p.x + intercept); 00143 } 00144 00145 if (is_on_line (p, line_pt_0->pos, line_pt_1->pos) && 00146 (!same_point (p, line_pt_0->pos)) && (!same_point (p, line_pt_1->pos))) { 00147 /* Intersection on line */ 00148 *near_pt = make_edgept(p.x, p.y, line_pt_1, line_pt_0); 00149 return true; 00150 } else { /* Intersection not on line */ 00151 *near_pt = closest(point, line_pt_0, line_pt_1); 00152 return false; 00153 } 00154 } 00155 00156 00157 /********************************************************************** 00158 * reverse_outline 00159 * 00160 * Change the direction of the outline. If it was clockwise make it 00161 * counter-clockwise and vice versa. Do this by swapping each of the 00162 * next and prev fields of each edge point. 00163 **********************************************************************/ 00164 void Wordrec::reverse_outline(EDGEPT *outline) { 00165 EDGEPT *edgept = outline; 00166 EDGEPT *temp; 00167 00168 do { 00169 /* Swap next and prev */ 00170 temp = edgept->prev; 00171 edgept->prev = edgept->next; 00172 edgept->next = temp; 00173 /* Set up vec field */ 00174 edgept->vec.x = edgept->next->pos.x - edgept->pos.x; 00175 edgept->vec.y = edgept->next->pos.y - edgept->pos.y; 00176 00177 edgept = edgept->prev; /* Go to next point */ 00178 } 00179 while (edgept != outline); 00180 } 00181 00182 } // namespace tesseract