72 if constexpr( std::is_floating_point<coord_type>() )
74 m_Pos.x =
m_Pos.y = coord_limits::lowest() / 2.0;
98 template <
class Container>
99 void Compute(
const Container& aPointList )
103 typename Container::const_iterator i;
105 if( !aPointList.size() )
108 vmin = vmax = aPointList[0];
110 for( i = aPointList.begin(); i != aPointList.end(); ++i )
113 vmin.x = std::min( vmin.x, p.x );
114 vmin.y = std::min( vmin.y, p.y );
115 vmax.x = std::max( vmax.x, p.x );
116 vmax.y = std::max( vmax.y, p.y );
128 void Move(
const Vec& aMoveVector )
130 m_Pos += aMoveVector;
160 Vec rel_pos = aPoint -
m_Pos;
175 return ( rel_pos.x >= 0 ) && ( rel_pos.y >= 0 ) && ( rel_pos.y <= size.y) &&
176 ( rel_pos.x <= size.x);
257 Offset( offset.x, offset.y );
337 Vec topLeft, bottomRight;
339 topLeft.x = std::max( me.
m_Pos.x, rect.
m_Pos.x );
344 topLeft.y = std::max( me.
m_Pos.y, rect.
m_Pos.y );
349 if( topLeft.x < bottomRight.x && topLeft.y < bottomRight.y )
358 bool Intersects(
const Vec& aPoint1,
const Vec& aPoint2 )
const
409 if(
std::abs( rotation - ii ) < ROT_EPSILON )
416 if(
std::abs( rotation - jj ) < ROT_EPSILON )
444 for(
int i = 0; i < 4; i++ )
455 int w = KiCheckedCast<ecoord_type, coord_type>( aRect.
GetWidth() / 2 );
456 int h = KiCheckedCast<ecoord_type, coord_type>( aRect.
GetHeight() / 2 );
465 for(
int j = 0; j < 4; j++ )
468 corners[j] += rCentre;
494 double dx =
static_cast<double>( aCenter.x ) - closest.x;
495 double dy =
static_cast<double>( aCenter.y ) - closest.y;
497 double r =
static_cast<double>( aRadius );
499 return ( dx * dx + dy * dy ) <= ( r * r );
520 double fx = (double) farpt.x - aCenter.x;
521 double fy = (
double) farpt.y - aCenter.y;
523 double r = (double) aRadius - (
double) aWidth / 2;
525 return ( fx * fx + fy * fy ) > ( r * r );
530 std::stringstream ss;
641 Vec rect_end = rect.
GetEnd();
646 end.x = std::max( end.x, rect_end.x );
647 end.y = std::max( end.y, rect_end.y );
674 end.x = std::max( end.x, aPoint.x );
675 end.y = std::max( end.y, aPoint.y );
693 corners[1].
x = corners[0].
x;
694 corners[1].
y = corners[2].
y;
695 corners[3].
x = corners[2].
x;
696 corners[3].
y = corners[0].
y;
699 for(
int ii = 0; ii < 4; ii++ )
706 for(
int ii = 1; ii < 4; ii++ )
708 start.
x = std::min( start.
x, corners[ii].
x );
709 start.
y = std::min( start.
y, corners[ii].
y );
710 end.
x = std::max( end.
x, corners[ii].
x );
711 end.
y = std::max( end.
y, corners[ii].
y );
749 return xdiff * xdiff + ydiff * ydiff;
816 return Vec( nx, ny );
833 if( aPoint.x < center.x )
838 if( aPoint.y < center.y )
843 return Vec( fx, fy );
852 return ( t1.m_Pos == t2.m_Pos && t1.m_Size == t2.m_Size );
861 return ( t1.m_Pos != t2.m_Pos || t1.m_Size != t2.m_Size );
885 constexpr double high = std::numeric_limits<int>::max();
886 constexpr double low = -std::numeric_limits<int>::max();
888 int left = (int) std::clamp( aInput.
GetLeft(), low, high );
889 int top = (int) std::clamp( aInput.
GetTop(), low, high );
891 int64_t
right = (int64_t) std::clamp( aInput.
GetRight(), low, high );
892 int64_t bottom = (int64_t) std::clamp( aInput.
GetBottom(), low, high );
900 constexpr double high = std::numeric_limits<int>::max();
901 constexpr double low = -std::numeric_limits<int>::max();
903 int left = (int) std::clamp( aPos.
x, low, high );
904 int top = (int) std::clamp( aPos.
y, low, high );
906 int64_t
right = (int64_t) std::clamp( aPos.
x + aSize.
x, low, high );
907 int64_t bottom = (int64_t) std::clamp( aPos.
y + aSize.
y, low, high );
913template <typename S, std::enable_if_t<std::is_integral<S>::value,
int> = 0>
916 constexpr int64_t high = std::numeric_limits<int>::max();
917 constexpr int64_t low = -std::numeric_limits<int>::max();
919 int64_t ext_right = int64_t( aPos.
x ) + aSize.
x;
920 int64_t ext_bottom = int64_t( aPos.
y ) + aSize.
y;
922 int64_t
right = std::clamp( ext_right, low, high );
923 int64_t bottom = std::clamp( ext_bottom, low, high );
std::optional< BOX2I > OPT_BOX2I
BOX2I BOX2ISafe(const BOX2D &aInput)
A 2D bounding box built on top of an origin point and size vector.
ecoord_type SquaredDistance(const BOX2< Vec > &aBox) const
Return the square of the minimum distance between self and box aBox.
void SetOrigin(const Vec &pos)
BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
bool operator==(const BOX2< Vec > &aOther) const
Vec::extended_type size_type
void SetSize(const SizeVec &size)
const Vec & GetPosition() const
ecoord_type Distance(const BOX2< Vec > &aBox) const
Return the minimum distance between self and aBox.
const Vec & GetOrigin() const
void Offset(coord_type dx, coord_type dy)
const std::string Format() const
const SizeVec & GetSize() const
bool Intersects(const BOX2< Vec > &aRect, const EDA_ANGLE &aRotation) const
BOX2< Vec > Intersect(const BOX2< Vec > &aRect)
ecoord_type Diagonal() const
Return the length of the diagonal of the rectangle.
void SetSize(size_type w, size_type h)
bool Intersects(const Vec &aPoint1, const Vec &aPoint2) const
void SetHeight(size_type val)
bool Contains(coord_type x, coord_type y) const
size_type GetHeight() const
void SetX(coord_type val)
BOX2< Vec > & Inflate(int aDelta)
Inflate the rectangle horizontally and vertically by aDelta.
BOX2< Vec > & Merge(const Vec &aPoint)
Modify the position and size of the rectangle in order to contain the given point.
const Vec FarthestPointTo(const Vec &aPoint) const
Return the point in this rect that is farthest from the provided point.
bool operator!=(const BOX2< Vec > &aOther) const
const Vec GetCenter() const
bool Intersects(const BOX2< Vec > &aRect) const
void SetWidth(size_type val)
void SetY(coord_type val)
bool Contains(const BOX2< Vec > &aRect) const
Vec::extended_type ecoord_type
bool IntersectsCircleEdge(const Vec &aCenter, const int aRadius, const int aWidth) const
coord_type GetTop() const
bool IntersectsCircle(const Vec &aCenter, const int aRadius) const
VECTOR2< size_type > SizeVec
size_type GetWidth() const
ecoord_type SquaredDistance(const Vec &aP) const
void Offset(const Vec &offset)
void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
std::numeric_limits< coord_type > coord_limits
void SetEnd(const Vec &pos)
const Vec ClosestPointTo(const Vec &aPoint) const
Return the point in this rect that is closest to the provided point.
Vec::coord_type coord_type
bool Contains(const Vec &aPoint) const
void SetOrigin(coord_type x, coord_type y)
BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
ecoord_type Distance(const Vec &aP) const
coord_type GetRight() const
ecoord_type GetArea() const
Return the area of the rectangle.
BOX2(const Vec &aPos, const SizeVec &aSize=SizeVec(0, 0))
coord_type GetLeft() const
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.
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
coord_type GetBottom() const
void SetEnd(coord_type x, coord_type y)
BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
Define a general 2D-vector/point.
T EuclideanNorm() const
Compute the Euclidean norm of the vector, which is defined as sqrt(x ** 2 + y ** 2).
static constexpr EDA_ANGLE ANGLE_0
static constexpr EDA_ANGLE ANGLE_90
static constexpr EDA_ANGLE ANGLE_270
static constexpr EDA_ANGLE ANGLE_360
static constexpr EDA_ANGLE ANGLE_180
T clamp(T min, T value, T max)
EDA_ANGLE abs(const EDA_ANGLE &aAngle)
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.
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.
VECTOR2< long long int > VECTOR2L