tesseract  3.03
/usr/local/google/home/jbreiden/tesseract-ocr-read-only/ccstruct/points.cpp
Go to the documentation of this file.
00001 /**********************************************************************
00002  * File:        points.c  (Formerly coords.c)
00003  * Description: Member functions for coordinate classes.
00004  * Author:                                      Ray Smith
00005  * Created:                                     Fri Mar 15 08:58:17 GMT 1991
00006  *
00007  * (C) Copyright 1991, Hewlett-Packard Ltd.
00008  ** Licensed under the Apache License, Version 2.0 (the "License");
00009  ** you may not use this file except in compliance with the License.
00010  ** You may obtain a copy of the License at
00011  ** http://www.apache.org/licenses/LICENSE-2.0
00012  ** Unless required by applicable law or agreed to in writing, software
00013  ** distributed under the License is distributed on an "AS IS" BASIS,
00014  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
00015  ** See the License for the specific language governing permissions and
00016  ** limitations under the License.
00017  *
00018  **********************************************************************/
00019 
00020 #ifdef _MSC_VER
00021 #define _USE_MATH_DEFINES
00022 #endif  // _MSC_VER
00023 
00024 #include          <stdlib.h>
00025 #include          "helpers.h"
00026 #include          "ndminx.h"
00027 #include          "serialis.h"
00028 #include          "points.h"
00029 
00030 ELISTIZE (ICOORDELT)           //turn to list
00031 bool FCOORD::normalise() {  //Convert to unit vec
00032   float len = length ();
00033 
00034   if (len < 0.0000000001) {
00035     return false;
00036   }
00037   xcoord /= len;
00038   ycoord /= len;
00039   return true;
00040 }
00041 
00042 // Set from the given x,y, shrinking the vector to fit if needed.
00043 void ICOORD::set_with_shrink(int x, int y) {
00044   // Fit the vector into an ICOORD, which is 16 bit.
00045   int factor = 1;
00046   int max_extent = MAX(abs(x), abs(y));
00047   if (max_extent > MAX_INT16)
00048     factor = max_extent / MAX_INT16 + 1;
00049   xcoord = x / factor;
00050   ycoord = y / factor;
00051 }
00052 
00053 // The fortran/basic sgn function returns -1, 0, 1 if x < 0, x == 0, x > 0
00054 // respectively.
00055 static int sign(int x) {
00056   if (x < 0)
00057     return -1;
00058   else
00059     return x > 0 ? 1 : 0;
00060 }
00061 
00062 // Writes to the given file. Returns false in case of error.
00063 bool ICOORD::Serialize(FILE* fp) const {
00064   if (fwrite(&xcoord, sizeof(xcoord), 1, fp) != 1) return false;
00065   if (fwrite(&ycoord, sizeof(ycoord), 1, fp) != 1) return false;
00066   return true;
00067 }
00068 // Reads from the given file. Returns false in case of error.
00069 // If swap is true, assumes a big/little-endian swap is needed.
00070 bool ICOORD::DeSerialize(bool swap, FILE* fp) {
00071   if (fread(&xcoord, sizeof(xcoord), 1, fp) != 1) return false;
00072   if (fread(&ycoord, sizeof(ycoord), 1, fp) != 1) return false;
00073   if (swap) {
00074     ReverseN(&xcoord, sizeof(xcoord));
00075     ReverseN(&ycoord, sizeof(ycoord));
00076   }
00077   return true;
00078 }
00079 
00080 // Setup for iterating over the pixels in a vector by the well-known
00081 // Bresenham rendering algorithm.
00082 // Starting with major/2 in the accumulator, on each step add major_step,
00083 // and then add minor to the accumulator. When the accumulator >= major
00084 // subtract major and step a minor step.
00085 
00086 void ICOORD::setup_render(ICOORD* major_step, ICOORD* minor_step,
00087                           int* major, int* minor) const {
00088   int abs_x = abs(xcoord);
00089   int abs_y = abs(ycoord);
00090   if (abs_x >= abs_y) {
00091     // X-direction is major.
00092     major_step->xcoord = sign(xcoord);
00093     major_step->ycoord = 0;
00094     minor_step->xcoord = 0;
00095     minor_step->ycoord = sign(ycoord);
00096     *major = abs_x;
00097     *minor = abs_y;
00098   } else {
00099     // Y-direction is major.
00100     major_step->xcoord = 0;
00101     major_step->ycoord = sign(ycoord);
00102     minor_step->xcoord = sign(xcoord);
00103     minor_step->ycoord = 0;
00104     *major = abs_y;
00105     *minor = abs_x;
00106   }
00107 }
00108 
00109 // Returns the standard feature direction corresponding to this.
00110 // See binary_angle_plus_pi below for a description of the direction.
00111 uinT8 FCOORD::to_direction() const {
00112   return binary_angle_plus_pi(angle());
00113 }
00114 // Sets this with a unit vector in the given standard feature direction.
00115 void FCOORD::from_direction(uinT8 direction) {
00116   double radians = angle_from_direction(direction);
00117   xcoord = cos(radians);
00118   ycoord = sin(radians);
00119 }
00120 
00121 // Converts an angle in radians (from ICOORD::angle or FCOORD::angle) to a
00122 // standard feature direction as an unsigned angle in 256ths of a circle
00123 // measured anticlockwise from (-1, 0).
00124 uinT8 FCOORD::binary_angle_plus_pi(double radians) {
00125   return Modulo(IntCastRounded((radians + M_PI) * 128.0 / M_PI), 256);
00126 }
00127 // Inverse of binary_angle_plus_pi returns an angle in radians for the
00128 // given standard feature direction.
00129 double FCOORD::angle_from_direction(uinT8 direction) {
00130   return direction * M_PI / 128.0 - M_PI;
00131 }
00132 
00133 // Returns the point on the given line nearest to this, ie the point such
00134 // that the vector point->this is perpendicular to the line.
00135 // The line is defined as a line_point and a dir_vector for its direction.
00136 FCOORD FCOORD::nearest_pt_on_line(const FCOORD& line_point,
00137                                   const FCOORD& dir_vector) const {
00138   FCOORD point_vector(*this - line_point);
00139   // The dot product (%) is |dir_vector||point_vector|cos theta, so dividing by
00140   // the square of the length of dir_vector gives us the fraction of dir_vector
00141   // to add to line1 to get the appropriate point, so
00142   // result = line1 + lambda dir_vector.
00143   double lambda = point_vector % dir_vector / dir_vector.sqlength();
00144   return line_point + (dir_vector * lambda);
00145 }
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines