tesseract 4.1.1
Loading...
Searching...
No Matches
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 <cmath> // for sqrt, atan2
23#include <cstdio>
24#include "elst.h"
25#include "errcode.h" // for ASSERT_HOST
26#include "platform.h" // for DLLSYM
27
28class FCOORD;
29
31class ICOORD
32{
33 friend class FCOORD;
34
35 public:
38 xcoord = ycoord = 0; //default zero
39 }
43 ICOORD(int16_t xin,
44 int16_t yin) {
45 xcoord = xin;
46 ycoord = yin;
47 }
49 ~ICOORD () = default;
50
52 int16_t x() const {
53 return xcoord;
54 }
56 int16_t y() const {
57 return ycoord;
58 }
59
61 void set_x(int16_t xin) {
62 xcoord = xin; //write new value
63 }
65 void set_y(int16_t yin) { //value to set
66 ycoord = yin;
67 }
68
70 void set_with_shrink(int x, int y);
71
73 float sqlength() const {
74 return xcoord * xcoord + ycoord * ycoord;
75 }
76
78 float length() const {
79 return std::sqrt(sqlength());
80 }
81
83 float pt_to_pt_sqdist(const ICOORD &pt) const {
84 ICOORD gap;
85
86 gap.xcoord = xcoord - pt.xcoord;
87 gap.ycoord = ycoord - pt.ycoord;
88 return gap.sqlength ();
89 }
90
92 float pt_to_pt_dist(const ICOORD &pt) const {
93 return std::sqrt(pt_to_pt_sqdist(pt));
94 }
95
97 float angle() const {
98 return std::atan2(ycoord, xcoord);
99 }
100
102 bool operator== (const ICOORD & other) const {
103 return xcoord == other.xcoord && ycoord == other.ycoord;
104 }
106 bool operator!= (const ICOORD & other) const {
107 return xcoord != other.xcoord || ycoord != other.ycoord;
108 }
110 friend ICOORD operator! (const ICOORD &);
112 friend ICOORD operator- (const ICOORD &);
114 friend ICOORD operator+ (const ICOORD &, const ICOORD &);
116 friend ICOORD & operator+= (ICOORD &, const ICOORD &);
118 friend ICOORD operator- (const ICOORD &, const ICOORD &);
120 friend ICOORD & operator-= (ICOORD &, const ICOORD &);
122 friend int32_t operator% (const ICOORD &, const ICOORD &);
124 friend int32_t operator *(const ICOORD &,
125 const ICOORD &);
127 friend ICOORD operator *(const ICOORD &,
128 int16_t);
130 friend ICOORD operator *(int16_t,
131 const ICOORD &);
133 friend ICOORD & operator*= (ICOORD &, int16_t);
135 friend ICOORD operator/ (const ICOORD &, int16_t);
137 friend ICOORD & operator/= (ICOORD &, int16_t);
140 void rotate(const FCOORD& vec);
141
147 void setup_render(ICOORD* major_step, ICOORD* minor_step,
148 int* major, int* minor) const;
149
150 // Writes to the given file. Returns false in case of error.
151 bool Serialize(FILE* fp) const;
152 // Reads from the given file. Returns false in case of error.
153 // If swap is true, assumes a big/little-endian swap is needed.
154 bool DeSerialize(bool swap, FILE* fp);
155
156 protected:
157 int16_t xcoord;
158 int16_t ycoord;
159};
160
161class DLLSYM ICOORDELT:public ELIST_LINK, public ICOORD
162 //embedded coord list
163{
164 public:
166 ICOORDELT() = default;
168 ICOORDELT (ICOORD icoord):ICOORD (icoord) {
169 }
173 ICOORDELT(int16_t xin,
174 int16_t yin) {
175 xcoord = xin;
176 ycoord = yin;
177 }
178
179 static ICOORDELT* deep_copy(const ICOORDELT* src) {
180 auto* elt = new ICOORDELT;
181 *elt = *src;
182 return elt;
183 }
184
185};
186
189{
190 public:
192 FCOORD() = default;
196 FCOORD(float xvalue,
197 float yvalue) {
198 xcoord = xvalue; //set coords
199 ycoord = yvalue;
200 }
201 FCOORD( //make from ICOORD
202 ICOORD icoord) { //coords to set
203 xcoord = icoord.xcoord;
204 ycoord = icoord.ycoord;
205 }
206
207 float x() const { //get coords
208 return xcoord;
209 }
210 float y() const {
211 return ycoord;
212 }
214 void set_x(float xin) {
215 xcoord = xin; //write new value
216 }
218 void set_y(float yin) { //value to set
219 ycoord = yin;
220 }
221
223 float sqlength() const {
224 return xcoord * xcoord + ycoord * ycoord;
225 }
226
228 float length() const {
229 return std::sqrt(sqlength());
230 }
231
233 float pt_to_pt_sqdist(const FCOORD &pt) const {
234 FCOORD gap;
235
236 gap.xcoord = xcoord - pt.xcoord;
237 gap.ycoord = ycoord - pt.ycoord;
238 return gap.sqlength ();
239 }
240
242 float pt_to_pt_dist(const FCOORD &pt) const {
243 return std::sqrt(pt_to_pt_sqdist(pt));
244 }
245
247 float angle() const {
248 return std::atan2(ycoord, xcoord);
249 }
250 // Returns the standard feature direction corresponding to this.
251 // See binary_angle_plus_pi below for a description of the direction.
252 uint8_t to_direction() const;
253 // Sets this with a unit vector in the given standard feature direction.
254 void from_direction(uint8_t direction);
255
256 // Converts an angle in radians (from ICOORD::angle or FCOORD::angle) to a
257 // standard feature direction as an unsigned angle in 256ths of a circle
258 // measured anticlockwise from (-1, 0).
259 static uint8_t binary_angle_plus_pi(double angle);
260 // Inverse of binary_angle_plus_pi returns an angle in radians for the
261 // given standard feature direction.
262 static double angle_from_direction(uint8_t direction);
263 // Returns the point on the given line nearest to this, ie the point such
264 // that the vector point->this is perpendicular to the line.
265 // The line is defined as a line_point and a dir_vector for its direction.
266 // dir_vector need not be a unit vector.
267 FCOORD nearest_pt_on_line(const FCOORD& line_point,
268 const FCOORD& dir_vector) const;
269
271 bool normalise();
272
274 bool operator== (const FCOORD & other) {
275 return xcoord == other.xcoord && ycoord == other.ycoord;
276 }
278 bool operator!= (const FCOORD & other) {
279 return xcoord != other.xcoord || ycoord != other.ycoord;
280 }
282 friend FCOORD operator! (const FCOORD &);
284 friend FCOORD operator- (const FCOORD &);
286 friend FCOORD operator+ (const FCOORD &, const FCOORD &);
288 friend FCOORD & operator+= (FCOORD &, const FCOORD &);
290 friend FCOORD operator- (const FCOORD &, const FCOORD &);
292 friend FCOORD & operator-= (FCOORD &, const FCOORD &);
294 friend float operator% (const FCOORD &, const FCOORD &);
296 friend float operator *(const FCOORD &, const FCOORD &);
298 friend FCOORD operator *(const FCOORD &, float);
300 friend FCOORD operator *(float, const FCOORD &);
301
303 friend FCOORD & operator*= (FCOORD &, float);
305 friend FCOORD operator/ (const FCOORD &, float);
308 void rotate(const FCOORD vec);
309 // unrotate - undo a rotate(vec)
310 // @param vec by vector
311 void unrotate(const FCOORD &vec);
313 friend FCOORD & operator/= (FCOORD &, float);
314
315 private:
316 float xcoord; //2 floating coords
317 float ycoord;
318};
319
320/**********************************************************************
321 * operator!
322 *
323 * Rotate an ICOORD 90 degrees anticlockwise.
324 **********************************************************************/
325
326inline ICOORD
327operator! ( //rotate 90 deg anti
328const ICOORD & src //thing to rotate
329) {
330 ICOORD result; //output
331
332 result.xcoord = -src.ycoord;
333 result.ycoord = src.xcoord;
334 return result;
335}
336
337
338/**********************************************************************
339 * operator-
340 *
341 * Unary minus of an ICOORD.
342 **********************************************************************/
343
344inline ICOORD
345operator- ( //unary minus
346const ICOORD & src //thing to minus
347) {
348 ICOORD result; //output
349
350 result.xcoord = -src.xcoord;
351 result.ycoord = -src.ycoord;
352 return result;
353}
354
355
356/**********************************************************************
357 * operator+
358 *
359 * Add 2 ICOORDS.
360 **********************************************************************/
361
362inline ICOORD
363operator+ ( //sum vectors
364const ICOORD & op1, //operands
365const ICOORD & op2) {
366 ICOORD sum; //result
367
368 sum.xcoord = op1.xcoord + op2.xcoord;
369 sum.ycoord = op1.ycoord + op2.ycoord;
370 return sum;
371}
372
373
374/**********************************************************************
375 * operator+=
376 *
377 * Add 2 ICOORDS.
378 **********************************************************************/
379
380inline ICOORD &
381operator+= ( //sum vectors
382ICOORD & op1, //operands
383const ICOORD & op2) {
384 op1.xcoord += op2.xcoord;
385 op1.ycoord += op2.ycoord;
386 return op1;
387}
388
389
390/**********************************************************************
391 * operator-
392 *
393 * Subtract 2 ICOORDS.
394 **********************************************************************/
395
396inline ICOORD
397operator- ( //subtract vectors
398const ICOORD & op1, //operands
399const ICOORD & op2) {
400 ICOORD sum; //result
401
402 sum.xcoord = op1.xcoord - op2.xcoord;
403 sum.ycoord = op1.ycoord - op2.ycoord;
404 return sum;
405}
406
407
408/**********************************************************************
409 * operator-=
410 *
411 * Subtract 2 ICOORDS.
412 **********************************************************************/
413
414inline ICOORD &
415operator-= ( //subtract vectors
416ICOORD & op1, //operands
417const ICOORD & op2) {
418 op1.xcoord -= op2.xcoord;
419 op1.ycoord -= op2.ycoord;
420 return op1;
421}
422
423
424/**********************************************************************
425 * operator%
426 *
427 * Scalar product of 2 ICOORDS.
428 **********************************************************************/
429
430inline int32_t
431operator% ( //scalar product
432const ICOORD & op1, //operands
433const ICOORD & op2) {
434 return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord;
435}
436
437
438/**********************************************************************
439 * operator*
440 *
441 * Cross product of 2 ICOORDS.
442 **********************************************************************/
443
444inline int32_t operator *( //cross product
445 const ICOORD &op1, //operands
446 const ICOORD &op2) {
447 return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord;
448}
449
450
451/**********************************************************************
452 * operator*
453 *
454 * Scalar multiply of an ICOORD.
455 **********************************************************************/
456
457inline ICOORD operator *( //scalar multiply
458 const ICOORD &op1, //operands
459 int16_t scale) {
460 ICOORD result; //output
461
462 result.xcoord = op1.xcoord * scale;
463 result.ycoord = op1.ycoord * scale;
464 return result;
465}
466
467
468inline ICOORD operator *( //scalar multiply
469 int16_t scale,
470 const ICOORD &op1 //operands
471 ) {
472 ICOORD result; //output
473
474 result.xcoord = op1.xcoord * scale;
475 result.ycoord = op1.ycoord * scale;
476 return result;
477}
478
479
480/**********************************************************************
481 * operator*=
482 *
483 * Scalar multiply of an ICOORD.
484 **********************************************************************/
485
486inline ICOORD &
487operator*= ( //scalar multiply
488ICOORD & op1, //operands
489int16_t scale) {
490 op1.xcoord *= scale;
491 op1.ycoord *= scale;
492 return op1;
493}
494
495
496/**********************************************************************
497 * operator/
498 *
499 * Scalar divide of an ICOORD.
500 **********************************************************************/
501
502inline ICOORD
503operator/ ( //scalar divide
504const ICOORD & op1, //operands
505int16_t scale) {
506 ICOORD result; //output
507
508 result.xcoord = op1.xcoord / scale;
509 result.ycoord = op1.ycoord / scale;
510 return result;
511}
512
513
514/**********************************************************************
515 * operator/=
516 *
517 * Scalar divide of an ICOORD.
518 **********************************************************************/
519
520inline ICOORD &
521operator/= ( //scalar divide
522ICOORD & op1, //operands
523int16_t scale) {
524 op1.xcoord /= scale;
525 op1.ycoord /= scale;
526 return op1;
527}
528
529
530/**********************************************************************
531 * ICOORD::rotate
532 *
533 * Rotate an ICOORD by the given (normalized) (cos,sin) vector.
534 **********************************************************************/
535
536inline void ICOORD::rotate( //rotate by vector
537 const FCOORD& vec) {
538 auto tmp = static_cast<int16_t>(std::floor(xcoord * vec.x() -
539 ycoord * vec.y() + 0.5f));
540 ycoord = static_cast<int16_t>(std::floor(ycoord * vec.x() +
541 xcoord * vec.y() + 0.5f));
542 xcoord = tmp;
543}
544
545
546/**********************************************************************
547 * operator!
548 *
549 * Rotate an FCOORD 90 degrees anticlockwise.
550 **********************************************************************/
551
552inline FCOORD
553operator! ( //rotate 90 deg anti
554const FCOORD & src //thing to rotate
555) {
556 FCOORD result; //output
557
558 result.xcoord = -src.ycoord;
559 result.ycoord = src.xcoord;
560 return result;
561}
562
563
564/**********************************************************************
565 * operator-
566 *
567 * Unary minus of an FCOORD.
568 **********************************************************************/
569
570inline FCOORD
571operator- ( //unary minus
572const FCOORD & src //thing to minus
573) {
574 FCOORD result; //output
575
576 result.xcoord = -src.xcoord;
577 result.ycoord = -src.ycoord;
578 return result;
579}
580
581
582/**********************************************************************
583 * operator+
584 *
585 * Add 2 FCOORDS.
586 **********************************************************************/
587
588inline FCOORD
589operator+ ( //sum vectors
590const FCOORD & op1, //operands
591const FCOORD & op2) {
592 FCOORD sum; //result
593
594 sum.xcoord = op1.xcoord + op2.xcoord;
595 sum.ycoord = op1.ycoord + op2.ycoord;
596 return sum;
597}
598
599
600/**********************************************************************
601 * operator+=
602 *
603 * Add 2 FCOORDS.
604 **********************************************************************/
605
606inline FCOORD &
607operator+= ( //sum vectors
608FCOORD & op1, //operands
609const FCOORD & op2) {
610 op1.xcoord += op2.xcoord;
611 op1.ycoord += op2.ycoord;
612 return op1;
613}
614
615
616/**********************************************************************
617 * operator-
618 *
619 * Subtract 2 FCOORDS.
620 **********************************************************************/
621
622inline FCOORD
623operator- ( //subtract vectors
624const FCOORD & op1, //operands
625const FCOORD & op2) {
626 FCOORD sum; //result
627
628 sum.xcoord = op1.xcoord - op2.xcoord;
629 sum.ycoord = op1.ycoord - op2.ycoord;
630 return sum;
631}
632
633
634/**********************************************************************
635 * operator-=
636 *
637 * Subtract 2 FCOORDS.
638 **********************************************************************/
639
640inline FCOORD &
641operator-= ( //subtract vectors
642FCOORD & op1, //operands
643const FCOORD & op2) {
644 op1.xcoord -= op2.xcoord;
645 op1.ycoord -= op2.ycoord;
646 return op1;
647}
648
649
650/**********************************************************************
651 * operator%
652 *
653 * Scalar product of 2 FCOORDS.
654 **********************************************************************/
655
656inline float
657operator% ( //scalar product
658const FCOORD & op1, //operands
659const FCOORD & op2) {
660 return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord;
661}
662
663
664/**********************************************************************
665 * operator*
666 *
667 * Cross product of 2 FCOORDS.
668 **********************************************************************/
669
670inline float operator *( //cross product
671 const FCOORD &op1, //operands
672 const FCOORD &op2) {
673 return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord;
674}
675
676
677/**********************************************************************
678 * operator*
679 *
680 * Scalar multiply of an FCOORD.
681 **********************************************************************/
682
683inline FCOORD operator *( //scalar multiply
684 const FCOORD &op1, //operands
685 float scale) {
686 FCOORD result; //output
687
688 result.xcoord = op1.xcoord * scale;
689 result.ycoord = op1.ycoord * scale;
690 return result;
691}
692
693
694inline FCOORD operator *( //scalar multiply
695 float scale,
696 const FCOORD &op1 //operands
697 ) {
698 FCOORD result; //output
699
700 result.xcoord = op1.xcoord * scale;
701 result.ycoord = op1.ycoord * scale;
702 return result;
703}
704
705
706/**********************************************************************
707 * operator*=
708 *
709 * Scalar multiply of an FCOORD.
710 **********************************************************************/
711
712inline FCOORD &
713operator*= ( //scalar multiply
714FCOORD & op1, //operands
715float scale) {
716 op1.xcoord *= scale;
717 op1.ycoord *= scale;
718 return op1;
719}
720
721
722/**********************************************************************
723 * operator/
724 *
725 * Scalar divide of an FCOORD.
726 **********************************************************************/
727
728inline FCOORD
729operator/ ( //scalar divide
730const FCOORD & op1, //operands
731float scale) {
732 FCOORD result; //output
733 ASSERT_HOST(scale != 0.0f);
734 result.xcoord = op1.xcoord / scale;
735 result.ycoord = op1.ycoord / scale;
736 return result;
737}
738
739
740/**********************************************************************
741 * operator/=
742 *
743 * Scalar divide of an FCOORD.
744 **********************************************************************/
745
746inline FCOORD &
747operator/= ( //scalar divide
748FCOORD & op1, //operands
749float scale) {
750 ASSERT_HOST(scale != 0.0f);
751 op1.xcoord /= scale;
752 op1.ycoord /= scale;
753 return op1;
754}
755
756
757/**********************************************************************
758 * rotate
759 *
760 * Rotate an FCOORD by the given (normalized) (cos,sin) vector.
761 **********************************************************************/
762
763inline void FCOORD::rotate( //rotate by vector
764 const FCOORD vec) {
765 float tmp;
766
767 tmp = xcoord * vec.x () - ycoord * vec.y ();
768 ycoord = ycoord * vec.x () + xcoord * vec.y ();
769 xcoord = tmp;
770}
771
772inline void FCOORD::unrotate(const FCOORD& vec) {
773 rotate(FCOORD(vec.x(), -vec.y()));
774}
775
776#endif
ICOORD & operator+=(ICOORD &op1, const ICOORD &op2)
Definition: points.h:381
int32_t operator*(const ICOORD &op1, const ICOORD &op2)
Definition: points.h:444
ICOORD & operator*=(ICOORD &op1, int16_t scale)
Definition: points.h:487
ICOORD & operator-=(ICOORD &op1, const ICOORD &op2)
Definition: points.h:415
ICOORD & operator/=(ICOORD &op1, int16_t scale)
Definition: points.h:521
ICOORD operator/(const ICOORD &op1, int16_t scale)
Definition: points.h:503
int32_t operator%(const ICOORD &op1, const ICOORD &op2)
Definition: points.h:431
ICOORD operator-(const ICOORD &src)
Definition: points.h:345
ICOORD operator!(const ICOORD &src)
Definition: points.h:327
ICOORD operator+(const ICOORD &op1, const ICOORD &op2)
Definition: points.h:363
#define ELISTIZEH(CLASSNAME)
Definition: elst.h:918
#define ASSERT_HOST(x)
Definition: errcode.h:88
#define DLLSYM
Definition: platform.h:21
integer coordinate
Definition: points.h:32
void set_x(int16_t xin)
rewrite function
Definition: points.h:61
friend int32_t operator*(const ICOORD &, const ICOORD &)
cross product
Definition: points.h:444
void set_with_shrink(int x, int y)
Set from the given x,y, shrinking the vector to fit if needed.
Definition: points.cpp:41
int16_t y() const
access_function
Definition: points.h:56
int16_t ycoord
y value
Definition: points.h:158
friend int32_t operator%(const ICOORD &, const ICOORD &)
scalar product
Definition: points.h:431
ICOORD(int16_t xin, int16_t yin)
Definition: points.h:43
bool operator==(const ICOORD &other) const
test equality
Definition: points.h:102
friend ICOORD & operator-=(ICOORD &, const ICOORD &)
subtract
Definition: points.h:415
void setup_render(ICOORD *major_step, ICOORD *minor_step, int *major, int *minor) const
Definition: points.cpp:83
bool Serialize(FILE *fp) const
Definition: points.cpp:61
void set_y(int16_t yin)
rewrite function
Definition: points.h:65
float length() const
find length
Definition: points.h:78
float sqlength() const
find sq length
Definition: points.h:73
~ICOORD()=default
destructor
friend ICOORD operator!(const ICOORD &)
rotate 90 deg anti
Definition: points.h:327
friend ICOORD & operator+=(ICOORD &, const ICOORD &)
add
Definition: points.h:381
float pt_to_pt_sqdist(const ICOORD &pt) const
sq dist between pts
Definition: points.h:83
float angle() const
find angle
Definition: points.h:97
friend ICOORD & operator/=(ICOORD &, int16_t)
divide
Definition: points.h:521
float pt_to_pt_dist(const ICOORD &pt) const
Distance between pts.
Definition: points.h:92
int16_t xcoord
x value
Definition: points.h:157
int16_t x() const
access function
Definition: points.h:52
void rotate(const FCOORD &vec)
Definition: points.h:536
friend ICOORD operator-(const ICOORD &)
unary minus
Definition: points.h:345
friend ICOORD operator+(const ICOORD &, const ICOORD &)
add
Definition: points.h:363
friend ICOORD & operator*=(ICOORD &, int16_t)
multiply
Definition: points.h:487
bool operator!=(const ICOORD &other) const
test inequality
Definition: points.h:106
bool DeSerialize(bool swap, FILE *fp)
Definition: points.cpp:67
ICOORD()
empty constructor
Definition: points.h:37
friend ICOORD operator/(const ICOORD &, int16_t)
divide
Definition: points.h:503
ICOORDELT()=default
empty constructor
ICOORDELT(ICOORD icoord)
constructor from ICOORD
Definition: points.h:168
static ICOORDELT * deep_copy(const ICOORDELT *src)
Definition: points.h:179
ICOORDELT(int16_t xin, int16_t yin)
Definition: points.h:173
Definition: points.h:189
FCOORD()=default
empty constructor
float length() const
find length
Definition: points.h:228
float pt_to_pt_sqdist(const FCOORD &pt) const
sq dist between pts
Definition: points.h:233
FCOORD(ICOORD icoord)
Definition: points.h:201
void rotate(const FCOORD vec)
Definition: points.h:763
void unrotate(const FCOORD &vec)
Definition: points.h:772
float angle() const
find angle
Definition: points.h:247
float y() const
Definition: points.h:210
FCOORD(float xvalue, float yvalue)
Definition: points.h:196
float sqlength() const
find sq length
Definition: points.h:223
void set_y(float yin)
rewrite function
Definition: points.h:218
void set_x(float xin)
rewrite function
Definition: points.h:214
float x() const
Definition: points.h:207
float pt_to_pt_dist(const FCOORD &pt) const
Distance between pts.
Definition: points.h:242