Tesseract  3.02
tesseract-ocr/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 #include          "mfcpch.h"     //precompiled headers
00021 #include          <stdlib.h>
00022 #include          "helpers.h"
00023 #include          "ndminx.h"
00024 #include          "serialis.h"
00025 #include          "points.h"
00026 
00027 ELISTIZE (ICOORDELT)           //turn to list
00028 bool FCOORD::normalise() {  //Convert to unit vec
00029   float len = length ();
00030 
00031   if (len < 0.0000000001) {
00032     return false;
00033   }
00034   xcoord /= len;
00035   ycoord /= len;
00036   return true;
00037 }
00038 
00039 // Set from the given x,y, shrinking the vector to fit if needed.
00040 void ICOORD::set_with_shrink(int x, int y) {
00041   // Fit the vector into an ICOORD, which is 16 bit.
00042   int factor = 1;
00043   int max_extent = MAX(abs(x), abs(y));
00044   if (max_extent > MAX_INT16)
00045     factor = max_extent / MAX_INT16 + 1;
00046   xcoord = x / factor;
00047   ycoord = y / factor;
00048 }
00049 
00050 // The fortran/basic sgn function returns -1, 0, 1 if x < 0, x == 0, x > 0
00051 // respectively.
00052 static int sign(int x) {
00053   if (x < 0)
00054     return -1;
00055   else
00056     return x > 0 ? 1 : 0;
00057 }
00058 
00059 // Writes to the given file. Returns false in case of error.
00060 bool ICOORD::Serialize(FILE* fp) const {
00061   if (fwrite(&xcoord, sizeof(xcoord), 1, fp) != 1) return false;
00062   if (fwrite(&ycoord, sizeof(ycoord), 1, fp) != 1) return false;
00063   return true;
00064 }
00065 // Reads from the given file. Returns false in case of error.
00066 // If swap is true, assumes a big/little-endian swap is needed.
00067 bool ICOORD::DeSerialize(bool swap, FILE* fp) {
00068   if (fread(&xcoord, sizeof(xcoord), 1, fp) != 1) return false;
00069   if (fread(&ycoord, sizeof(ycoord), 1, fp) != 1) return false;
00070   if (swap) {
00071     ReverseN(&xcoord, sizeof(xcoord));
00072     ReverseN(&ycoord, sizeof(ycoord));
00073   }
00074   return true;
00075 }
00076 
00077 // Setup for iterating over the pixels in a vector by the well-known
00078 // Bresenham rendering algorithm.
00079 // Starting with major/2 in the accumulator, on each step add major_step,
00080 // and then add minor to the accumulator. When the accumulator >= major
00081 // subtract major and step a minor step.
00082 
00083 void ICOORD::setup_render(ICOORD* major_step, ICOORD* minor_step,
00084                           int* major, int* minor) const {
00085   int abs_x = abs(xcoord);
00086   int abs_y = abs(ycoord);
00087   if (abs_x >= abs_y) {
00088     // X-direction is major.
00089     major_step->xcoord = sign(xcoord);
00090     major_step->ycoord = 0;
00091     minor_step->xcoord = 0;
00092     minor_step->ycoord = sign(ycoord);
00093     *major = abs_x;
00094     *minor = abs_y;
00095   } else {
00096     // Y-direction is major.
00097     major_step->xcoord = 0;
00098     major_step->ycoord = sign(ycoord);
00099     minor_step->xcoord = sign(xcoord);
00100     minor_step->ycoord = 0;
00101     *major = abs_y;
00102     *minor = abs_x;
00103   }
00104 }