tesseract  5.0.0
points.h
Go to the documentation of this file.
1 /**********************************************************************
2  * File: points.h (Formerly coords.h)
3  * Description: Coordinate class definitions.
4  * Author: Ray Smith
5  *
6  * (C) Copyright 1991, Hewlett-Packard Ltd.
7  ** Licensed under the Apache License, Version 2.0 (the "License");
8  ** you may not use this file except in compliance with the License.
9  ** You may obtain a copy of the License at
10  ** http://www.apache.org/licenses/LICENSE-2.0
11  ** Unless required by applicable law or agreed to in writing, software
12  ** distributed under the License is distributed on an "AS IS" BASIS,
13  ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  ** See the License for the specific language governing permissions and
15  ** limitations under the License.
16  *
17  **********************************************************************/
18 
19 #ifndef POINTS_H
20 #define POINTS_H
21 
22 #include "elst.h"
23 #include "errcode.h" // for ASSERT_HOST
24 #include "tesstypes.h" // for TDimension
25 
26 #include <tesseract/export.h> // for DLLSYM
27 
28 #include <cmath> // for sqrt, atan2
29 #include <cstdio>
30 
31 namespace tesseract {
32 
33 class FCOORD;
34 
36 class ICOORD {
37  friend class FCOORD;
38 
39 public:
41  ICOORD() {
42  xcoord = ycoord = 0; // default zero
43  }
48  xcoord = xin;
49  ycoord = yin;
50  }
52  ~ICOORD() = default;
53 
54  bool DeSerialize(TFile *f);
55  bool Serialize(TFile *f) const;
56 
58  TDimension x() const {
59  return xcoord;
60  }
62  TDimension y() const {
63  return ycoord;
64  }
65 
67  void set_x(TDimension xin) {
68  xcoord = xin; // write new value
69  }
71  void set_y(TDimension yin) { // value to set
72  ycoord = yin;
73  }
74 
76  void set_with_shrink(int x, int y);
77 
79  float sqlength() const {
80  return (float)(xcoord * xcoord + ycoord * ycoord);
81  }
82 
84  float length() const {
85  return std::sqrt(sqlength());
86  }
87 
89  float pt_to_pt_sqdist(const ICOORD &pt) const {
90  ICOORD gap;
91 
92  gap.xcoord = xcoord - pt.xcoord;
93  gap.ycoord = ycoord - pt.ycoord;
94  return gap.sqlength();
95  }
96 
98  float pt_to_pt_dist(const ICOORD &pt) const {
99  return std::sqrt(pt_to_pt_sqdist(pt));
100  }
101 
103  float angle() const {
104  return (float)std::atan2(ycoord, xcoord);
105  }
106 
108  bool operator==(const ICOORD &other) const {
109  return xcoord == other.xcoord && ycoord == other.ycoord;
110  }
112  bool operator!=(const ICOORD &other) const {
113  return xcoord != other.xcoord || ycoord != other.ycoord;
114  }
116  friend ICOORD operator!(const ICOORD &);
118  friend ICOORD operator-(const ICOORD &);
120  friend ICOORD operator+(const ICOORD &, const ICOORD &);
122  friend ICOORD &operator+=(ICOORD &, const ICOORD &);
124  friend ICOORD operator-(const ICOORD &, const ICOORD &);
126  friend ICOORD &operator-=(ICOORD &, const ICOORD &);
128  friend int32_t operator%(const ICOORD &, const ICOORD &);
130  friend int32_t operator*(const ICOORD &, const ICOORD &);
132  friend ICOORD operator*(const ICOORD &, TDimension);
134  friend ICOORD operator*(TDimension, const ICOORD &);
136  friend ICOORD &operator*=(ICOORD &, TDimension);
138  friend ICOORD operator/(const ICOORD &, TDimension);
140  friend ICOORD &operator/=(ICOORD &, TDimension);
143  void rotate(const FCOORD &vec);
144 
150  void setup_render(ICOORD *major_step, ICOORD *minor_step, int *major, int *minor) const;
151 
152  // Writes to the given file. Returns false in case of error.
153  bool Serialize(FILE *fp) const;
154  // Reads from the given file. Returns false in case of error.
155  // If swap is true, assumes a big/little-endian swap is needed.
156  bool DeSerialize(bool swap, FILE *fp);
157 
158 protected:
161 };
162 
163 class ICOORDELT : public ELIST_LINK,
164  public ICOORD
165 // embedded coord list
166 {
167 public:
169  ICOORDELT() = default;
171  ICOORDELT(ICOORD icoord) : ICOORD(icoord) {}
176  xcoord = xin;
177  ycoord = yin;
178  }
179 
180  static ICOORDELT *deep_copy(const ICOORDELT *src) {
181  auto *elt = new ICOORDELT;
182  *elt = *src;
183  return elt;
184  }
185 };
186 
187 ELISTIZEH(ICOORDELT)
188 
190 public:
192  FCOORD() = default;
196  FCOORD(float xvalue, float yvalue) {
197  xcoord = xvalue; // set coords
198  ycoord = yvalue;
199  }
200  FCOORD( // make from ICOORD
201  ICOORD icoord) { // coords to set
202  xcoord = icoord.xcoord;
203  ycoord = icoord.ycoord;
204  }
205 
206  float x() const { // get coords
207  return xcoord;
208  }
209  float y() const {
210  return ycoord;
211  }
213  void set_x(float xin) {
214  xcoord = xin; // write new value
215  }
217  void set_y(float yin) { // value to set
218  ycoord = yin;
219  }
220 
222  float sqlength() const {
223  return xcoord * xcoord + ycoord * ycoord;
224  }
225 
227  float length() const {
228  return std::sqrt(sqlength());
229  }
230 
232  float pt_to_pt_sqdist(const FCOORD &pt) const {
233  FCOORD gap;
234 
235  gap.xcoord = xcoord - pt.xcoord;
236  gap.ycoord = ycoord - pt.ycoord;
237  return gap.sqlength();
238  }
239 
241  float pt_to_pt_dist(const FCOORD &pt) const {
242  return std::sqrt(pt_to_pt_sqdist(pt));
243  }
244 
246  float angle() const {
247  return std::atan2(ycoord, xcoord);
248  }
249  // Returns the standard feature direction corresponding to this.
250  // See binary_angle_plus_pi below for a description of the direction.
251  uint8_t to_direction() const;
252  // Sets this with a unit vector in the given standard feature direction.
253  void from_direction(uint8_t direction);
254 
255  // Converts an angle in radians (from ICOORD::angle or FCOORD::angle) to a
256  // standard feature direction as an unsigned angle in 256ths of a circle
257  // measured anticlockwise from (-1, 0).
258  static uint8_t binary_angle_plus_pi(double angle);
259  // Inverse of binary_angle_plus_pi returns an angle in radians for the
260  // given standard feature direction.
261  static double angle_from_direction(uint8_t direction);
262  // Returns the point on the given line nearest to this, ie the point such
263  // that the vector point->this is perpendicular to the line.
264  // The line is defined as a line_point and a dir_vector for its direction.
265  // dir_vector need not be a unit vector.
266  FCOORD nearest_pt_on_line(const FCOORD &line_point, const FCOORD &dir_vector) const;
267 
269  bool normalise();
270 
272  bool operator==(const FCOORD &other) {
273  return xcoord == other.xcoord && ycoord == other.ycoord;
274  }
276  bool operator!=(const FCOORD &other) {
277  return xcoord != other.xcoord || ycoord != other.ycoord;
278  }
280  friend FCOORD operator!(const FCOORD &);
282  friend FCOORD operator-(const FCOORD &);
284  friend FCOORD operator+(const FCOORD &, const FCOORD &);
286  friend FCOORD &operator+=(FCOORD &, const FCOORD &);
288  friend FCOORD operator-(const FCOORD &, const FCOORD &);
290  friend FCOORD &operator-=(FCOORD &, const FCOORD &);
292  friend float operator%(const FCOORD &, const FCOORD &);
294  friend float operator*(const FCOORD &, const FCOORD &);
296  friend FCOORD operator*(const FCOORD &, float);
298  friend FCOORD operator*(float, const FCOORD &);
299 
301  friend FCOORD &operator*=(FCOORD &, float);
303  friend FCOORD operator/(const FCOORD &, float);
306  void rotate(const FCOORD vec);
307  // unrotate - undo a rotate(vec)
308  // @param vec by vector
309  void unrotate(const FCOORD &vec);
311  friend FCOORD &operator/=(FCOORD &, float);
312 
313 private:
314  float xcoord; // 2 floating coords
315  float ycoord;
316 };
317 
318 /**********************************************************************
319  * operator!
320  *
321  * Rotate an ICOORD 90 degrees anticlockwise.
322  **********************************************************************/
323 
324 inline ICOORD operator!( // rotate 90 deg anti
325  const ICOORD &src // thing to rotate
326 ) {
327  ICOORD result; // output
328 
329  result.xcoord = -src.ycoord;
330  result.ycoord = src.xcoord;
331  return result;
332 }
333 
334 /**********************************************************************
335  * operator-
336  *
337  * Unary minus of an ICOORD.
338  **********************************************************************/
339 
340 inline ICOORD operator-( // unary minus
341  const ICOORD &src // thing to minus
342 ) {
343  ICOORD result; // output
344 
345  result.xcoord = -src.xcoord;
346  result.ycoord = -src.ycoord;
347  return result;
348 }
349 
350 /**********************************************************************
351  * operator+
352  *
353  * Add 2 ICOORDS.
354  **********************************************************************/
355 
356 inline ICOORD operator+( // sum vectors
357  const ICOORD &op1, // operands
358  const ICOORD &op2) {
359  ICOORD sum; // result
360 
361  sum.xcoord = op1.xcoord + op2.xcoord;
362  sum.ycoord = op1.ycoord + op2.ycoord;
363  return sum;
364 }
365 
366 /**********************************************************************
367  * operator+=
368  *
369  * Add 2 ICOORDS.
370  **********************************************************************/
371 
372 inline ICOORD &operator+=( // sum vectors
373  ICOORD &op1, // operands
374  const ICOORD &op2) {
375  op1.xcoord += op2.xcoord;
376  op1.ycoord += op2.ycoord;
377  return op1;
378 }
379 
380 /**********************************************************************
381  * operator-
382  *
383  * Subtract 2 ICOORDS.
384  **********************************************************************/
385 
386 inline ICOORD operator-( // subtract vectors
387  const ICOORD &op1, // operands
388  const ICOORD &op2) {
389  ICOORD sum; // result
390 
391  sum.xcoord = op1.xcoord - op2.xcoord;
392  sum.ycoord = op1.ycoord - op2.ycoord;
393  return sum;
394 }
395 
396 /**********************************************************************
397  * operator-=
398  *
399  * Subtract 2 ICOORDS.
400  **********************************************************************/
401 
402 inline ICOORD &operator-=( // subtract vectors
403  ICOORD &op1, // operands
404  const ICOORD &op2) {
405  op1.xcoord -= op2.xcoord;
406  op1.ycoord -= op2.ycoord;
407  return op1;
408 }
409 
410 /**********************************************************************
411  * operator%
412  *
413  * Scalar product of 2 ICOORDS.
414  **********************************************************************/
415 
416 inline int32_t operator%( // scalar product
417  const ICOORD &op1, // operands
418  const ICOORD &op2) {
419  return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord;
420 }
421 
422 /**********************************************************************
423  * operator*
424  *
425  * Cross product of 2 ICOORDS.
426  **********************************************************************/
427 
428 inline int32_t operator*( // cross product
429  const ICOORD &op1, // operands
430  const ICOORD &op2) {
431  return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord;
432 }
433 
434 /**********************************************************************
435  * operator*
436  *
437  * Scalar multiply of an ICOORD.
438  **********************************************************************/
439 
440 inline ICOORD operator*( // scalar multiply
441  const ICOORD &op1, // operands
442  TDimension scale) {
443  ICOORD result; // output
444 
445  result.xcoord = op1.xcoord * scale;
446  result.ycoord = op1.ycoord * scale;
447  return result;
448 }
449 
450 inline ICOORD operator*( // scalar multiply
451  TDimension scale,
452  const ICOORD &op1 // operands
453 ) {
454  ICOORD result; // output
455 
456  result.xcoord = op1.xcoord * scale;
457  result.ycoord = op1.ycoord * scale;
458  return result;
459 }
460 
461 /**********************************************************************
462  * operator*=
463  *
464  * Scalar multiply of an ICOORD.
465  **********************************************************************/
466 
467 inline ICOORD &operator*=( // scalar multiply
468  ICOORD &op1, // operands
469  TDimension scale) {
470  op1.xcoord *= scale;
471  op1.ycoord *= scale;
472  return op1;
473 }
474 
475 /**********************************************************************
476  * operator/
477  *
478  * Scalar divide of an ICOORD.
479  **********************************************************************/
480 
481 inline ICOORD operator/( // scalar divide
482  const ICOORD &op1, // operands
483  TDimension scale) {
484  ICOORD result; // output
485 
486  result.xcoord = op1.xcoord / scale;
487  result.ycoord = op1.ycoord / scale;
488  return result;
489 }
490 
491 /**********************************************************************
492  * operator/=
493  *
494  * Scalar divide of an ICOORD.
495  **********************************************************************/
496 
497 inline ICOORD &operator/=( // scalar divide
498  ICOORD &op1, // operands
499  TDimension scale) {
500  op1.xcoord /= scale;
501  op1.ycoord /= scale;
502  return op1;
503 }
504 
505 /**********************************************************************
506  * ICOORD::rotate
507  *
508  * Rotate an ICOORD by the given (normalized) (cos,sin) vector.
509  **********************************************************************/
510 
511 inline void ICOORD::rotate( // rotate by vector
512  const FCOORD &vec) {
513  auto tmp = static_cast<TDimension>(std::floor(xcoord * vec.x() - ycoord * vec.y() + 0.5f));
514  ycoord = static_cast<TDimension>(std::floor(ycoord * vec.x() + xcoord * vec.y() + 0.5f));
515  xcoord = tmp;
516 }
517 
518 /**********************************************************************
519  * operator!
520  *
521  * Rotate an FCOORD 90 degrees anticlockwise.
522  **********************************************************************/
523 
524 inline FCOORD operator!( // rotate 90 deg anti
525  const FCOORD &src // thing to rotate
526 ) {
527  FCOORD result; // output
528 
529  result.xcoord = -src.ycoord;
530  result.ycoord = src.xcoord;
531  return result;
532 }
533 
534 /**********************************************************************
535  * operator-
536  *
537  * Unary minus of an FCOORD.
538  **********************************************************************/
539 
540 inline FCOORD operator-( // unary minus
541  const FCOORD &src // thing to minus
542 ) {
543  FCOORD result; // output
544 
545  result.xcoord = -src.xcoord;
546  result.ycoord = -src.ycoord;
547  return result;
548 }
549 
550 /**********************************************************************
551  * operator+
552  *
553  * Add 2 FCOORDS.
554  **********************************************************************/
555 
556 inline FCOORD operator+( // sum vectors
557  const FCOORD &op1, // operands
558  const FCOORD &op2) {
559  FCOORD sum; // result
560 
561  sum.xcoord = op1.xcoord + op2.xcoord;
562  sum.ycoord = op1.ycoord + op2.ycoord;
563  return sum;
564 }
565 
566 /**********************************************************************
567  * operator+=
568  *
569  * Add 2 FCOORDS.
570  **********************************************************************/
571 
572 inline FCOORD &operator+=( // sum vectors
573  FCOORD &op1, // operands
574  const FCOORD &op2) {
575  op1.xcoord += op2.xcoord;
576  op1.ycoord += op2.ycoord;
577  return op1;
578 }
579 
580 /**********************************************************************
581  * operator-
582  *
583  * Subtract 2 FCOORDS.
584  **********************************************************************/
585 
586 inline FCOORD operator-( // subtract vectors
587  const FCOORD &op1, // operands
588  const FCOORD &op2) {
589  FCOORD sum; // result
590 
591  sum.xcoord = op1.xcoord - op2.xcoord;
592  sum.ycoord = op1.ycoord - op2.ycoord;
593  return sum;
594 }
595 
596 /**********************************************************************
597  * operator-=
598  *
599  * Subtract 2 FCOORDS.
600  **********************************************************************/
601 
602 inline FCOORD &operator-=( // subtract vectors
603  FCOORD &op1, // operands
604  const FCOORD &op2) {
605  op1.xcoord -= op2.xcoord;
606  op1.ycoord -= op2.ycoord;
607  return op1;
608 }
609 
610 /**********************************************************************
611  * operator%
612  *
613  * Scalar product of 2 FCOORDS.
614  **********************************************************************/
615 
616 inline float operator%( // scalar product
617  const FCOORD &op1, // operands
618  const FCOORD &op2) {
619  return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord;
620 }
621 
622 /**********************************************************************
623  * operator*
624  *
625  * Cross product of 2 FCOORDS.
626  **********************************************************************/
627 
628 inline float operator*( // cross product
629  const FCOORD &op1, // operands
630  const FCOORD &op2) {
631  return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord;
632 }
633 
634 /**********************************************************************
635  * operator*
636  *
637  * Scalar multiply of an FCOORD.
638  **********************************************************************/
639 
640 inline FCOORD operator*( // scalar multiply
641  const FCOORD &op1, // operands
642  float scale) {
643  FCOORD result; // output
644 
645  result.xcoord = op1.xcoord * scale;
646  result.ycoord = op1.ycoord * scale;
647  return result;
648 }
649 
650 inline FCOORD operator*( // scalar multiply
651  float scale,
652  const FCOORD &op1 // operands
653 ) {
654  FCOORD result; // output
655 
656  result.xcoord = op1.xcoord * scale;
657  result.ycoord = op1.ycoord * scale;
658  return result;
659 }
660 
661 /**********************************************************************
662  * operator*=
663  *
664  * Scalar multiply of an FCOORD.
665  **********************************************************************/
666 
667 inline FCOORD &operator*=( // scalar multiply
668  FCOORD &op1, // operands
669  float scale) {
670  op1.xcoord *= scale;
671  op1.ycoord *= scale;
672  return op1;
673 }
674 
675 /**********************************************************************
676  * operator/
677  *
678  * Scalar divide of an FCOORD.
679  **********************************************************************/
680 
681 inline FCOORD operator/( // scalar divide
682  const FCOORD &op1, // operands
683  float scale) {
684  FCOORD result; // output
685  ASSERT_HOST(scale != 0.0f);
686  result.xcoord = op1.xcoord / scale;
687  result.ycoord = op1.ycoord / scale;
688  return result;
689 }
690 
691 /**********************************************************************
692  * operator/=
693  *
694  * Scalar divide of an FCOORD.
695  **********************************************************************/
696 
697 inline FCOORD &operator/=( // scalar divide
698  FCOORD &op1, // operands
699  float scale) {
700  ASSERT_HOST(scale != 0.0f);
701  op1.xcoord /= scale;
702  op1.ycoord /= scale;
703  return op1;
704 }
705 
706 /**********************************************************************
707  * rotate
708  *
709  * Rotate an FCOORD by the given (normalized) (cos,sin) vector.
710  **********************************************************************/
711 
712 inline void FCOORD::rotate( // rotate by vector
713  const FCOORD vec) {
714  float tmp;
715 
716  tmp = xcoord * vec.x() - ycoord * vec.y();
717  ycoord = ycoord * vec.x() + xcoord * vec.y();
718  xcoord = tmp;
719 }
720 
721 inline void FCOORD::unrotate(const FCOORD &vec) {
722  rotate(FCOORD(vec.x(), -vec.y()));
723 }
724 
725 } // namespace tesseract
726 
727 #endif
#define ELISTIZEH(CLASSNAME)
Definition: elst.h:803
#define ASSERT_HOST(x)
Definition: errcode.h:59
int32_t operator%(const ICOORD &op1, const ICOORD &op2)
Definition: points.h:416
ICOORD operator+(const ICOORD &op1, const ICOORD &op2)
Definition: points.h:356
ICOORD & operator+=(ICOORD &op1, const ICOORD &op2)
Definition: points.h:372
ICOORD operator!(const ICOORD &src)
Definition: points.h:324
int32_t operator*(const ICOORD &op1, const ICOORD &op2)
Definition: points.h:428
ICOORD & operator/=(ICOORD &op1, TDimension scale)
Definition: points.h:497
ICOORD & operator*=(ICOORD &op1, TDimension scale)
Definition: points.h:467
int16_t TDimension
Definition: tesstypes.h:32
ICOORD & operator-=(ICOORD &op1, const ICOORD &op2)
Definition: points.h:402
ICOORD operator/(const ICOORD &op1, TDimension scale)
Definition: points.h:481
ICOORD operator-(const ICOORD &src)
Definition: points.h:340
integer coordinate
Definition: points.h:36
friend int32_t operator*(const ICOORD &, const ICOORD &)
cross product
Definition: points.h:428
float sqlength() const
find sq length
Definition: points.h:79
friend ICOORD & operator-=(ICOORD &, const ICOORD &)
subtract
Definition: points.h:402
friend ICOORD & operator/=(ICOORD &, TDimension)
divide
Definition: points.h:497
friend ICOORD operator/(const ICOORD &, TDimension)
divide
Definition: points.h:481
friend int32_t operator%(const ICOORD &, const ICOORD &)
scalar product
Definition: points.h:416
TDimension ycoord
y value
Definition: points.h:160
void rotate(const FCOORD &vec)
Definition: points.h:511
float pt_to_pt_sqdist(const ICOORD &pt) const
sq dist between pts
Definition: points.h:89
void set_with_shrink(int x, int y)
Set from the given x,y, shrinking the vector to fit if needed.
Definition: points.cpp:52
void set_x(TDimension xin)
rewrite function
Definition: points.h:67
friend ICOORD & operator+=(ICOORD &, const ICOORD &)
add
Definition: points.h:372
friend ICOORD operator!(const ICOORD &)
rotate 90 deg anti
Definition: points.h:324
TDimension y() const
access_function
Definition: points.h:62
bool DeSerialize(TFile *f)
Definition: points.cpp:43
ICOORD()
empty constructor
Definition: points.h:41
TDimension xcoord
x value
Definition: points.h:159
float length() const
find length
Definition: points.h:84
void set_y(TDimension yin)
rewrite function
Definition: points.h:71
bool operator==(const ICOORD &other) const
test equality
Definition: points.h:108
TDimension x() const
access function
Definition: points.h:58
bool operator!=(const ICOORD &other) const
test inequality
Definition: points.h:112
float angle() const
find angle
Definition: points.h:103
friend ICOORD operator-(const ICOORD &)
unary minus
Definition: points.h:340
ICOORD(TDimension xin, TDimension yin)
Definition: points.h:47
~ICOORD()=default
destructor
friend ICOORD operator+(const ICOORD &, const ICOORD &)
add
Definition: points.h:356
friend ICOORD & operator*=(ICOORD &, TDimension)
multiply
Definition: points.h:467
bool Serialize(TFile *f) const
Definition: points.cpp:47
float pt_to_pt_dist(const ICOORD &pt) const
Distance between pts.
Definition: points.h:98
void setup_render(ICOORD *major_step, ICOORD *minor_step, int *major, int *minor) const
Definition: points.cpp:99
static ICOORDELT * deep_copy(const ICOORDELT *src)
Definition: points.h:180
ICOORDELT(ICOORD icoord)
constructor from ICOORD
Definition: points.h:171
ICOORDELT()=default
empty constructor
ICOORDELT(TDimension xin, TDimension yin)
Definition: points.h:175
bool operator!=(const FCOORD &other)
test inequality
Definition: points.h:276
void set_y(float yin)
rewrite function
Definition: points.h:217
float length() const
find length
Definition: points.h:227
FCOORD(float xvalue, float yvalue)
Definition: points.h:196
float angle() const
find angle
Definition: points.h:246
float sqlength() const
find sq length
Definition: points.h:222
FCOORD()=default
empty constructor
FCOORD(ICOORD icoord)
Definition: points.h:200
float pt_to_pt_sqdist(const FCOORD &pt) const
sq dist between pts
Definition: points.h:232
float pt_to_pt_dist(const FCOORD &pt) const
Distance between pts.
Definition: points.h:241
void set_x(float xin)
rewrite function
Definition: points.h:213
void unrotate(const FCOORD &vec)
Definition: points.h:721
void rotate(const FCOORD vec)
Definition: points.h:712
float y() const
Definition: points.h:209
float x() const
Definition: points.h:206
bool operator==(const FCOORD &other)
test equality
Definition: points.h:272
#define TESS_API
Definition: export.h:34