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