Tesseract
3.02
|
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 }