Coverage Report

Created: 2024-10-01 06:54

/src/Simd/src/Simd/SimdRectangle.hpp
Line
Count
Source (jump to first uncovered line)
1
/*
2
* Simd Library (http://ermig1979.github.io/Simd).
3
*
4
* Copyright (c) 2011-2017 Yermalayeu Ihar.
5
*
6
* Permission is hereby granted, free of charge, to any person obtaining a copy
7
* of this software and associated documentation files (the "Software"), to deal
8
* in the Software without restriction, including without limitation the rights
9
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10
* copies of the Software, and to permit persons to whom the Software is
11
* furnished to do so, subject to the following conditions:
12
*
13
* The above copyright notice and this permission notice shall be included in
14
* all copies or substantial portions of the Software.
15
*
16
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
22
* SOFTWARE.
23
*/
24
#ifndef __SimdRectangle_hpp__
25
#define __SimdRectangle_hpp__
26
27
#include "Simd/SimdPoint.hpp"
28
29
#include <algorithm>
30
31
namespace Simd
32
{
33
    /*! @ingroup cpp_rectangle
34
35
        \short The Rectangle structure defines the positions of left, top, right and bottom sides of a rectangle.
36
37
        In order to have mutual conversion with OpenCV rectangle you have to define macro SIMD_OPENCV_ENABLE:
38
        \verbatim
39
        #include "opencv2/core/core.hpp"
40
        #define SIMD_OPENCV_ENABLE
41
        #include "Simd/SimdRectangle.hpp"
42
43
        int main()
44
        {
45
            typedef Simd::Rectangle<ptrdiff_t> Rect;
46
47
            cv::Rect cvRect;
48
            Rect simdRect;
49
50
            simdRect = cvRect;
51
            cvRect = simdRect;
52
53
            return 0;
54
        }
55
        \endverbatim
56
57
        \ref cpp_rectangle_functions.
58
    */
59
    template <typename T>
60
    struct Rectangle
61
    {
62
        typedef T Type; /*!< Type definition. */
63
64
        T left; /*!< \brief Specifies the position of left side of a rectangle. */
65
        T top; /*!< \brief Specifies the position of top side of a rectangle. */
66
        T right; /*!< \brief Specifies the position of right side of a rectangle. */
67
        T bottom; /*!< \brief Specifies the position of bottom side of a rectangle. */
68
69
        /*!
70
            Creates a new Rectangle structure that contains the default (0, 0, 0, 0) positions of its sides.
71
        */
72
        Rectangle();
73
74
        /*!
75
            Creates a new Rectangle structure that contains the specified positions of its sides.
76
77
            \param [in] l - initial left value.
78
            \param [in] t - initial top value.
79
            \param [in] r - initial right value.
80
            \param [in] b - initial bottom value.
81
        */
82
        template <typename TL, typename TT, typename TR, typename TB> Rectangle(TL l, TT t, TR r, TB b);
83
84
        /*!
85
            Creates a new Rectangular structure that contains the specified coordinates of its left-top and right-bottom corners.
86
87
            \param [in] lt - initial coordinates of left-top corner.
88
            \param [in] rb - initial coordinates of right-bottom corner.
89
        */
90
        template <typename TLT, typename TRB> Rectangle(const Point<TLT> & lt, const Point<TRB> & rb);
91
92
        /*!
93
            Creates a new Rectangular structure that contains the specified coordinates of its right-bottom corner.
94
            The coordinates of left-top corner is set to (0, 0).
95
96
            \param [in] rb - initial coordinates of right-bottom corner.
97
        */
98
        template <typename TRB> Rectangle(const Point<TRB> & rb);
99
100
        /*!
101
            Creates a new Rectangle structure on the base of another rectangle of arbitrary type.
102
103
            \param [in] r - a rectangle of arbitrary type.
104
        */
105
        template <class TR, template<class> class TRectangle> Rectangle(const TRectangle<TR> & r);
106
107
#ifdef SIMD_OPENCV_ENABLE
108
        /*!
109
            Creates a new Rectangle structure on the base of OpenCV rectangle.
110
111
            \note You have to define SIMD_OPENCV_ENABLE in order to use this functionality.
112
113
            \param [in] r - an OpenCV rectangle.
114
        */
115
        template <class TR> Rectangle(const cv::Rect_<TR> & r);
116
#endif
117
118
        /*!
119
            A rectangle destructor.
120
        */
121
        ~Rectangle();
122
123
        /*!
124
            Converts itself to rectangle of arbitrary type.
125
126
            \return a rectangle of arbitrary type.
127
        */
128
        template <class TR, template<class> class TRectangle> operator TRectangle<TR>() const;
129
130
#ifdef SIMD_OPENCV_ENABLE
131
        /*!
132
            Converts itself to OpenCV rectangle.
133
134
            \note You have to define SIMD_OPENCV_ENABLE in order to use this functionality.
135
136
            \return an OpenCV rectangle.
137
        */
138
        template <class TR> operator cv::Rect_<TR>() const;
139
#endif
140
141
        /*!
142
            Performs copying from rectangle of arbitrary type.
143
144
            \param [in] r - a rectangle of arbitrary type.
145
            \return a reference to itself.
146
        */
147
        template <typename TR> Rectangle<T> & operator = (const Rectangle<TR> & r);
148
149
#ifdef SIMD_OPENCV_ENABLE
150
        /*!
151
            Performs copying from OpenCV rectangle.
152
153
            \note You have to define SIMD_OPENCV_ENABLE in order to use this functionality.
154
155
            \param [in] r - an OpenCV rectangle.
156
            \return a reference to itself.
157
        */
158
        template <typename TR> Rectangle<T> & operator = (const cv::Rect_<TR> & r);
159
#endif
160
161
        /*!
162
            Sets position of left side.
163
164
            \param [in] l - a new position of left side.
165
            \return a reference to itself.
166
        */
167
        template <typename TL> Rectangle<T> & SetLeft(const TL & l);
168
169
        /*!
170
            Sets position of top side.
171
172
            \param [in] t - a new position of top side.
173
            \return a reference to itself.
174
        */
175
        template <typename TT> Rectangle<T> & SetTop(const TT & t);
176
177
        /*!
178
            Sets position of right side.
179
180
            \param [in] r - a new position of right side.
181
            \return a reference to itself.
182
        */
183
        template <typename TR> Rectangle<T> & SetRight(const TR & r);
184
185
        /*!
186
            Sets position of bottom side.
187
188
            \param [in] b - a new position of bottom side.
189
            \return a reference to itself.
190
        */
191
        template <typename TB> Rectangle<T> & SetBottom(const TB & b);
192
193
        /*!
194
            Sets coordinates of top-left corner.
195
196
            \param [in] topLeft - a new coordinates of top-left corner.
197
            \return a reference to itself.
198
        */
199
        template <typename TP> Rectangle<T> & SetTopLeft(const Point<TP> & topLeft);
200
201
        /*!
202
            Sets coordinates of top-right corner.
203
204
            \param [in] topRight - a new coordinates of top-right corner.
205
            \return a reference to itself.
206
        */
207
        template <typename TP> Rectangle<T> & SetTopRight(const Point<TP> & topRight);
208
209
        /*!
210
            Sets coordinates of bottom-left corner.
211
212
            \param [in] bottomLeft - a new coordinates of bottom-left corner.
213
            \return a reference to itself.
214
        */
215
        template <typename TP> Rectangle<T> & SetBottomLeft(const Point<TP> & bottomLeft);
216
217
        /*!
218
            Sets coordinates of bottom-right corner.
219
220
            \param [in] bottomRight - a new coordinates of bottom-right corner.
221
            \return a reference to itself.
222
        */
223
        template <typename TP> Rectangle<T> & SetBottomRight(const Point<TP> & bottomRight);
224
225
        /*!
226
            Gets position of left side.
227
228
            \return a position of left side.
229
        */
230
        T Left() const;
231
232
        /*!
233
            Gets position of top side.
234
235
            \return a position of top side.
236
        */
237
        T Top() const;
238
239
        /*!
240
            Gets position of right side.
241
242
            \return a position of right side.
243
        */
244
        T Right() const;
245
246
        /*!
247
            Gets position of bottom side.
248
249
            \return a position of bottom side.
250
        */
251
        T Bottom() const;
252
253
        /*!
254
            Gets coordinates of top-left corner.
255
256
            \return a point with coordinates of top-left corner.
257
        */
258
        Point<T> TopLeft() const;
259
260
        /*!
261
            Gets coordinates of top-right corner.
262
263
            \return a point with coordinates of top-right corner.
264
        */
265
        Point<T> TopRight() const;
266
267
        /*!
268
            Gets coordinates of bottom-left corner.
269
270
            \return a point with coordinates of bottom-left corner.
271
        */
272
        Point<T> BottomLeft() const;
273
274
        /*!
275
            Gets coordinates of bottom-right corner.
276
277
            \return a point with coordinates of bottom-right corner.
278
        */
279
        Point<T> BottomRight() const;
280
281
        /*!
282
            Gets rectangle width.
283
284
            \return a rectangle width.
285
        */
286
        T Width() const;
287
288
        /*!
289
            Gets rectangle height.
290
291
            \return a rectangle height.
292
        */
293
        T Height() const;
294
295
        /*!
296
            Gets rectangle area.
297
298
            \return a rectangle area.
299
        */
300
        T Area() const;
301
302
        /*!
303
            Returns true if rectangle area is equal to zero.
304
305
            \return a boolean value.
306
        */
307
        bool Empty() const;
308
309
        /*!
310
            Gets size (width and height) of the rectangle.
311
312
            \return a point with rectangle size.
313
        */
314
        Point<T> Size() const;
315
316
        /*!
317
            Gets coordinates of rectangle center.
318
319
            \return a point with coordinates of rectangle center.
320
        */
321
        Point<T> Center() const;
322
323
        /*!
324
            Checks on the point with specified coordinates to belonging to the rectangle.
325
326
            \param [in] x - x-coordinate of checked point.
327
            \param [in] y - y-coordinate of checked point.
328
            \return a result of checking.
329
        */
330
        template <typename TX, typename TY> bool Contains(TX x, TY y) const;
331
332
        /*!
333
            Checks on the point to belonging to the rectangle.
334
335
            \param [in] p - a checked point.
336
            \return a result of checking.
337
        */
338
        template <typename TP> bool Contains(const Point<TP> & p) const;
339
340
        /*!
341
            Checks on the rectangle with specified coordinates to belonging to the rectangle.
342
343
            \param [in] l - a left side of checked rectangle.
344
            \param [in] t - a top side of checked rectangle.
345
            \param [in] r - a right side of checked rectangle.
346
            \param [in] b - a bottom side of checked rectangle.
347
            \return a result of checking.
348
        */
349
        template <typename TL, typename TT, typename TR, typename TB> bool Contains(TL l, TT t, TR r, TB b) const;
350
351
        /*!
352
            Checks on the rectangle to belonging to the rectangle.
353
354
            \param [in] r - a checked rectangle.
355
            \return a result of checking.
356
        */
357
        template <typename TR> bool Contains(const Rectangle <TR> & r) const;
358
359
        /*!
360
            Shifts a rectangle on the specific value.
361
362
            \param [in] shift - a point with shift value.
363
            \return a reference to itself.
364
        */
365
        template <typename TP> Rectangle<T> & Shift(const Point<TP> & shift);
366
367
        /*!
368
            Shifts a rectangle on the specific value.
369
370
            \param [in] shiftX - x-coordinate of the shift.
371
            \param [in] shiftY - y-coordinate of the shift.
372
            \return a reference to itself.
373
        */
374
        template <typename TX, typename TY> Rectangle<T> & Shift(TX shiftX, TY shiftY);
375
376
        /*!
377
            Gets a rectangle with shifted coordinates.
378
379
            \param [in] shift - a point with shift value.
380
            \return a shifted rectangle.
381
        */
382
        template <typename TP> Rectangle<T> Shifted(const Point<TP> & shift) const;
383
384
        /*!
385
            Gets a rectangle with shifted coordinates.
386
387
            \param [in] shiftX - x-coordinate of the shift.
388
            \param [in] shiftY - y-coordinate of the shift.
389
            \return a shifted rectangle.
390
        */
391
        template <typename TX, typename TY> Rectangle<T> Shifted(TX shiftX, TY shiftY) const;
392
393
        /*!
394
            Adds border to rectangle.
395
396
            \note The value of border can be negative.
397
398
            \param [in] border - a width of added border.
399
            \return a reference to itself.
400
        */
401
        template <typename TB> Rectangle<T> & AddBorder(TB border);
402
403
        /*!
404
            Gets an intersection of the two rectangles (current and specified).
405
406
            \param [in] r - specified rectangle.
407
            \return a rectangle with result of intersection.
408
        */
409
        template <typename TR> Rectangle<T> Intersection(const Rectangle<TR> & r) const;
410
411
        /*!
412
            Sets to the rectangle results of the intersection of the rectangle and specified point.
413
414
            \param [in] p - specified point.
415
            \return a reference to itself.
416
        */
417
        template <typename TP> Rectangle<T> & operator &= (const Point<TP> & p);
418
419
        /*!
420
            Sets to the rectangle results of the intersection of the rectangle and specified rectangle.
421
422
            \param [in] r - specified rectangle.
423
            \return a reference to itself.
424
        */
425
        template <typename TR> Rectangle<T> & operator &= (const Rectangle<TR> & r);
426
427
        /*!
428
            Sets to the rectangle results of the union of the rectangle and specified point.
429
430
            \param [in] p - specified point.
431
            \return a reference to itself.
432
        */
433
        template <typename TP> Rectangle<T> & operator |= (const Point<TP> & p);
434
435
        /*!
436
            Sets to the rectangle results of the union of the rectangle and specified rectangle.
437
438
            \param [in] r - specified rectangle.
439
            \return a reference to itself.
440
        */
441
        template <typename TR> Rectangle<T> & operator |= (const Rectangle<TR> & r);
442
443
        /*!
444
            Adds to the rectangle's coordinates corresponding coordinates of specified rectangle.
445
446
            \param [in] r - specified rectangle.
447
            \return a reference to itself.
448
        */
449
        template <typename TR> Rectangle<T> & operator += (const Rectangle<TR> & r);
450
451
        /*!
452
            Checks on overlapping of current rectangle and specified rectangle.
453
454
            \param [in] r - specified rectangle.
455
            \return a result of checking.
456
        */
457
        bool Overlaps(const Rectangle<T> & r) const;
458
    };
459
460
    /*! @ingroup cpp_rectangle_functions
461
462
        \fn template <typename T> bool operator == (const Rectangle<T> & r1, const Rectangle<T> & r2);
463
464
        \short Compares two rectangles on equality.
465
466
        \param [in] r1 - a first rectangle.
467
        \param [in] r2 - a second rectangle.
468
        \return a result of comparison.
469
    */
470
    template <typename T> bool operator == (const Rectangle<T> & r1, const Rectangle<T> & r2);
471
472
    /*! @ingroup cpp_rectangle_functions
473
474
        \fn template <typename T> bool operator != (const Rectangle<T> & r1, const Rectangle<T> & r2);
475
476
        \short Compares two rectangles on inequality.
477
478
        \param [in] r1 - a first rectangle.
479
        \param [in] r2 - a second rectangle.
480
        \return a result of comparison.
481
    */
482
    template <typename T> bool operator != (const Rectangle<T> & r1, const Rectangle<T> & r2);
483
484
    /*! @ingroup cpp_rectangle_functions
485
486
        \fn template<class T1, class T2> Rectangle<T1> operator / (const Rectangle<T1> & rect, const T2 & value);
487
488
        \short Divides the rectangle on the scalar value.
489
490
        \param [in] rect - a rectangle.
491
        \param [in] value - a scalar value.
492
        \return a result of division.
493
    */
494
    template<class T1, class T2> Rectangle<T1> operator / (const Rectangle<T1> & rect, const T2 & value);
495
496
    /*! @ingroup cpp_rectangle_functions
497
498
        \fn template<class T1, class T2> Rectangle<T1> operator * (const Rectangle<T1> & rect, const T2 & value);
499
500
        \short Multiplies the rectangle on the scalar value.
501
502
        \param [in] rect - a rectangle.
503
        \param [in] value - a scalar value.
504
        \return a result of multiplication.
505
    */
506
    template<class T1, class T2> Rectangle<T1> operator * (const Rectangle<T1> & rect, const T2 & value);
507
508
    /*! @ingroup cpp_rectangle_functions
509
510
        \fn template<class T1, class T2> Rectangle<T1> operator * (const T2 & value, const Rectangle<T1> & rect);
511
512
        \short Multiplies the scalar value on the rectangle.
513
514
        \param [in] value - a scalar value.
515
        \param [in] rect - a rectangle.
516
        \return a result of multiplication.
517
    */
518
    template<class T1, class T2> Rectangle<T1> operator * (const T2 & value, const Rectangle<T1> & rect);
519
520
    /*! @ingroup cpp_rectangle_functions
521
522
        \fn template <typename T> Rectangle<T> operator + (const Rectangle<T> & r1, const Rectangle<T> & r2);
523
524
        \short Sums the corresponding rectangle's coordinates of two rectangles..
525
526
        \param [in] r1 - a first rectangle.
527
        \param [in] r2 - a second rectangle.
528
        \return a rectangle with result coordinates.
529
    */
530
    template <typename T> Rectangle<T> operator + (const Rectangle<T> & r1, const Rectangle<T> & r2);
531
532
    //-------------------------------------------------------------------------
533
534
    // struct Rectangle<T> implementation:
535
536
    template <typename T>
537
    SIMD_INLINE Rectangle<T>::Rectangle()
538
        : left(0)
539
        , top(0)
540
        , right(0)
541
        , bottom(0)
542
0
    {
543
0
    }
544
545
    template <typename T> template <typename TL, typename TT, typename TR, typename TB>
546
    SIMD_INLINE Rectangle<T>::Rectangle(TL l, TT t, TR r, TB b)
547
        : left(Convert<T, TL>(l))
548
        , top(Convert<T, TT>(t))
549
        , right(Convert<T, TR>(r))
550
        , bottom(Convert<T, TB>(b))
551
0
    {
552
0
    }
Unexecuted instantiation: Simd::Rectangle<long>::Rectangle<int, int, long, long>(int, int, long, long)
Unexecuted instantiation: Simd::Rectangle<long>::Rectangle<long, long, long, long>(long, long, long, long)
553
554
    template <typename T> template <typename TLT, typename TRB>
555
    SIMD_INLINE Rectangle<T>::Rectangle(const Point<TLT> & lt, const Point<TRB> & rb)
556
        : left(Convert<T, TLT>(lt.x))
557
        , top(Convert<T, TLT>(lt.y))
558
        , right(Convert<T, TRB>(rb.x))
559
        , bottom(Convert<T, TRB>(rb.y))
560
    {
561
    }
562
563
    template <typename T> template <typename TRB>
564
    SIMD_INLINE Rectangle<T>::Rectangle(const Point<TRB> & rb)
565
        : left(0)
566
        , top(0)
567
        , right(Convert<T, TRB>(rb.x))
568
        , bottom(Convert<T, TRB>(rb.y))
569
    {
570
    }
571
572
    template <typename T> template <class TR, template<class> class TRectangle>
573
    SIMD_INLINE Rectangle<T>::Rectangle(const TRectangle<TR> & r)
574
        : left(Convert<T, TR>(r.left))
575
        , top(Convert<T, TR>(r.top))
576
        , right(Convert<T, TR>(r.right))
577
        , bottom(Convert<T, TR>(r.bottom))
578
    {
579
    }
580
581
#ifdef SIMD_OPENCV_ENABLE
582
    template <typename T> template <class TR>
583
    SIMD_INLINE Rectangle<T>::Rectangle(const cv::Rect_<TR> & r)
584
        : left(Convert<T, TR>(r.x))
585
        , top(Convert<T, TR>(r.y))
586
        , right(Convert<T, TR>(r.x + r.width))
587
        , bottom(Convert<T, TR>(r.y + r.height))
588
    {
589
    }
590
#endif
591
592
    template <typename T>
593
    SIMD_INLINE Rectangle<T>::~Rectangle()
594
0
    {
595
0
    }
596
597
    template <typename T> template <class TR, template<class> class TRectangle>
598
    SIMD_INLINE Rectangle<T>::operator TRectangle<TR>() const
599
    {
600
        return TRectangle<TR>(Convert<TR, T>(left), Convert<TR, T>(top),
601
            Convert<TR, T>(right), Convert<TR, T>(bottom));
602
    }
603
604
#ifdef SIMD_OPENCV_ENABLE
605
    template <typename T> template <class TR>
606
    SIMD_INLINE Rectangle<T>::operator cv::Rect_<TR>() const
607
    {
608
        return cv::Rect_<TR>(Convert<TR, T>(left), Convert<TR, T>(top),
609
            Convert<TR, T>(right - left), Convert<TR, T>(bottom - top));
610
    }
611
#endif
612
613
    template <typename T> template <typename TR>
614
    SIMD_INLINE Rectangle<T> & Rectangle<T>::operator = (const Rectangle<TR> & r)
615
    {
616
        left = Convert<T, TR>(r.left);
617
        top = Convert<T, TR>(r.top);
618
        right = Convert<T, TR>(r.right);
619
        bottom = Convert<T, TR>(r.bottom);
620
        return *this;
621
    }
622
623
#ifdef SIMD_OPENCV_ENABLE
624
    template <typename T> template <class TR>
625
    SIMD_INLINE Rectangle<T> & Rectangle<T>::operator = (const cv::Rect_<TR> & r)
626
    {
627
        left = Convert<T, TR>(r.x);
628
        top = Convert<T, TR>(r.y);
629
        right = Convert<T, TR>(r.x + r.width);
630
        bottom = Convert<T, TR>(r.y + r.height);
631
        return *this;
632
    }
633
#endif
634
635
    template <typename T> template <typename TL>
636
    SIMD_INLINE Rectangle<T> & Rectangle<T>::SetLeft(const TL & l)
637
    {
638
        left = Convert<T, TL>(l);
639
        return *this;
640
    }
641
642
    template <typename T> template <typename TT>
643
    SIMD_INLINE Rectangle<T> & Rectangle<T>::SetTop(const TT & t)
644
    {
645
        top = Convert<T, TT>(t);
646
        return *this;
647
    }
648
649
    template <typename T> template <typename TR>
650
    SIMD_INLINE Rectangle<T> & Rectangle<T>::SetRight(const TR & r)
651
    {
652
        right = Convert<T, TR>(r);
653
        return *this;
654
    }
655
656
    template <typename T> template <typename TB>
657
    SIMD_INLINE Rectangle<T> & Rectangle<T>::SetBottom(const TB & b)
658
    {
659
        bottom = Convert<T, TB>(b);
660
        return *this;
661
    }
662
663
    template <typename T> template <typename TP>
664
    SIMD_INLINE Rectangle<T> & Rectangle<T>::SetTopLeft(const Point<TP> & topLeft)
665
    {
666
        left = Convert<T, TP>(topLeft.x);
667
        top = Convert<T, TP>(topLeft.y);
668
        return *this;
669
    }
670
671
    template <typename T> template <typename TP>
672
    SIMD_INLINE Rectangle<T> & Rectangle<T>::SetTopRight(const Point<TP> & topRight)
673
    {
674
        right = Convert<T, TP>(topRight.x);
675
        top = Convert<T, TP>(topRight.y);
676
        return *this;
677
    }
678
679
    template <typename T> template <typename TP>
680
    SIMD_INLINE Rectangle<T> & Rectangle<T>::SetBottomLeft(const Point<TP> & bottomLeft)
681
    {
682
        left = Convert<T, TP>(bottomLeft.x);
683
        bottom = Convert<T, TP>(bottomLeft.y);
684
        return *this;
685
    }
686
687
    template <typename T> template <typename TP>
688
    SIMD_INLINE Rectangle<T> & Rectangle<T>::SetBottomRight(const Point<TP> & bottomRight)
689
    {
690
        right = Convert<T, TP>(bottomRight.x);
691
        bottom = Convert<T, TP>(bottomRight.y);
692
        return *this;
693
    }
694
695
    template <typename T>
696
    SIMD_INLINE T Rectangle<T>::Left() const
697
    {
698
        return left;
699
    }
700
701
    template <typename T>
702
    SIMD_INLINE T Rectangle<T>::Top() const
703
    {
704
        return top;
705
    }
706
707
    template <typename T>
708
    SIMD_INLINE T Rectangle<T>::Right() const
709
    {
710
        return right;
711
    }
712
713
    template <typename T>
714
    SIMD_INLINE T Rectangle<T>::Bottom() const
715
    {
716
        return bottom;
717
    }
718
719
    template <typename T>
720
    SIMD_INLINE Point<T> Rectangle<T>::TopLeft() const
721
    {
722
        return Point<T>(left, top);
723
    }
724
725
    template <typename T>
726
    SIMD_INLINE Point<T> Rectangle<T>::TopRight() const
727
    {
728
        return Point<T>(right, top);
729
    }
730
731
    template <typename T>
732
    SIMD_INLINE Point<T> Rectangle<T>::BottomLeft() const
733
    {
734
        return Point<T>(left, bottom);
735
    }
736
737
    template <typename T>
738
    SIMD_INLINE Point<T> Rectangle<T>::BottomRight() const
739
    {
740
        return Point<T>(right, bottom);
741
    }
742
743
    template <typename T>
744
    SIMD_INLINE T Rectangle<T>::Width() const
745
0
    {
746
0
        return right - left;
747
0
    }
748
749
    template <typename T>
750
    SIMD_INLINE T Rectangle<T>::Height() const
751
0
    {
752
0
        return bottom - top;
753
0
    }
754
755
    template <typename T>
756
    SIMD_INLINE T Rectangle<T>::Area() const
757
0
    {
758
0
        return Width()*Height();
759
0
    }
760
761
    template <typename T>
762
    SIMD_INLINE bool Rectangle<T>::Empty() const
763
    {
764
        return Area() == 0;
765
    }
766
767
    template <typename T>
768
    SIMD_INLINE Point<T> Rectangle<T>::Size() const
769
    {
770
        return Point<T>(Width(), Height());
771
    }
772
773
    template <typename T>
774
    SIMD_INLINE Point<T> Rectangle<T>::Center() const
775
    {
776
        return Point<T>((left + right) / 2.0, (top + bottom) / 2.0);
777
    }
778
779
    template <typename T> template <typename TX, typename TY>
780
    SIMD_INLINE bool Rectangle<T>::Contains(TX x, TY y) const
781
    {
782
        Point<T> p(x, y);
783
        return p.x >= left && p.x < right && p.y >= top && p.y < bottom;
784
    }
785
786
    template <typename T> template <typename TP>
787
    SIMD_INLINE bool Rectangle<T>::Contains(const Point<TP> & p) const
788
    {
789
        return Contains(p.x, p.y);
790
    }
791
792
    template <typename T> template <typename TL, typename TT, typename TR, typename TB>
793
    SIMD_INLINE bool Rectangle<T>::Contains(TL l, TT t, TR r, TB b) const
794
    {
795
        Rectangle<T> rect(l, t, r, b);
796
        return rect.left >= left && rect.right <= right && rect.top >= top && rect.bottom <= bottom;
797
    }
798
799
    template <typename T> template <typename TR>
800
    SIMD_INLINE bool Rectangle<T>::Contains(const Rectangle <TR> & r) const
801
    {
802
        return Contains(r.left, r.top, r.right, r.bottom);
803
    }
804
805
    template <typename T> template <typename TP>
806
    SIMD_INLINE Rectangle<T> & Rectangle<T>::Shift(const Point<TP> & shift)
807
    {
808
        return Shift(shift.x, shift.y);
809
    }
810
811
    template <typename T> template <typename TX, typename TY>
812
    SIMD_INLINE Rectangle<T> & Rectangle<T>::Shift(TX shiftX, TY shiftY)
813
    {
814
        Point<T> shift(shiftX, shiftY);
815
        left += shift.x;
816
        top += shift.y;
817
        right += shift.x;
818
        bottom += shift.y;
819
        return *this;
820
    }
821
822
    template <typename T> template <typename TP>
823
    SIMD_INLINE Rectangle<T> Rectangle<T>::Shifted(const Point<TP> & shift) const
824
    {
825
        return Shifted(shift.x, shift.y);
826
    }
827
828
    template <typename T> template <typename TX, typename TY>
829
    SIMD_INLINE Rectangle<T> Rectangle<T>::Shifted(TX shiftX, TY shiftY) const
830
    {
831
        Point<T> shift(shiftX, shiftY);
832
        return Rectangle<T>(left + shift.x, top + shift.y, right + shift.x, bottom + shift.y);
833
    }
834
835
    template <typename T> template <typename TB>
836
    SIMD_INLINE Rectangle<T> & Rectangle<T>::AddBorder(TB border)
837
    {
838
        T _border = Convert<T, TB>(border);
839
        left -= _border;
840
        top -= _border;
841
        right += _border;
842
        bottom += _border;
843
        return *this;
844
    }
845
846
    template <typename T> template <typename TR>
847
    SIMD_INLINE Rectangle<T> Rectangle<T>::Intersection(const Rectangle<TR> & rect) const
848
    {
849
        Rectangle<T> _rect(rect);
850
        T l = std::max(left, _rect.left);
851
        T t = std::max(top, _rect.top);
852
        T r = std::max(l, std::min(right, _rect.right));
853
        T b = std::max(t, std::min(bottom, _rect.bottom));
854
        return Rectangle(l, t, r, b);
855
    }
856
857
    /*! \cond PRIVATE */
858
    template <typename T> template <typename TP>
859
    SIMD_INLINE Rectangle<T> & Rectangle<T>::operator &= (const Point<TP> & p)
860
    {
861
        Point<T> _p(p);
862
        if (Contains(_p))
863
        {
864
            left = _p.x;
865
            top = _p.y;
866
            right = _p.x + 1;
867
            bottom = _p.y + 1;
868
        }
869
        else
870
        {
871
            bottom = top;
872
            right = left;
873
        }
874
        return *this;
875
    }
876
877
    template <typename T> template <typename TR>
878
    SIMD_INLINE Rectangle<T> & Rectangle<T>::operator &= (const Rectangle<TR> & r)
879
    {
880
        if (Empty())
881
            return *this;
882
        if (r.Empty())
883
            return this->operator=(r);
884
885
        Rectangle<T> _r(r);
886
        if (left < _r.left)
887
            left = std::min(_r.left, right);
888
        if (top < _r.top)
889
            top = std::min(_r.top, bottom);
890
        if (right > _r.right)
891
            right = std::max(_r.right, left);
892
        if (bottom > _r.bottom)
893
            bottom = std::max(_r.bottom, top);
894
        return *this;
895
    }
896
    /*! \endcond */
897
898
    template <typename T> template <typename TP>
899
    SIMD_INLINE Rectangle<T> & Rectangle<T>::operator |= (const Point<TP> & p)
900
    {
901
        Point<T> _p(p);
902
        if (Empty())
903
        {
904
            left = _p.x;
905
            top = _p.y;
906
            right = _p.x + 1;
907
            bottom = _p.y + 1;
908
        }
909
        else
910
        {
911
            if (left > _p.x)
912
                left = _p.x;
913
            if (top > _p.y)
914
                top = _p.y;
915
            if (right <= _p.x)
916
                right = _p.x + 1;
917
            if (bottom <= _p.y)
918
                bottom = _p.y + 1;
919
        }
920
        return *this;
921
    }
922
923
    template <typename T> template <typename TR>
924
    SIMD_INLINE Rectangle<T> & Rectangle<T>::operator |= (const Rectangle<TR> & r)
925
    {
926
        if (Empty())
927
            return this->operator=(r);
928
        if (r.Empty())
929
            return *this;
930
931
        Rectangle<T> _r(r);
932
        left = std::min(left, _r.left);
933
        top = std::min(top, _r.top);
934
        right = std::max(right, _r.right);
935
        bottom = std::max(bottom, _r.bottom);
936
        return *this;
937
    }
938
939
    template <typename T> template <typename TR>
940
    SIMD_INLINE Rectangle<T> & Rectangle<T>::operator += (const Rectangle<TR> & r)
941
    {
942
        left += Convert<T, TR>(r.left);
943
        top += Convert<T, TR>(r.top);
944
        right += Convert<T, TR>(r.right);
945
        bottom += Convert<T, TR>(r.bottom);
946
        return *this;
947
    }
948
949
    template <typename T>
950
    SIMD_INLINE bool Rectangle<T>::Overlaps(const Rectangle<T> & r) const
951
    {
952
        bool lr = left < r.right;
953
        bool rl = right > r.left;
954
        bool tb = top < r.bottom;
955
        bool bt = bottom > r.top;
956
        return (lr == rl) && (tb == bt);
957
    }
958
959
    // Rectangle<T> utilities implementation:
960
961
    template <typename T>
962
    SIMD_INLINE bool operator == (const Rectangle<T> & r1, const Rectangle<T> & r2)
963
    {
964
        return r1.left == r2.left && r1.top == r2.top && r1.right == r2.right && r1.bottom == r2.bottom;
965
    }
966
967
    template <typename T>
968
    SIMD_INLINE bool operator != (const Rectangle<T> & r1, const Rectangle<T> & r2)
969
    {
970
        return r1.left != r2.left || r1.top != r2.top || r1.right != r2.right || r1.bottom != r2.bottom;
971
    }
972
973
    template<class T1, class T2>
974
    SIMD_INLINE Rectangle<T1> operator / (const Rectangle<T1> & rect, const T2 & value)
975
    {
976
        return Rectangle<T1>(rect.left / value, rect.top / value, rect.right / value, rect.bottom / value);
977
    }
978
979
    template<class T1, class T2>
980
    SIMD_INLINE Rectangle<T1> operator * (const Rectangle<T1> & rect, const T2 & value)
981
    {
982
        return Rectangle<T1>(rect.left*value, rect.top*value, rect.right*value, rect.bottom*value);
983
    }
984
985
    template<class T1, class T2>
986
    SIMD_INLINE Rectangle<T1> operator * (const T2 & value, const Rectangle<T1> & rect)
987
    {
988
        return Rectangle<T1>(rect.left*value, rect.top*value, rect.right*value, rect.bottom*value);
989
    }
990
991
    template<class T>
992
    SIMD_INLINE Rectangle<T> operator + (const Rectangle<T> & r1, const Rectangle<T> & r2)
993
    {
994
        return Rectangle<T>(r1.left + r2.left, r1.top + r2.top, r1.right + r2.right, r1.bottom + r2.bottom);
995
    }
996
}
997
#endif//__SimdRectangle_hpp__