diff options
Diffstat (limited to 'tesseract/src/ccstruct/points.h')
-rw-r--r-- | tesseract/src/ccstruct/points.h | 783 |
1 files changed, 783 insertions, 0 deletions
diff --git a/tesseract/src/ccstruct/points.h b/tesseract/src/ccstruct/points.h new file mode 100644 index 00000000..1c8a1ab6 --- /dev/null +++ b/tesseract/src/ccstruct/points.h @@ -0,0 +1,783 @@ +/********************************************************************** + * File: points.h (Formerly coords.h) + * Description: Coordinate class definitions. + * Author: Ray Smith + * + * (C) Copyright 1991, Hewlett-Packard Ltd. + ** Licensed under the Apache License, Version 2.0 (the "License"); + ** you may not use this file except in compliance with the License. + ** You may obtain a copy of the License at + ** http://www.apache.org/licenses/LICENSE-2.0 + ** Unless required by applicable law or agreed to in writing, software + ** distributed under the License is distributed on an "AS IS" BASIS, + ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + ** See the License for the specific language governing permissions and + ** limitations under the License. + * + **********************************************************************/ + +#ifndef POINTS_H +#define POINTS_H + +#include "elst.h" +#include "errcode.h" // for ASSERT_HOST + +#include <tesseract/export.h> // for DLLSYM + +#include <cmath> // for sqrt, atan2 +#include <cstdio> + +namespace tesseract { + +class FCOORD; + +///integer coordinate +class ICOORD +{ + friend class FCOORD; + + public: + ///empty constructor + ICOORD() { + xcoord = ycoord = 0; //default zero + } + ///constructor + ///@param xin x value + ///@param yin y value + ICOORD(int16_t xin, + int16_t yin) { + xcoord = xin; + ycoord = yin; + } + ///destructor + ~ICOORD () = default; + + ///access function + int16_t x() const { + return xcoord; + } + ///access_function + int16_t y() const { + return ycoord; + } + + ///rewrite function + void set_x(int16_t xin) { + xcoord = xin; //write new value + } + ///rewrite function + void set_y(int16_t yin) { //value to set + ycoord = yin; + } + + /// Set from the given x,y, shrinking the vector to fit if needed. + void set_with_shrink(int x, int y); + + ///find sq length + float sqlength() const { + return (float)(xcoord * xcoord + ycoord * ycoord); + } + + ///find length + float length() const { + return std::sqrt(sqlength()); + } + + ///sq dist between pts + float pt_to_pt_sqdist(const ICOORD &pt) const { + ICOORD gap; + + gap.xcoord = xcoord - pt.xcoord; + gap.ycoord = ycoord - pt.ycoord; + return gap.sqlength (); + } + + ///Distance between pts + float pt_to_pt_dist(const ICOORD &pt) const { + return std::sqrt(pt_to_pt_sqdist(pt)); + } + + ///find angle + float angle() const { + return (float)std::atan2(ycoord, xcoord); + } + + ///test equality + bool operator== (const ICOORD & other) const { + return xcoord == other.xcoord && ycoord == other.ycoord; + } + ///test inequality + bool operator!= (const ICOORD & other) const { + return xcoord != other.xcoord || ycoord != other.ycoord; + } + ///rotate 90 deg anti + friend ICOORD operator! (const ICOORD &); + ///unary minus + friend ICOORD operator- (const ICOORD &); + ///add + friend ICOORD operator+ (const ICOORD &, const ICOORD &); + ///add + friend ICOORD & operator+= (ICOORD &, const ICOORD &); + ///subtract + friend ICOORD operator- (const ICOORD &, const ICOORD &); + ///subtract + friend ICOORD & operator-= (ICOORD &, const ICOORD &); + ///scalar product + friend int32_t operator% (const ICOORD &, const ICOORD &); + ///cross product + friend int32_t operator *(const ICOORD &, + const ICOORD &); + ///multiply + friend ICOORD operator *(const ICOORD &, + int16_t); + ///multiply + friend ICOORD operator *(int16_t, + const ICOORD &); + ///multiply + friend ICOORD & operator*= (ICOORD &, int16_t); + ///divide + friend ICOORD operator/ (const ICOORD &, int16_t); + ///divide + friend ICOORD & operator/= (ICOORD &, int16_t); + ///rotate + ///@param vec by vector + void rotate(const FCOORD& vec); + + /// Setup for iterating over the pixels in a vector by the well-known + /// Bresenham rendering algorithm. + /// Starting with major/2 in the accumulator, on each step move by + /// major_step, and then add minor to the accumulator. When + /// accumulator >= major subtract major and also move by minor_step. + void setup_render(ICOORD* major_step, ICOORD* minor_step, + int* major, int* minor) const; + + // Writes to the given file. Returns false in case of error. + bool Serialize(FILE* fp) const; + // Reads from the given file. Returns false in case of error. + // If swap is true, assumes a big/little-endian swap is needed. + bool DeSerialize(bool swap, FILE* fp); + + protected: + int16_t xcoord; ///< x value + int16_t ycoord; ///< y value +}; + +class ICOORDELT : public ELIST_LINK, public ICOORD + //embedded coord list +{ + public: + ///empty constructor + ICOORDELT() = default; + ///constructor from ICOORD + ICOORDELT (ICOORD icoord):ICOORD (icoord) { + } + ///constructor + ///@param xin x value + ///@param yin y value + ICOORDELT(int16_t xin, + int16_t yin) { + xcoord = xin; + ycoord = yin; + } + + static ICOORDELT* deep_copy(const ICOORDELT* src) { + auto* elt = new ICOORDELT; + *elt = *src; + return elt; + } + +}; + +ELISTIZEH (ICOORDELT) + +class TESS_API FCOORD +{ + public: + ///empty constructor + FCOORD() = default; + ///constructor + ///@param xvalue x value + ///@param yvalue y value + FCOORD(float xvalue, + float yvalue) { + xcoord = xvalue; //set coords + ycoord = yvalue; + } + FCOORD( //make from ICOORD + ICOORD icoord) { //coords to set + xcoord = icoord.xcoord; + ycoord = icoord.ycoord; + } + + float x() const { //get coords + return xcoord; + } + float y() const { + return ycoord; + } + ///rewrite function + void set_x(float xin) { + xcoord = xin; //write new value + } + ///rewrite function + void set_y(float yin) { //value to set + ycoord = yin; + } + + ///find sq length + float sqlength() const { + return xcoord * xcoord + ycoord * ycoord; + } + + ///find length + float length() const { + return std::sqrt(sqlength()); + } + + ///sq dist between pts + float pt_to_pt_sqdist(const FCOORD &pt) const { + FCOORD gap; + + gap.xcoord = xcoord - pt.xcoord; + gap.ycoord = ycoord - pt.ycoord; + return gap.sqlength (); + } + + ///Distance between pts + float pt_to_pt_dist(const FCOORD &pt) const { + return std::sqrt(pt_to_pt_sqdist(pt)); + } + + ///find angle + float angle() const { + return std::atan2(ycoord, xcoord); + } + // Returns the standard feature direction corresponding to this. + // See binary_angle_plus_pi below for a description of the direction. + uint8_t to_direction() const; + // Sets this with a unit vector in the given standard feature direction. + void from_direction(uint8_t direction); + + // Converts an angle in radians (from ICOORD::angle or FCOORD::angle) to a + // standard feature direction as an unsigned angle in 256ths of a circle + // measured anticlockwise from (-1, 0). + static uint8_t binary_angle_plus_pi(double angle); + // Inverse of binary_angle_plus_pi returns an angle in radians for the + // given standard feature direction. + static double angle_from_direction(uint8_t direction); + // Returns the point on the given line nearest to this, ie the point such + // that the vector point->this is perpendicular to the line. + // The line is defined as a line_point and a dir_vector for its direction. + // dir_vector need not be a unit vector. + FCOORD nearest_pt_on_line(const FCOORD& line_point, + const FCOORD& dir_vector) const; + + ///Convert to unit vec + bool normalise(); + + ///test equality + bool operator== (const FCOORD & other) { + return xcoord == other.xcoord && ycoord == other.ycoord; + } + ///test inequality + bool operator!= (const FCOORD & other) { + return xcoord != other.xcoord || ycoord != other.ycoord; + } + ///rotate 90 deg anti + friend FCOORD operator! (const FCOORD &); + ///unary minus + friend FCOORD operator- (const FCOORD &); + ///add + friend FCOORD operator+ (const FCOORD &, const FCOORD &); + ///add + friend FCOORD & operator+= (FCOORD &, const FCOORD &); + ///subtract + friend FCOORD operator- (const FCOORD &, const FCOORD &); + ///subtract + friend FCOORD & operator-= (FCOORD &, const FCOORD &); + ///scalar product + friend float operator% (const FCOORD &, const FCOORD &); + ///cross product + friend float operator *(const FCOORD &, const FCOORD &); + ///multiply + friend FCOORD operator *(const FCOORD &, float); + ///multiply + friend FCOORD operator *(float, const FCOORD &); + + ///multiply + friend FCOORD & operator*= (FCOORD &, float); + ///divide + friend FCOORD operator/ (const FCOORD &, float); + ///rotate + ///@param vec by vector + void rotate(const FCOORD vec); + // unrotate - undo a rotate(vec) + // @param vec by vector + void unrotate(const FCOORD &vec); + ///divide + friend FCOORD & operator/= (FCOORD &, float); + + private: + float xcoord; //2 floating coords + float ycoord; +}; + +/********************************************************************** + * operator! + * + * Rotate an ICOORD 90 degrees anticlockwise. + **********************************************************************/ + +inline ICOORD +operator! ( //rotate 90 deg anti +const ICOORD & src //thing to rotate +) { + ICOORD result; //output + + result.xcoord = -src.ycoord; + result.ycoord = src.xcoord; + return result; +} + + +/********************************************************************** + * operator- + * + * Unary minus of an ICOORD. + **********************************************************************/ + +inline ICOORD +operator- ( //unary minus +const ICOORD & src //thing to minus +) { + ICOORD result; //output + + result.xcoord = -src.xcoord; + result.ycoord = -src.ycoord; + return result; +} + + +/********************************************************************** + * operator+ + * + * Add 2 ICOORDS. + **********************************************************************/ + +inline ICOORD +operator+ ( //sum vectors +const ICOORD & op1, //operands +const ICOORD & op2) { + ICOORD sum; //result + + sum.xcoord = op1.xcoord + op2.xcoord; + sum.ycoord = op1.ycoord + op2.ycoord; + return sum; +} + + +/********************************************************************** + * operator+= + * + * Add 2 ICOORDS. + **********************************************************************/ + +inline ICOORD & +operator+= ( //sum vectors +ICOORD & op1, //operands +const ICOORD & op2) { + op1.xcoord += op2.xcoord; + op1.ycoord += op2.ycoord; + return op1; +} + + +/********************************************************************** + * operator- + * + * Subtract 2 ICOORDS. + **********************************************************************/ + +inline ICOORD +operator- ( //subtract vectors +const ICOORD & op1, //operands +const ICOORD & op2) { + ICOORD sum; //result + + sum.xcoord = op1.xcoord - op2.xcoord; + sum.ycoord = op1.ycoord - op2.ycoord; + return sum; +} + + +/********************************************************************** + * operator-= + * + * Subtract 2 ICOORDS. + **********************************************************************/ + +inline ICOORD & +operator-= ( //subtract vectors +ICOORD & op1, //operands +const ICOORD & op2) { + op1.xcoord -= op2.xcoord; + op1.ycoord -= op2.ycoord; + return op1; +} + + +/********************************************************************** + * operator% + * + * Scalar product of 2 ICOORDS. + **********************************************************************/ + +inline int32_t +operator% ( //scalar product +const ICOORD & op1, //operands +const ICOORD & op2) { + return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord; +} + + +/********************************************************************** + * operator* + * + * Cross product of 2 ICOORDS. + **********************************************************************/ + +inline int32_t operator *( //cross product + const ICOORD &op1, //operands + const ICOORD &op2) { + return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord; +} + + +/********************************************************************** + * operator* + * + * Scalar multiply of an ICOORD. + **********************************************************************/ + +inline ICOORD operator *( //scalar multiply + const ICOORD &op1, //operands + int16_t scale) { + ICOORD result; //output + + result.xcoord = op1.xcoord * scale; + result.ycoord = op1.ycoord * scale; + return result; +} + + +inline ICOORD operator *( //scalar multiply + int16_t scale, + const ICOORD &op1 //operands + ) { + ICOORD result; //output + + result.xcoord = op1.xcoord * scale; + result.ycoord = op1.ycoord * scale; + return result; +} + + +/********************************************************************** + * operator*= + * + * Scalar multiply of an ICOORD. + **********************************************************************/ + +inline ICOORD & +operator*= ( //scalar multiply +ICOORD & op1, //operands +int16_t scale) { + op1.xcoord *= scale; + op1.ycoord *= scale; + return op1; +} + + +/********************************************************************** + * operator/ + * + * Scalar divide of an ICOORD. + **********************************************************************/ + +inline ICOORD +operator/ ( //scalar divide +const ICOORD & op1, //operands +int16_t scale) { + ICOORD result; //output + + result.xcoord = op1.xcoord / scale; + result.ycoord = op1.ycoord / scale; + return result; +} + + +/********************************************************************** + * operator/= + * + * Scalar divide of an ICOORD. + **********************************************************************/ + +inline ICOORD & +operator/= ( //scalar divide +ICOORD & op1, //operands +int16_t scale) { + op1.xcoord /= scale; + op1.ycoord /= scale; + return op1; +} + + +/********************************************************************** + * ICOORD::rotate + * + * Rotate an ICOORD by the given (normalized) (cos,sin) vector. + **********************************************************************/ + +inline void ICOORD::rotate( //rotate by vector + const FCOORD& vec) { + auto tmp = static_cast<int16_t>(std::floor(xcoord * vec.x() - + ycoord * vec.y() + 0.5f)); + ycoord = static_cast<int16_t>(std::floor(ycoord * vec.x() + + xcoord * vec.y() + 0.5f)); + xcoord = tmp; +} + + +/********************************************************************** + * operator! + * + * Rotate an FCOORD 90 degrees anticlockwise. + **********************************************************************/ + +inline FCOORD +operator! ( //rotate 90 deg anti +const FCOORD & src //thing to rotate +) { + FCOORD result; //output + + result.xcoord = -src.ycoord; + result.ycoord = src.xcoord; + return result; +} + + +/********************************************************************** + * operator- + * + * Unary minus of an FCOORD. + **********************************************************************/ + +inline FCOORD +operator- ( //unary minus +const FCOORD & src //thing to minus +) { + FCOORD result; //output + + result.xcoord = -src.xcoord; + result.ycoord = -src.ycoord; + return result; +} + + +/********************************************************************** + * operator+ + * + * Add 2 FCOORDS. + **********************************************************************/ + +inline FCOORD +operator+ ( //sum vectors +const FCOORD & op1, //operands +const FCOORD & op2) { + FCOORD sum; //result + + sum.xcoord = op1.xcoord + op2.xcoord; + sum.ycoord = op1.ycoord + op2.ycoord; + return sum; +} + + +/********************************************************************** + * operator+= + * + * Add 2 FCOORDS. + **********************************************************************/ + +inline FCOORD & +operator+= ( //sum vectors +FCOORD & op1, //operands +const FCOORD & op2) { + op1.xcoord += op2.xcoord; + op1.ycoord += op2.ycoord; + return op1; +} + + +/********************************************************************** + * operator- + * + * Subtract 2 FCOORDS. + **********************************************************************/ + +inline FCOORD +operator- ( //subtract vectors +const FCOORD & op1, //operands +const FCOORD & op2) { + FCOORD sum; //result + + sum.xcoord = op1.xcoord - op2.xcoord; + sum.ycoord = op1.ycoord - op2.ycoord; + return sum; +} + + +/********************************************************************** + * operator-= + * + * Subtract 2 FCOORDS. + **********************************************************************/ + +inline FCOORD & +operator-= ( //subtract vectors +FCOORD & op1, //operands +const FCOORD & op2) { + op1.xcoord -= op2.xcoord; + op1.ycoord -= op2.ycoord; + return op1; +} + + +/********************************************************************** + * operator% + * + * Scalar product of 2 FCOORDS. + **********************************************************************/ + +inline float +operator% ( //scalar product +const FCOORD & op1, //operands +const FCOORD & op2) { + return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord; +} + + +/********************************************************************** + * operator* + * + * Cross product of 2 FCOORDS. + **********************************************************************/ + +inline float operator *( //cross product + const FCOORD &op1, //operands + const FCOORD &op2) { + return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord; +} + + +/********************************************************************** + * operator* + * + * Scalar multiply of an FCOORD. + **********************************************************************/ + +inline FCOORD operator *( //scalar multiply + const FCOORD &op1, //operands + float scale) { + FCOORD result; //output + + result.xcoord = op1.xcoord * scale; + result.ycoord = op1.ycoord * scale; + return result; +} + + +inline FCOORD operator *( //scalar multiply + float scale, + const FCOORD &op1 //operands + ) { + FCOORD result; //output + + result.xcoord = op1.xcoord * scale; + result.ycoord = op1.ycoord * scale; + return result; +} + + +/********************************************************************** + * operator*= + * + * Scalar multiply of an FCOORD. + **********************************************************************/ + +inline FCOORD & +operator*= ( //scalar multiply +FCOORD & op1, //operands +float scale) { + op1.xcoord *= scale; + op1.ycoord *= scale; + return op1; +} + + +/********************************************************************** + * operator/ + * + * Scalar divide of an FCOORD. + **********************************************************************/ + +inline FCOORD +operator/ ( //scalar divide +const FCOORD & op1, //operands +float scale) { + FCOORD result; //output + ASSERT_HOST(scale != 0.0f); + result.xcoord = op1.xcoord / scale; + result.ycoord = op1.ycoord / scale; + return result; +} + + +/********************************************************************** + * operator/= + * + * Scalar divide of an FCOORD. + **********************************************************************/ + +inline FCOORD & +operator/= ( //scalar divide +FCOORD & op1, //operands +float scale) { + ASSERT_HOST(scale != 0.0f); + op1.xcoord /= scale; + op1.ycoord /= scale; + return op1; +} + + +/********************************************************************** + * rotate + * + * Rotate an FCOORD by the given (normalized) (cos,sin) vector. + **********************************************************************/ + +inline void FCOORD::rotate( //rotate by vector + const FCOORD vec) { + float tmp; + + tmp = xcoord * vec.x () - ycoord * vec.y (); + ycoord = ycoord * vec.x () + xcoord * vec.y (); + xcoord = tmp; +} + +inline void FCOORD::unrotate(const FCOORD& vec) { + rotate(FCOORD(vec.x(), -vec.y())); +} + +} // namespace tesseract + +#endif |