/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 |