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