Coverage Report

Created: 2025-06-13 07:15

/src/tesseract/src/ccstruct/points.h
Line
Count
Source (jump to first uncovered line)
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
35
/// integer coordinate
36
class ICOORD {
37
  friend class FCOORD;
38
39
public:
40
  /// empty constructor
41
464M
  ICOORD() {
42
464M
    xcoord = ycoord = 0; // default zero
43
464M
  }
44
  /// constructor
45
  ///@param xin x value
46
  ///@param yin y value
47
3.94G
  ICOORD(TDimension xin, TDimension yin) {
48
3.94G
    xcoord = xin;
49
3.94G
    ycoord = yin;
50
3.94G
  }
51
  /// destructor
52
  ~ICOORD() = default;
53
54
  bool DeSerialize(TFile *f);
55
  bool Serialize(TFile *f) const;
56
57
  /// access function
58
17.9G
  TDimension x() const {
59
17.9G
    return xcoord;
60
17.9G
  }
61
  /// access_function
62
22.3G
  TDimension y() const {
63
22.3G
    return ycoord;
64
22.3G
  }
65
66
  /// rewrite function
67
1.50G
  void set_x(TDimension xin) {
68
1.50G
    xcoord = xin; // write new value
69
1.50G
  }
70
  /// rewrite function
71
1.58G
  void set_y(TDimension yin) { // value to set
72
1.58G
    ycoord = yin;
73
1.58G
  }
74
75
  /// Set from the given x,y, shrinking the vector to fit if needed.
76
  void set_with_shrink(int x, int y);
77
78
  /// find sq length
79
1.88M
  float sqlength() const {
80
1.88M
    return static_cast<float>(xcoord * xcoord + ycoord * ycoord);
81
1.88M
  }
82
83
  /// find length
84
0
  float length() const {
85
0
    return std::sqrt(sqlength());
86
0
  }
87
88
  /// sq dist between pts
89
0
  float pt_to_pt_sqdist(const ICOORD &pt) const {
90
0
    ICOORD gap;
91
0
92
0
    gap.xcoord = xcoord - pt.xcoord;
93
0
    gap.ycoord = ycoord - pt.ycoord;
94
0
    return gap.sqlength();
95
0
  }
96
97
  /// Distance between pts
98
0
  float pt_to_pt_dist(const ICOORD &pt) const {
99
0
    return std::sqrt(pt_to_pt_sqdist(pt));
100
0
  }
101
102
  /// find angle
103
0
  float angle() const {
104
0
    return std::atan2(static_cast<float>(ycoord), static_cast<float>(xcoord));
105
0
  }
106
107
  /// test equality
108
0
  bool operator==(const ICOORD &other) const {
109
0
    return xcoord == other.xcoord && ycoord == other.ycoord;
110
0
  }
111
  /// test inequality
112
2.04M
  bool operator!=(const ICOORD &other) const {
113
2.04M
    return xcoord != other.xcoord || ycoord != other.ycoord;
114
2.04M
  }
115
  /// rotate 90 deg anti
116
  friend ICOORD operator!(const ICOORD &);
117
  /// unary minus
118
  friend ICOORD operator-(const ICOORD &);
119
  /// add
120
  friend ICOORD operator+(const ICOORD &, const ICOORD &);
121
  /// add
122
  friend ICOORD &operator+=(ICOORD &, const ICOORD &);
123
  /// subtract
124
  friend ICOORD operator-(const ICOORD &, const ICOORD &);
125
  /// subtract
126
  friend ICOORD &operator-=(ICOORD &, const ICOORD &);
127
  /// scalar product
128
  friend int32_t operator%(const ICOORD &, const ICOORD &);
129
  /// cross product
130
  friend int32_t operator*(const ICOORD &, const ICOORD &);
131
  /// multiply
132
  friend ICOORD operator*(const ICOORD &, TDimension);
133
  /// multiply
134
  friend ICOORD operator*(TDimension, const ICOORD &);
135
  /// multiply
136
  friend ICOORD &operator*=(ICOORD &, TDimension);
137
  /// divide
138
  friend ICOORD operator/(const ICOORD &, TDimension);
139
  /// divide
140
  friend ICOORD &operator/=(ICOORD &, TDimension);
141
  /// rotate
142
  ///@param vec by vector
143
  void rotate(const FCOORD &vec);
144
145
  /// Setup for iterating over the pixels in a vector by the well-known
146
  /// Bresenham rendering algorithm.
147
  /// Starting with major/2 in the accumulator, on each step move by
148
  /// major_step, and then add minor to the accumulator. When
149
  /// accumulator >= major subtract major and also move by minor_step.
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:
159
  TDimension xcoord; ///< x value
160
  TDimension ycoord; ///< y value
161
};
162
163
class ICOORDELT : public ELIST<ICOORDELT>::LINK,
164
                  public ICOORD
165
// embedded coord list
166
{
167
public:
168
  /// empty constructor
169
0
  ICOORDELT() = default;
170
  /// constructor from ICOORD
171
66.9k
  ICOORDELT(ICOORD icoord) : ICOORD(icoord) {}
172
  /// constructor
173
  ///@param xin x value
174
  ///@param yin y value
175
1.55M
  ICOORDELT(TDimension xin, TDimension yin) {
176
1.55M
    xcoord = xin;
177
1.55M
    ycoord = yin;
178
1.55M
  }
179
180
0
  static ICOORDELT *deep_copy(const ICOORDELT *src) {
181
0
    auto *elt = new ICOORDELT;
182
0
    *elt = *src;
183
0
    return elt;
184
0
  }
185
};
186
187
ELISTIZEH(ICOORDELT)
188
189
class TESS_API FCOORD {
190
public:
191
  /// empty constructor
192
  FCOORD() = default;
193
  /// constructor
194
  ///@param xvalue x value
195
  ///@param yvalue y value
196
447M
  FCOORD(float xvalue, float yvalue) {
197
447M
    xcoord = xvalue; // set coords
198
447M
    ycoord = yvalue;
199
447M
  }
200
  FCOORD(              // make from ICOORD
201
76.1M
      ICOORD icoord) { // coords to set
202
76.1M
    xcoord = icoord.xcoord;
203
76.1M
    ycoord = icoord.ycoord;
204
76.1M
  }
205
206
4.42G
  float x() const { // get coords
207
4.42G
    return xcoord;
208
4.42G
  }
209
4.38G
  float y() const {
210
4.38G
    return ycoord;
211
4.38G
  }
212
  /// rewrite function
213
267M
  void set_x(float xin) {
214
267M
    xcoord = xin; // write new value
215
267M
  }
216
  /// rewrite function
217
267M
  void set_y(float yin) { // value to set
218
267M
    ycoord = yin;
219
267M
  }
220
221
  /// find sq length
222
90.4M
  float sqlength() const {
223
90.4M
    return xcoord * xcoord + ycoord * ycoord;
224
90.4M
  }
225
226
  /// find length
227
81.0M
  float length() const {
228
81.0M
    return std::sqrt(sqlength());
229
81.0M
  }
230
231
  /// sq dist between pts
232
8.33M
  float pt_to_pt_sqdist(const FCOORD &pt) const {
233
8.33M
    FCOORD gap;
234
235
8.33M
    gap.xcoord = xcoord - pt.xcoord;
236
8.33M
    gap.ycoord = ycoord - pt.ycoord;
237
8.33M
    return gap.sqlength();
238
8.33M
  }
239
240
  /// Distance between pts
241
8.33M
  float pt_to_pt_dist(const FCOORD &pt) const {
242
8.33M
    return std::sqrt(pt_to_pt_sqdist(pt));
243
8.33M
  }
244
245
  /// find angle
246
126M
  float angle() const {
247
126M
    return std::atan2(ycoord, xcoord);
248
126M
  }
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
268
  /// Convert to unit vec
269
  bool normalise();
270
271
  /// test equality
272
0
  bool operator==(const FCOORD &other) const {
273
0
    return xcoord == other.xcoord && ycoord == other.ycoord;
274
0
  }
275
  /// test inequality
276
0
  bool operator!=(const FCOORD &other) const {
277
0
    return xcoord != other.xcoord || ycoord != other.ycoord;
278
0
  }
279
  /// rotate 90 deg anti
280
  friend FCOORD operator!(const FCOORD &);
281
  /// unary minus
282
  friend FCOORD operator-(const FCOORD &);
283
  /// add
284
  friend FCOORD operator+(const FCOORD &, const FCOORD &);
285
  /// add
286
  friend FCOORD &operator+=(FCOORD &, const FCOORD &);
287
  /// subtract
288
  friend FCOORD operator-(const FCOORD &, const FCOORD &);
289
  /// subtract
290
  friend FCOORD &operator-=(FCOORD &, const FCOORD &);
291
  /// scalar product
292
  friend float operator%(const FCOORD &, const FCOORD &);
293
  /// cross product
294
  friend float operator*(const FCOORD &, const FCOORD &);
295
  /// multiply
296
  friend FCOORD operator*(const FCOORD &, float);
297
  /// multiply
298
  friend FCOORD operator*(float, const FCOORD &);
299
300
  /// multiply
301
  friend FCOORD &operator*=(FCOORD &, float);
302
  /// divide
303
  friend FCOORD operator/(const FCOORD &, float);
304
  /// rotate
305
  ///@param vec by vector
306
  void rotate(const FCOORD vec);
307
  // unrotate - undo a rotate(vec)
308
  // @param vec by vector
309
  void unrotate(const FCOORD &vec);
310
  /// divide
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
0
) {
327
0
  ICOORD result; // output
328
0
329
0
  result.xcoord = -src.ycoord;
330
0
  result.ycoord = src.xcoord;
331
0
  return result;
332
0
}
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
0
) {
343
0
  ICOORD result; // output
344
345
0
  result.xcoord = -src.xcoord;
346
0
  result.ycoord = -src.ycoord;
347
0
  return result;
348
0
}
349
350
/**********************************************************************
351
 * operator+
352
 *
353
 * Add 2 ICOORDS.
354
 **********************************************************************/
355
356
inline ICOORD operator+( // sum vectors
357
    const ICOORD &op1,   // operands
358
0
    const ICOORD &op2) {
359
0
  ICOORD sum; // result
360
361
0
  sum.xcoord = op1.xcoord + op2.xcoord;
362
0
  sum.ycoord = op1.ycoord + op2.ycoord;
363
0
  return sum;
364
0
}
365
366
/**********************************************************************
367
 * operator+=
368
 *
369
 * Add 2 ICOORDS.
370
 **********************************************************************/
371
372
inline ICOORD &operator+=( // sum vectors
373
    ICOORD &op1,           // operands
374
2.92G
    const ICOORD &op2) {
375
2.92G
  op1.xcoord += op2.xcoord;
376
2.92G
  op1.ycoord += op2.ycoord;
377
2.92G
  return op1;
378
2.92G
}
379
380
/**********************************************************************
381
 * operator-
382
 *
383
 * Subtract 2 ICOORDS.
384
 **********************************************************************/
385
386
inline ICOORD operator-( // subtract vectors
387
    const ICOORD &op1,   // operands
388
22.3M
    const ICOORD &op2) {
389
22.3M
  ICOORD sum; // result
390
391
22.3M
  sum.xcoord = op1.xcoord - op2.xcoord;
392
22.3M
  sum.ycoord = op1.ycoord - op2.ycoord;
393
22.3M
  return sum;
394
22.3M
}
395
396
/**********************************************************************
397
 * operator-=
398
 *
399
 * Subtract 2 ICOORDS.
400
 **********************************************************************/
401
402
inline ICOORD &operator-=( // subtract vectors
403
    ICOORD &op1,           // operands
404
50.4M
    const ICOORD &op2) {
405
50.4M
  op1.xcoord -= op2.xcoord;
406
50.4M
  op1.ycoord -= op2.ycoord;
407
50.4M
  return op1;
408
50.4M
}
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
42.6M
    const ICOORD &op2) {
419
42.6M
  return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord;
420
42.6M
}
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
66.8M
    const ICOORD &op2) {
431
66.8M
  return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord;
432
66.8M
}
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
0
    TDimension scale) {
443
0
  ICOORD result; // output
444
445
0
  result.xcoord = op1.xcoord * scale;
446
0
  result.ycoord = op1.ycoord * scale;
447
0
  return result;
448
0
}
449
450
inline ICOORD operator*( // scalar multiply
451
    TDimension scale,
452
    const ICOORD &op1 // operands
453
0
) {
454
0
  ICOORD result; // output
455
0
456
0
  result.xcoord = op1.xcoord * scale;
457
0
  result.ycoord = op1.ycoord * scale;
458
0
  return result;
459
0
}
460
461
/**********************************************************************
462
 * operator*=
463
 *
464
 * Scalar multiply of an ICOORD.
465
 **********************************************************************/
466
467
inline ICOORD &operator*=( // scalar multiply
468
    ICOORD &op1,           // operands
469
35.8M
    TDimension scale) {
470
35.8M
  op1.xcoord *= scale;
471
35.8M
  op1.ycoord *= scale;
472
35.8M
  return op1;
473
35.8M
}
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
0
    TDimension scale) {
484
0
  ICOORD result; // output
485
0
486
0
  result.xcoord = op1.xcoord / scale;
487
0
  result.ycoord = op1.ycoord / scale;
488
0
  return result;
489
0
}
490
491
/**********************************************************************
492
 * operator/=
493
 *
494
 * Scalar divide of an ICOORD.
495
 **********************************************************************/
496
497
inline ICOORD &operator/=( // scalar divide
498
    ICOORD &op1,           // operands
499
0
    TDimension scale) {
500
0
  op1.xcoord /= scale;
501
0
  op1.ycoord /= scale;
502
0
  return op1;
503
0
}
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
161M
    const FCOORD &vec) {
513
161M
  auto tmp = static_cast<TDimension>(std::floor(xcoord * vec.x() - ycoord * vec.y() + 0.5f));
514
161M
  ycoord = static_cast<TDimension>(std::floor(ycoord * vec.x() + xcoord * vec.y() + 0.5f));
515
161M
  xcoord = tmp;
516
161M
}
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
0
) {
527
0
  FCOORD result; // output
528
529
0
  result.xcoord = -src.ycoord;
530
0
  result.ycoord = src.xcoord;
531
0
  return result;
532
0
}
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
0
) {
543
0
  FCOORD result; // output
544
545
0
  result.xcoord = -src.xcoord;
546
0
  result.ycoord = -src.ycoord;
547
0
  return result;
548
0
}
549
550
/**********************************************************************
551
 * operator+
552
 *
553
 * Add 2 FCOORDS.
554
 **********************************************************************/
555
556
inline FCOORD operator+( // sum vectors
557
    const FCOORD &op1,   // operands
558
2.38M
    const FCOORD &op2) {
559
2.38M
  FCOORD sum; // result
560
561
2.38M
  sum.xcoord = op1.xcoord + op2.xcoord;
562
2.38M
  sum.ycoord = op1.ycoord + op2.ycoord;
563
2.38M
  return sum;
564
2.38M
}
565
566
/**********************************************************************
567
 * operator+=
568
 *
569
 * Add 2 FCOORDS.
570
 **********************************************************************/
571
572
inline FCOORD &operator+=( // sum vectors
573
    FCOORD &op1,           // operands
574
232M
    const FCOORD &op2) {
575
232M
  op1.xcoord += op2.xcoord;
576
232M
  op1.ycoord += op2.ycoord;
577
232M
  return op1;
578
232M
}
579
580
/**********************************************************************
581
 * operator-
582
 *
583
 * Subtract 2 FCOORDS.
584
 **********************************************************************/
585
586
inline FCOORD operator-( // subtract vectors
587
    const FCOORD &op1,   // operands
588
55.3M
    const FCOORD &op2) {
589
55.3M
  FCOORD sum; // result
590
591
55.3M
  sum.xcoord = op1.xcoord - op2.xcoord;
592
55.3M
  sum.ycoord = op1.ycoord - op2.ycoord;
593
55.3M
  return sum;
594
55.3M
}
595
596
/**********************************************************************
597
 * operator-=
598
 *
599
 * Subtract 2 FCOORDS.
600
 **********************************************************************/
601
602
inline FCOORD &operator-=( // subtract vectors
603
    FCOORD &op1,           // operands
604
26.8M
    const FCOORD &op2) {
605
26.8M
  op1.xcoord -= op2.xcoord;
606
26.8M
  op1.ycoord -= op2.ycoord;
607
26.8M
  return op1;
608
26.8M
}
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
0
    const FCOORD &op2) {
619
0
  return op1.xcoord * op2.xcoord + op1.ycoord * op2.ycoord;
620
0
}
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
48.1M
    const FCOORD &op2) {
631
48.1M
  return op1.xcoord * op2.ycoord - op1.ycoord * op2.xcoord;
632
48.1M
}
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
232M
    float scale) {
643
232M
  FCOORD result; // output
644
645
232M
  result.xcoord = op1.xcoord * scale;
646
232M
  result.ycoord = op1.ycoord * scale;
647
232M
  return result;
648
232M
}
649
650
inline FCOORD operator*( // scalar multiply
651
    float scale,
652
    const FCOORD &op1 // operands
653
0
) {
654
0
  FCOORD result; // output
655
0
656
0
  result.xcoord = op1.xcoord * scale;
657
0
  result.ycoord = op1.ycoord * scale;
658
0
  return result;
659
0
}
660
661
/**********************************************************************
662
 * operator*=
663
 *
664
 * Scalar multiply of an FCOORD.
665
 **********************************************************************/
666
667
inline FCOORD &operator*=( // scalar multiply
668
    FCOORD &op1,           // operands
669
0
    float scale) {
670
0
  op1.xcoord *= scale;
671
0
  op1.ycoord *= scale;
672
0
  return op1;
673
0
}
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
0
    float scale) {
684
0
  FCOORD result; // output
685
0
  ASSERT_HOST(scale != 0.0f);
686
0
  result.xcoord = op1.xcoord / scale;
687
0
  result.ycoord = op1.ycoord / scale;
688
0
  return result;
689
0
}
690
691
/**********************************************************************
692
 * operator/=
693
 *
694
 * Scalar divide of an FCOORD.
695
 **********************************************************************/
696
697
inline FCOORD &operator/=( // scalar divide
698
    FCOORD &op1,           // operands
699
0
    float scale) {
700
0
  ASSERT_HOST(scale != 0.0f);
701
0
  op1.xcoord /= scale;
702
0
  op1.ycoord /= scale;
703
0
  return op1;
704
0
}
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
50.7M
    const FCOORD vec) {
714
50.7M
  float tmp;
715
716
50.7M
  tmp = xcoord * vec.x() - ycoord * vec.y();
717
50.7M
  ycoord = ycoord * vec.x() + xcoord * vec.y();
718
50.7M
  xcoord = tmp;
719
50.7M
}
720
721
0
inline void FCOORD::unrotate(const FCOORD &vec) {
722
0
  rotate(FCOORD(vec.x(), -vec.y()));
723
0
}
724
725
} // namespace tesseract
726
727
#endif