KiCad PCB EDA Suite
Loading...
Searching...
No Matches
box2.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright (C) 2012 SoftPLC Corporation, Dick Hollenbeck <[email protected]>
5 * Copyright (C) 2012-2022 Kicad Developers, see AUTHORS.txt for contributors.
6 * Copyright (C) 2013 CERN
7 * @author Tomasz Wlostowski <[email protected]>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#ifndef __BOX2_H
28#define __BOX2_H
29
30#include <algorithm>
31#include <limits>
32#include <optional>
33
34#include <math/vector2d.h>
35#include <geometry/eda_angle.h>
36#include <trigo.h>
37
41template <class Vec>
42class BOX2
43{
44public:
45 typedef typename Vec::coord_type coord_type;
46 typedef typename Vec::extended_type ecoord_type;
47 typedef std::numeric_limits<coord_type> coord_limits;
48
49 BOX2() :
50 m_Pos( 0, 0 ),
51 m_Size( 0, 0 ),
52 m_init( false )
53 {};
54
55 BOX2( const Vec& aPos, const Vec& aSize = Vec(0, 0) ) :
56 m_Pos( aPos ),
57 m_Size( aSize ),
58 m_init( true )
59 {
60 Normalize();
61 }
62
64 {
65 m_Pos.x = m_Pos.y = coord_limits::lowest() / 2 + coord_limits::epsilon();
66 m_Size.x = m_Size.y = coord_limits::max() - coord_limits::epsilon();
67 m_init = true;
68 }
69
70 Vec Centre() const
71 {
72 return Vec( m_Pos.x + ( m_Size.x / 2 ),
73 m_Pos.y + ( m_Size.y / 2 ) );
74 }
75
81 template <class Container>
82 void Compute( const Container& aPointList )
83 {
84 Vec vmin, vmax;
85
86 typename Container::const_iterator i;
87
88 if( !aPointList.size() )
89 return;
90
91 vmin = vmax = aPointList[0];
92
93 for( i = aPointList.begin(); i != aPointList.end(); ++i )
94 {
95 Vec p( *i );
96 vmin.x = std::min( vmin.x, p.x );
97 vmin.y = std::min( vmin.y, p.y );
98 vmax.x = std::max( vmax.x, p.x );
99 vmax.y = std::max( vmax.y, p.y );
100 }
101
102 SetOrigin( vmin );
103 SetSize( vmax - vmin );
104 }
105
111 void Move( const Vec& aMoveVector )
112 {
113 m_Pos += aMoveVector;
114 }
115
120 {
121 if( m_Size.y < 0 )
122 {
123 m_Size.y = -m_Size.y;
124 m_Pos.y -= m_Size.y;
125 }
126
127 if( m_Size.x < 0 )
128 {
129 m_Size.x = -m_Size.x;
130 m_Pos.x -= m_Size.x;
131 }
132
133 return *this;
134 }
135
141 bool Contains( const Vec& aPoint ) const
142 {
143 Vec rel_pos = aPoint - m_Pos;
144 Vec size = m_Size;
145
146 if( size.x < 0 )
147 {
148 size.x = -size.x;
149 rel_pos.x += size.x;
150 }
151
152 if( size.y < 0 )
153 {
154 size.y = -size.y;
155 rel_pos.y += size.y;
156 }
157
158 return ( rel_pos.x >= 0 ) && ( rel_pos.y >= 0 ) && ( rel_pos.y <= size.y) &&
159 ( rel_pos.x <= size.x);
160 }
161
167 bool Contains( coord_type x, coord_type y ) const { return Contains( Vec( x, y ) ); }
168
174 bool Contains( const BOX2<Vec>& aRect ) const
175 {
176 return Contains( aRect.GetOrigin() ) && Contains( aRect.GetEnd() );
177 }
178
179 const Vec& GetSize() const { return m_Size; }
180 coord_type GetX() const { return m_Pos.x; }
181 coord_type GetY() const { return m_Pos.y; }
182
183 const Vec& GetOrigin() const { return m_Pos; }
184 const Vec& GetPosition() const { return m_Pos; }
185 const Vec GetEnd() const { return Vec( GetRight(), GetBottom() ); }
186
187 coord_type GetWidth() const { return m_Size.x; }
188 coord_type GetHeight() const { return m_Size.y; }
189 coord_type GetRight() const { return m_Pos.x + m_Size.x; }
190 coord_type GetBottom() const { return m_Pos.y + m_Size.y; }
191
192 // Compatibility aliases
193 coord_type GetLeft() const { return GetX(); }
194 coord_type GetTop() const { return GetY(); }
195 const Vec GetCenter() const { return Centre(); }
196
200 int GetSizeMax() const { return ( m_Size.x > m_Size.y ) ? m_Size.x : m_Size.y; }
201
202 void SetOrigin( const Vec& pos )
203 {
204 m_Pos = pos;
205 m_init = true;
206 }
207
209 {
210 SetOrigin( Vec( x, y ) );
211 }
212
213 void SetSize( const Vec& size )
214 {
215 m_Size = size;
216 m_init = true;
217 }
218
220 {
221 SetSize( Vec( w, h ) );
222 }
223
225 {
226 m_Pos.x += dx;
227 m_Pos.y += dy;
228 }
229
230 void Offset( const Vec& offset )
231 {
232 Offset( offset.x, offset.y );
233 }
234
235 void SetX( coord_type val )
236 {
237 SetOrigin( val, m_Pos.y );
238 }
239
240 void SetY( coord_type val )
241 {
242 SetOrigin( m_Pos.x, val );
243 }
244
246 {
247 SetSize( val, m_Size.y );
248 }
249
251 {
252 SetSize( m_Size.x, val );
253 }
254
256 {
257 SetEnd( Vec( x, y ) );
258 }
259
260 void SetEnd( const Vec& pos )
261 {
262 SetSize( pos - m_Pos );
263 }
264
269 bool Intersects( const BOX2<Vec>& aRect ) const
270 {
271 // this logic taken from wxWidgets' geometry.cpp file:
272 bool rc;
273
274 BOX2<Vec> me( *this );
275 BOX2<Vec> rect( aRect );
276 me.Normalize(); // ensure size is >= 0
277 rect.Normalize(); // ensure size is >= 0
278
279 // calculate the left common area coordinate:
280 int left = std::max( me.m_Pos.x, rect.m_Pos.x );
281 // calculate the right common area coordinate:
282 int right = std::min( me.m_Pos.x + me.m_Size.x, rect.m_Pos.x + rect.m_Size.x );
283 // calculate the upper common area coordinate:
284 int top = std::max( me.m_Pos.y, rect.m_Pos.y );
285 // calculate the lower common area coordinate:
286 int bottom = std::min( me.m_Pos.y + me.m_Size.y, rect.m_Pos.y + rect.m_Size.y );
287
288 // if a common area exists, it must have a positive (null accepted) size
289 if( left <= right && top <= bottom )
290 rc = true;
291 else
292 rc = false;
293
294 return rc;
295 }
296
301 {
302 BOX2<Vec> me( *this );
303 BOX2<Vec> rect( aRect );
304 me.Normalize(); // ensure size is >= 0
305 rect.Normalize(); // ensure size is >= 0
306
307 Vec topLeft, bottomRight;
308
309 topLeft.x = std::max( me.m_Pos.x, rect.m_Pos.x );
310 bottomRight.x = std::min( me.m_Pos.x + me.m_Size.x, rect.m_Pos.x + rect.m_Size.x );
311 topLeft.y = std::max( me.m_Pos.y, rect.m_Pos.y );
312 bottomRight.y = std::min( me.m_Pos.y + me.m_Size.y, rect.m_Pos.y + rect.m_Size.y );
313
314 if ( topLeft.x < bottomRight.x && topLeft.y < bottomRight.y )
315 return BOX2<Vec>( topLeft, bottomRight - topLeft );
316 else
317 return BOX2<Vec>( Vec( 0, 0 ), Vec( 0, 0 ) );
318 }
319
323 bool Intersects( const Vec& aPoint1, const Vec& aPoint2 ) const
324 {
325 Vec point2, point4;
326
327 if( Contains( aPoint1 ) || Contains( aPoint2 ) )
328 return true;
329
330 point2.x = GetEnd().x;
331 point2.y = GetOrigin().y;
332 point4.x = GetOrigin().x;
333 point4.y = GetEnd().y;
334
335 //Only need to test 3 sides since a straight line can't enter and exit on same side
336 if( SegmentIntersectsSegment( aPoint1, aPoint2, GetOrigin(), point2 ) )
337 return true;
338
339 if( SegmentIntersectsSegment( aPoint1, aPoint2, point2, GetEnd() ) )
340 return true;
341
342 if( SegmentIntersectsSegment( aPoint1, aPoint2, GetEnd(), point4 ) )
343 return true;
344
345 return false;
346 }
347
352 bool Intersects( const BOX2<Vec>& aRect, const EDA_ANGLE& aRotation ) const
353 {
354 if( !m_init )
355 return false;
356
357 EDA_ANGLE rotation = aRotation;
358 rotation.Normalize();
359
360 /*
361 * Most rectangles will be axis aligned. It is quicker to check for this case and pass
362 * the rect to the simpler intersection test.
363 */
364
365 // Prevent floating point comparison errors
366 static const EDA_ANGLE ROT_EPSILON( 0.000000001, DEGREES_T );
367
368 static const EDA_ANGLE ROT_PARALLEL[] = { ANGLE_0, ANGLE_180, ANGLE_360 };
369 static const EDA_ANGLE ROT_PERPENDICULAR[] = { ANGLE_0, ANGLE_90, ANGLE_270 };
370
371 // Test for non-rotated rectangle
372 for( EDA_ANGLE ii : ROT_PARALLEL )
373 {
374 if( std::abs( rotation - ii ) < ROT_EPSILON )
375 return Intersects( aRect );
376 }
377
378 // Test for rectangle rotated by multiple of 90 degrees
379 for( EDA_ANGLE jj : ROT_PERPENDICULAR )
380 {
381 if( std::abs( rotation - jj ) < ROT_EPSILON )
382 {
383 BOX2<Vec> rotRect;
384
385 // Rotate the supplied rect by 90 degrees
386 rotRect.SetOrigin( aRect.Centre() );
387 rotRect.Inflate( aRect.GetHeight(), aRect.GetWidth() );
388 return Intersects( rotRect );
389 }
390 }
391
392 /* There is some non-orthogonal rotation.
393 * There are three cases to test:
394 * A) One point of this rect is inside the rotated rect
395 * B) One point of the rotated rect is inside this rect
396 * C) One of the sides of the rotated rect intersect this
397 */
398
399 VECTOR2I corners[4];
400
401 /* Test A : Any corners exist in rotated rect? */
402 corners[0] = m_Pos;
403 corners[1] = m_Pos + VECTOR2I( m_Size.x, 0 );
404 corners[2] = m_Pos + VECTOR2I( m_Size.x, m_Size.y );
405 corners[3] = m_Pos + VECTOR2I( 0, m_Size.y );
406
407 VECTOR2I rCentre = aRect.Centre();
408
409 for( int i = 0; i < 4; i++ )
410 {
411 VECTOR2I delta = corners[i] - rCentre;
412 RotatePoint( delta, -rotation );
413 delta += rCentre;
414
415 if( aRect.Contains( delta ) )
416 return true;
417 }
418
419 /* Test B : Any corners of rotated rect exist in this one? */
420 int w = aRect.GetWidth() / 2;
421 int h = aRect.GetHeight() / 2;
422
423 // Construct corners around center of shape
424 corners[0] = VECTOR2I( -w, -h );
425 corners[1] = VECTOR2I( w, -h );
426 corners[2] = VECTOR2I( w, h );
427 corners[3] = VECTOR2I( -w, h );
428
429 // Rotate and test each corner
430 for( int j = 0; j < 4; j++ )
431 {
432 RotatePoint( corners[j], rotation );
433 corners[j] += rCentre;
434
435 if( Contains( corners[j] ) )
436 return true;
437 }
438
439 /* Test C : Any sides of rotated rect intersect this */
440 if( Intersects( corners[0], corners[1] ) || Intersects( corners[1], corners[2] )
441 || Intersects( corners[2], corners[3] ) || Intersects( corners[3], corners[0] ) )
442 {
443 return true;
444 }
445
446 return false;
447 }
448
452 bool IntersectsCircle( const Vec& aCenter, const int aRadius ) const
453 {
454 if( !m_init )
455 return false;
456
457 Vec closest = ClosestPointTo( aCenter );
458
459 double dx = static_cast<double>( aCenter.x ) - closest.x;
460 double dy = static_cast<double>( aCenter.y ) - closest.y;
461
462 double r = static_cast<double>( aRadius );
463
464 return ( dx * dx + dy * dy ) <= ( r * r );
465 }
466
471 bool IntersectsCircleEdge( const Vec& aCenter, const int aRadius, const int aWidth ) const
472 {
473 if( !m_init )
474 return false;
475
476 BOX2<Vec> me( *this );
477 me.Normalize(); // ensure size is >= 0
478
479 // Test if the circle intersects at all
480 if( !IntersectsCircle( aCenter, aRadius + aWidth / 2 ) )
481 return false;
482
483 Vec farpt = FarthestPointTo( aCenter );
484 // Farthest point must be further than the inside of the line
485 double fx = (double) farpt.x - aCenter.x;
486 double fy = (double) farpt.y - aCenter.y;
487
488 double r = (double) aRadius - (double) aWidth / 2;
489
490 return ( fx * fx + fy * fy ) > ( r * r );
491 }
492
493 const std::string Format() const
494 {
495 std::stringstream ss;
496
497 ss << "( box corner " << m_Pos.Format() << " w " << m_Size.x << " h " << m_Size.y << " )";
498
499 return ss.str();
500 }
501
507 {
508 if( m_Size.x >= 0 )
509 {
510 if( m_Size.x < -2 * dx )
511 {
512 // Don't allow deflate to eat more width than we have,
513 m_Pos.x += m_Size.x / 2;
514 m_Size.x = 0;
515 }
516 else
517 {
518 // The inflate is valid.
519 m_Pos.x -= dx;
520 m_Size.x += 2 * dx;
521 }
522 }
523 else // size.x < 0:
524 {
525 if( m_Size.x > 2 * dx )
526 {
527 // Don't allow deflate to eat more width than we have,
528 m_Pos.x -= m_Size.x / 2;
529 m_Size.x = 0;
530 }
531 else
532 {
533 // The inflate is valid.
534 m_Pos.x += dx;
535 m_Size.x -= 2 * dx; // m_Size.x <0: inflate when dx > 0
536 }
537 }
538
539 if( m_Size.y >= 0 )
540 {
541 if( m_Size.y < -2 * dy )
542 {
543 // Don't allow deflate to eat more height than we have,
544 m_Pos.y += m_Size.y / 2;
545 m_Size.y = 0;
546 }
547 else
548 {
549 // The inflate is valid.
550 m_Pos.y -= dy;
551 m_Size.y += 2 * dy;
552 }
553 }
554 else // size.y < 0:
555 {
556 if( m_Size.y > 2 * dy )
557 {
558 // Don't allow deflate to eat more height than we have,
559 m_Pos.y -= m_Size.y / 2;
560 m_Size.y = 0;
561 }
562 else
563 {
564 // The inflate is valid.
565 m_Pos.y += dy;
566 m_Size.y -= 2 * dy; // m_Size.y <0: inflate when dy > 0
567 }
568 }
569
570 return *this;
571 }
572
577 BOX2<Vec>& Inflate( int aDelta )
578 {
579 Inflate( aDelta, aDelta );
580 return *this;
581 }
582
588 BOX2<Vec>& Merge( const BOX2<Vec>& aRect )
589 {
590 if( !m_init )
591 {
592 if( aRect.m_init )
593 {
594 m_Pos = aRect.GetPosition();
595 m_Size = aRect.GetSize();
596 m_init = true;
597 }
598
599 return *this;
600 }
601
602 Normalize(); // ensure width and height >= 0
603 BOX2<Vec> rect = aRect;
604 rect.Normalize(); // ensure width and height >= 0
605 Vec end = GetEnd();
606 Vec rect_end = rect.GetEnd();
607
608 // Change origin and size in order to contain the given rect
609 m_Pos.x = std::min( m_Pos.x, rect.m_Pos.x );
610 m_Pos.y = std::min( m_Pos.y, rect.m_Pos.y );
611 end.x = std::max( end.x, rect_end.x );
612 end.y = std::max( end.y, rect_end.y );
613 SetEnd( end );
614 return *this;
615 }
616
622 BOX2<Vec>& Merge( const Vec& aPoint )
623 {
624 if( !m_init )
625 {
626 m_Pos = aPoint;
627 m_Size = VECTOR2I( 0, 0 );
628 m_init = true;
629 return *this;
630 }
631
632 Normalize(); // ensure width and height >= 0
633
634 Vec end = GetEnd();
635
636 // Change origin and size in order to contain the given rectangle.
637 m_Pos.x = std::min( m_Pos.x, aPoint.x );
638 m_Pos.y = std::min( m_Pos.y, aPoint.y );
639 end.x = std::max( end.x, aPoint.x );
640 end.y = std::max( end.y, aPoint.y );
641 SetEnd( end );
642 return *this;
643 }
644
650 const BOX2<Vec> GetBoundingBoxRotated( const VECTOR2I& aRotCenter,
651 const EDA_ANGLE& aAngle ) const
652 {
653 VECTOR2I corners[4];
654
655 // Build the corners list
656 corners[0] = GetOrigin();
657 corners[2] = GetEnd();
658 corners[1].x = corners[0].x;
659 corners[1].y = corners[2].y;
660 corners[3].x = corners[2].x;
661 corners[3].y = corners[0].y;
662
663 // Rotate all corners, to find the bounding box
664 for( int ii = 0; ii < 4; ii++ )
665 RotatePoint( corners[ii], aRotCenter, aAngle );
666
667 // Find the corners bounding box
668 VECTOR2I start = corners[0];
669 VECTOR2I end = corners[0];
670
671 for( int ii = 1; ii < 4; ii++ )
672 {
673 start.x = std::min( start.x, corners[ii].x );
674 start.y = std::min( start.y, corners[ii].y );
675 end.x = std::max( end.x, corners[ii].x );
676 end.y = std::max( end.y, corners[ii].y );
677 }
678
679 BOX2<Vec> bbox;
680 bbox.SetOrigin( start );
681 bbox.SetEnd( end );
682
683 return bbox;
684 }
685
690 {
691 m_Pos.y = -m_Pos.y;
692 m_Size.y = -m_Size.y;
693 Normalize();
694 }
695
702 {
703 return (ecoord_type) GetWidth() * (ecoord_type) GetHeight();
704 }
705
712 {
713 return m_Size.EuclideanNorm();
714 }
715
716 ecoord_type SquaredDistance( const Vec& aP ) const
717 {
718 ecoord_type x2 = m_Pos.x + m_Size.x;
719 ecoord_type y2 = m_Pos.y + m_Size.y;
720 ecoord_type xdiff = std::max( aP.x < m_Pos.x ? m_Pos.x - aP.x : m_Pos.x - x2,
721 (ecoord_type) 0 );
722 ecoord_type ydiff = std::max( aP.y < m_Pos.y ? m_Pos.y - aP.y : m_Pos.y - y2,
723 (ecoord_type) 0 );
724 return xdiff * xdiff + ydiff * ydiff;
725 }
726
727 ecoord_type Distance( const Vec& aP ) const
728 {
729 return sqrt( SquaredDistance( aP ) );
730 }
731
739 {
740 ecoord_type s = 0;
741
742 if( aBox.m_Pos.x + aBox.m_Size.x < m_Pos.x )
743 {
744 ecoord_type d = aBox.m_Pos.x + aBox.m_Size.x - m_Pos.x;
745 s += d * d;
746 }
747 else if( aBox.m_Pos.x > m_Pos.x + m_Size.x )
748 {
749 ecoord_type d = aBox.m_Pos.x - m_Size.x - m_Pos.x;
750 s += d * d;
751 }
752
753 if( aBox.m_Pos.y + aBox.m_Size.y < m_Pos.y )
754 {
755 ecoord_type d = aBox.m_Pos.y + aBox.m_Size.y - m_Pos.y;
756 s += d * d;
757 }
758 else if( aBox.m_Pos.y > m_Pos.y + m_Size.y )
759 {
760 ecoord_type d = aBox.m_Pos.y - m_Size.y - m_Pos.y;
761 s += d * d;
762 }
763
764 return s;
765 }
766
773 ecoord_type Distance( const BOX2<Vec>& aBox ) const
774 {
775 return sqrt( SquaredDistance( aBox ) );
776 }
777
781 const Vec ClosestPointTo( const Vec& aPoint ) const
782 {
783 BOX2<Vec> me( *this );
784
785 me.Normalize(); // ensure size is >= 0
786
787 // Determine closest point to the circle centre within this rect
788 coord_type nx = std::max( me.GetLeft(), std::min( aPoint.x, me.GetRight() ) );
789 coord_type ny = std::max( me.GetTop(), std::min( aPoint.y, me.GetBottom() ) );
790
791 return Vec( nx, ny );
792 }
793
797 const Vec FarthestPointTo( const Vec& aPoint ) const
798 {
799 BOX2<Vec> me( *this );
800
801 me.Normalize(); // ensure size is >= 0
802
803 coord_type fx;
804 coord_type fy;
805
806 Vec center = me.GetCenter();
807
808 if( aPoint.x < center.x )
809 fx = me.GetRight();
810 else
811 fx = me.GetLeft();
812
813 if( aPoint.y < center.y )
814 fy = me.GetBottom();
815 else
816 fy = me.GetTop();
817
818 return Vec( fx, fy );
819 }
820
821 bool operator==( const BOX2<Vec>& aOther ) const
822 {
823 auto t1 ( *this );
824 auto t2 ( aOther );
825 t1.Normalize();
826 t2.Normalize();
827 return ( t1.m_Pos == t2.m_Pos && t1.m_Size == t2.m_Size );
828 }
829
830 bool operator!=( const BOX2<Vec>& aOther ) const
831 {
832 auto t1 ( *this );
833 auto t2 ( aOther );
834 t1.Normalize();
835 t2.Normalize();
836 return ( t1.m_Pos != t2.m_Pos || t1.m_Size != t2.m_Size );
837 }
838
839private:
840 Vec m_Pos; // Rectangle Origin
841 Vec m_Size; // Rectangle Size
842
843 bool m_init; // Is the rectangle initialized
844};
845
846/* Default specializations */
849
850typedef std::optional<BOX2I> OPT_BOX2I;
851
852
853#endif
BOX2< VECTOR2I > BOX2I
Definition: box2.h:847
std::optional< BOX2I > OPT_BOX2I
Definition: box2.h:850
BOX2< VECTOR2D > BOX2D
Definition: box2.h:848
A 2D bounding box built on top of an origin point and size vector.
Definition: box2.h:43
ecoord_type SquaredDistance(const BOX2< Vec > &aBox) const
Return the square of the minimum distance between self and box aBox.
Definition: box2.h:738
void SetOrigin(const Vec &pos)
Definition: box2.h:202
BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
Definition: box2.h:119
bool m_init
Definition: box2.h:843
bool operator==(const BOX2< Vec > &aOther) const
Definition: box2.h:821
Vec m_Size
Definition: box2.h:841
const Vec & GetPosition() const
Definition: box2.h:184
int GetSizeMax() const
Definition: box2.h:200
ecoord_type Distance(const BOX2< Vec > &aBox) const
Return the minimum distance between self and aBox.
Definition: box2.h:773
const Vec & GetOrigin() const
Definition: box2.h:183
void Offset(coord_type dx, coord_type dy)
Definition: box2.h:224
const std::string Format() const
Definition: box2.h:493
void SetMaximum()
Definition: box2.h:63
bool Intersects(const BOX2< Vec > &aRect, const EDA_ANGLE &aRotation) const
Definition: box2.h:352
BOX2< Vec > Intersect(const BOX2< Vec > &aRect)
Definition: box2.h:300
ecoord_type Diagonal() const
Return the length of the diagonal of the rectangle.
Definition: box2.h:711
void SetSize(coord_type w, coord_type h)
Definition: box2.h:219
bool Intersects(const Vec &aPoint1, const Vec &aPoint2) const
Definition: box2.h:323
void RevertYAxis()
Mirror the rectangle from the X axis (negate Y pos and size).
Definition: box2.h:689
BOX2(const Vec &aPos, const Vec &aSize=Vec(0, 0))
Definition: box2.h:55
bool Contains(coord_type x, coord_type y) const
Definition: box2.h:167
Vec m_Pos
Definition: box2.h:840
void SetX(coord_type val)
Definition: box2.h:235
BOX2< Vec > & Inflate(int aDelta)
Inflate the rectangle horizontally and vertically by aDelta.
Definition: box2.h:577
BOX2< Vec > & Merge(const Vec &aPoint)
Modify the position and size of the rectangle in order to contain the given point.
Definition: box2.h:622
const Vec FarthestPointTo(const Vec &aPoint) const
Return the point in this rect that is farthest from the provided point.
Definition: box2.h:797
bool operator!=(const BOX2< Vec > &aOther) const
Definition: box2.h:830
const Vec GetCenter() const
Definition: box2.h:195
bool Intersects(const BOX2< Vec > &aRect) const
Definition: box2.h:269
void SetY(coord_type val)
Definition: box2.h:240
bool Contains(const BOX2< Vec > &aRect) const
Definition: box2.h:174
Vec::extended_type ecoord_type
Definition: box2.h:46
bool IntersectsCircleEdge(const Vec &aCenter, const int aRadius, const int aWidth) const
Definition: box2.h:471
coord_type GetTop() const
Definition: box2.h:194
bool IntersectsCircle(const Vec &aCenter, const int aRadius) const
Definition: box2.h:452
coord_type GetHeight() const
Definition: box2.h:188
coord_type GetY() const
Definition: box2.h:181
ecoord_type SquaredDistance(const Vec &aP) const
Definition: box2.h:716
void Offset(const Vec &offset)
Definition: box2.h:230
coord_type GetWidth() const
Definition: box2.h:187
void SetWidth(coord_type val)
Definition: box2.h:245
const Vec GetEnd() const
Definition: box2.h:185
void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
Definition: box2.h:111
std::numeric_limits< coord_type > coord_limits
Definition: box2.h:47
void SetEnd(const Vec &pos)
Definition: box2.h:260
const Vec ClosestPointTo(const Vec &aPoint) const
Return the point in this rect that is closest to the provided point.
Definition: box2.h:781
Vec::coord_type coord_type
Definition: box2.h:45
void SetSize(const Vec &size)
Definition: box2.h:213
bool Contains(const Vec &aPoint) const
Definition: box2.h:141
void SetOrigin(coord_type x, coord_type y)
Definition: box2.h:208
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
Definition: box2.h:506
ecoord_type Distance(const Vec &aP) const
Definition: box2.h:727
coord_type GetX() const
Definition: box2.h:180
Vec Centre() const
Definition: box2.h:70
coord_type GetRight() const
Definition: box2.h:189
ecoord_type GetArea() const
Return the area of the rectangle.
Definition: box2.h:701
coord_type GetLeft() const
Definition: box2.h:193
const Vec & GetSize() const
Definition: box2.h:179
const BOX2< Vec > GetBoundingBoxRotated(const VECTOR2I &aRotCenter, const EDA_ANGLE &aAngle) const
Useful to calculate bounding box of rotated items, when rotation is not cardinal.
Definition: box2.h:650
void SetHeight(coord_type val)
Definition: box2.h:250
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
Definition: box2.h:82
coord_type GetBottom() const
Definition: box2.h:190
void SetEnd(coord_type x, coord_type y)
Definition: box2.h:255
BOX2()
Definition: box2.h:49
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Definition: box2.h:588
EDA_ANGLE Normalize()
Definition: eda_angle.h:249
static constexpr EDA_ANGLE & ANGLE_180
Definition: eda_angle.h:433
@ DEGREES_T
Definition: eda_angle.h:31
static constexpr EDA_ANGLE & ANGLE_360
Definition: eda_angle.h:435
static constexpr EDA_ANGLE & ANGLE_90
Definition: eda_angle.h:431
static constexpr EDA_ANGLE & ANGLE_0
Definition: eda_angle.h:429
static constexpr EDA_ANGLE & ANGLE_270
Definition: eda_angle.h:434
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
Definition: eda_angle.h:418
constexpr int delta
void RotatePoint(int *pX, int *pY, const EDA_ANGLE &aAngle)
Definition: trigo.cpp:183
bool SegmentIntersectsSegment(const VECTOR2I &a_p1_l1, const VECTOR2I &a_p2_l1, const VECTOR2I &a_p1_l2, const VECTOR2I &a_p2_l2, VECTOR2I *aIntersectionPoint=nullptr)
Test if two lines intersect.
Definition: trigo.cpp:61
VECTOR2< int > VECTOR2I
Definition: vector2d.h:588