tesseract v5.3.3.20231005
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
31namespace tesseract {
32
33class FCOORD;
34
36class ICOORD {
37 friend class FCOORD;
38
39public:
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 &);
138 friend ICOORD operator/(const 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
158protected:
161};
162
163class ICOORDELT : public ELIST_LINK,
164 public ICOORD
165// embedded coord list
166{
167public:
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
187ELISTIZEH(ICOORDELT)
188
190public:
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) const {
273 return xcoord == other.xcoord && ycoord == other.ycoord;
274 }
276 bool operator!=(const FCOORD &other) const {
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
313private:
314 float xcoord; // 2 floating coords
315 float ycoord;
316};
317
318/**********************************************************************
319 * operator!
320 *
321 * Rotate an ICOORD 90 degrees anticlockwise.
322 **********************************************************************/
323
324inline 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
340inline 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
356inline 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
372inline 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
386inline 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
402inline 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
416inline 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
428inline 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
440inline 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
450inline 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
467inline 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
481inline 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
497inline 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
511inline 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
524inline 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
540inline 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
556inline 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
572inline 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
586inline 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
602inline 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
616inline 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
628inline 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
640inline 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
650inline 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
667inline 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
681inline 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
697inline 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
712inline 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
721inline 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:54
ICOORD & operator+=(ICOORD &op1, const ICOORD &op2)
Definition: points.h:372
ICOORD & operator-=(ICOORD &op1, const ICOORD &op2)
Definition: points.h:402
ICOORD & operator*=(ICOORD &op1, TDimension scale)
Definition: points.h:467
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!(const ICOORD &src)
Definition: points.h:324
int32_t operator*(const ICOORD &op1, const ICOORD &op2)
Definition: points.h:428
int16_t TDimension
Definition: tesstypes.h:32
ICOORD & operator/=(ICOORD &op1, TDimension scale)
Definition: points.h:497
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/(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
friend ICOORD & operator-=(ICOORD &, const ICOORD &)
subtract
Definition: points.h:402
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!(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
friend ICOORD & operator+=(ICOORD &, const ICOORD &)
add
Definition: points.h:372
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/=(ICOORD &, TDimension)
divide
Definition: points.h:497
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
ICOORDELT(ICOORD icoord)
constructor from ICOORD
Definition: points.h:171
ICOORDELT()=default
empty constructor
static ICOORDELT * deep_copy(const ICOORDELT *src)
Definition: points.h:180
ICOORDELT(TDimension xin, TDimension yin)
Definition: points.h:175
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
bool operator==(const FCOORD &other) const
test equality
Definition: points.h:272
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) const
test inequality
Definition: points.h:276
#define TESS_API
Definition: export.h:32