72 return BOX2( aCorner1, aCorner2 - aCorner1 );
77 return BOX2( aCenter - aSize / 2, aSize );
82 if constexpr( std::is_floating_point<coord_type>() )
84 m_Pos.x =
m_Pos.y = coord_limits::lowest() / 2.0;
108 template <
class Container>
113 typename Container::const_iterator i;
115 if( !aPointList.size() )
118 vmin = vmax = aPointList[0];
120 for( i = aPointList.begin(); i != aPointList.end(); ++i )
123 vmin.x = std::min( vmin.x, p.x );
124 vmin.y = std::min( vmin.y, p.y );
125 vmax.x = std::max( vmax.x, p.x );
126 vmax.y = std::max( vmax.y, p.y );
138 constexpr void Move(
const Vec& aMoveVector )
140 m_Pos += aMoveVector;
170 Vec rel_pos = aPoint -
m_Pos;
185 return ( rel_pos.x >= 0 ) && ( rel_pos.y >= 0 ) && ( rel_pos.y <= size.y) &&
186 ( rel_pos.x <= size.x);
265 constexpr void Offset(
const Vec& offset )
267 Offset( offset.x, offset.y );
273 ret.
Move( aMoveVector );
354 Vec topLeft, bottomRight;
356 topLeft.x = std::max( me.
m_Pos.x, rect.
m_Pos.x );
361 topLeft.y = std::max( me.
m_Pos.y, rect.
m_Pos.y );
366 if( topLeft.x < bottomRight.x && topLeft.y < bottomRight.y )
375 bool Intersects(
const Vec& aPoint1,
const Vec& aPoint2 )
const
426 if(
std::abs( rotation - ii ) < ROT_EPSILON )
433 if(
std::abs( rotation - jj ) < ROT_EPSILON )
461 for(
int i = 0; i < 4; i++ )
472 int w = KiCheckedCast<ecoord_type, coord_type>( aRect.
GetWidth() / 2 );
473 int h = KiCheckedCast<ecoord_type, coord_type>( aRect.
GetHeight() / 2 );
482 for(
int j = 0; j < 4; j++ )
485 corners[j] += rCentre;
511 double dx =
static_cast<double>( aCenter.x ) - closest.x;
512 double dy =
static_cast<double>( aCenter.y ) - closest.y;
514 double r =
static_cast<double>( aRadius );
516 return ( dx * dx + dy * dy ) <= ( r * r );
537 double fx = (double) farpt.x - aCenter.x;
538 double fy = (
double) farpt.y - aCenter.y;
540 double r = (double) aRadius - (
double) aWidth / 2;
542 return ( fx * fx + fy * fy ) > ( r * r );
547 std::stringstream ss;
676 Vec rect_end = rect.
GetEnd();
681 end.x = std::max( end.x, rect_end.x );
682 end.y = std::max( end.y, rect_end.y );
709 end.x = std::max( end.x, aPoint.x );
710 end.y = std::max( end.y, aPoint.y );
728 corners[1].
x = corners[0].
x;
729 corners[1].
y = corners[2].
y;
730 corners[3].
x = corners[2].
x;
731 corners[3].
y = corners[0].
y;
734 for(
int ii = 0; ii < 4; ii++ )
741 for(
int ii = 1; ii < 4; ii++ )
743 start.
x = std::min( start.
x, corners[ii].
x );
744 start.
y = std::min( start.
y, corners[ii].
y );
745 end.
x = std::max( end.
x, corners[ii].
x );
746 end.
y = std::max( end.
y, corners[ii].
y );
794 return xdiff * xdiff + ydiff * ydiff;
861 return Vec( nx, ny );
878 if( aPoint.x < center.x )
883 if( aPoint.y < center.y )
888 return Vec( fx, fy );
897 return ( t1.m_Pos == t2.m_Pos && t1.m_Size == t2.m_Size );
906 return ( t1.m_Pos != t2.m_Pos || t1.m_Size != t2.m_Size );
931 constexpr double high = std::numeric_limits<int>::max();
932 constexpr double low = -std::numeric_limits<int>::max();
934 int left = (int) std::clamp( aInput.
GetLeft(), low, high );
935 int top = (int) std::clamp( aInput.
GetTop(), low, high );
937 int64_t
right = (int64_t) std::clamp( aInput.
GetRight(), low, high );
938 int64_t bottom = (int64_t) std::clamp( aInput.
GetBottom(), low, high );
948template <
typename Vec>
951 constexpr double high = std::numeric_limits<int>::max();
952 constexpr double low = -std::numeric_limits<int>::max();
954 return ( aInput.
GetLeft() >= low && aInput.
GetTop() >= low &&
961 constexpr double high = std::numeric_limits<int>::max();
962 constexpr double low = -std::numeric_limits<int>::max();
964 int left = (int) std::clamp( aPos.
x, low, high );
965 int top = (int) std::clamp( aPos.
y, low, high );
967 int64_t
right = (int64_t) std::clamp( aPos.
x + aSize.
x, low, high );
968 int64_t bottom = (int64_t) std::clamp( aPos.
y + aSize.
y, low, high );
974template <typename S, std::enable_if_t<std::is_integral<S>::value,
int> = 0>
977 constexpr int64_t high = std::numeric_limits<int>::max();
978 constexpr int64_t low = -std::numeric_limits<int>::max();
980 int64_t ext_right = int64_t( aPos.
x ) + aSize.
x;
981 int64_t ext_bottom = int64_t( aPos.
y ) + aSize.
y;
983 int64_t
right = std::clamp( ext_right, low, high );
984 int64_t bottom = std::clamp( ext_bottom, low, high );
constexpr bool IsBOX2Safe(const BOX2< Vec > &aInput)
Check if a BOX2 is safe for use with BOX2D (probably BOX2D or BOX2L)
constexpr BOX2I BOX2ISafe(const BOX2D &aInput)
std::optional< BOX2I > OPT_BOX2I
constexpr BOX2I KiROUND(const BOX2D &aBoxD)
A 2D bounding box built on top of an origin point and size vector.
constexpr BOX2< Vec > Intersect(const BOX2< Vec > &aRect)
constexpr ecoord_type SquaredDistance(const BOX2< Vec > &aBox) const
Return the square of the minimum distance between self and box aBox.
constexpr const Vec & GetPosition() const
constexpr int GetSizeMax() const
constexpr void SetMaximum()
Vec::extended_type size_type
constexpr BOX2< Vec > & Inflate(coord_type dx, coord_type dy)
Inflates the rectangle horizontally by dx and vertically by dy.
static constexpr BOX2< Vec > ByCorners(const Vec &aCorner1, const Vec &aCorner2)
constexpr bool operator==(const BOX2< Vec > &aOther) const
ecoord_type Distance(const BOX2< Vec > &aBox) const
Return the minimum distance between self and aBox.
constexpr void SetHeight(size_type val)
const std::string Format() const
constexpr BOX2< Vec > & Inflate(coord_type aDelta)
Inflate the rectangle horizontally and vertically by aDelta.
constexpr const Vec GetEnd() const
constexpr void SetOrigin(const Vec &pos)
bool Intersects(const BOX2< Vec > &aRect, const EDA_ANGLE &aRotation) const
constexpr ecoord_type SquaredDiagonal() const
Return the square of the length of the diagonal of the rectangle.
constexpr BOX2< Vec > & Normalize()
Ensure that the height and width are positive.
ecoord_type Diagonal() const
Return the length of the diagonal of the rectangle.
constexpr coord_type GetY() const
bool Intersects(const Vec &aPoint1, const Vec &aPoint2) const
static constexpr BOX2< Vec > ByCenter(const Vec &aCenter, const SizeVec &aSize)
constexpr Vec ClosestPointTo(const Vec &aPoint) const
Return the point in this rect that is closest to the provided point.
constexpr bool operator!=(const BOX2< Vec > &aOther) const
constexpr void SetSize(size_type w, size_type h)
constexpr size_type GetWidth() const
constexpr Vec Centre() const
Vec::extended_type ecoord_type
constexpr coord_type GetX() const
constexpr void SetEnd(const Vec &pos)
bool IntersectsCircleEdge(const Vec &aCenter, const int aRadius, const int aWidth) const
constexpr BOX2< Vec > & Merge(const BOX2< Vec > &aRect)
Modify the position and size of the rectangle in order to contain aRect.
bool IntersectsCircle(const Vec &aCenter, const int aRadius) const
constexpr BOX2(const Vec &aPos, const SizeVec &aSize=SizeVec(0, 0))
VECTOR2< size_type > SizeVec
constexpr ecoord_type GetArea() const
Return the area of the rectangle.
constexpr const Vec GetCenter() const
constexpr void SetSize(const SizeVec &size)
std::numeric_limits< coord_type > coord_limits
constexpr void Offset(const Vec &offset)
constexpr size_type GetHeight() const
constexpr coord_type GetLeft() const
constexpr bool Contains(const Vec &aPoint) const
constexpr void SetOrigin(coord_type x, coord_type y)
constexpr void SetWidth(size_type val)
constexpr bool Contains(const BOX2< Vec > &aRect) const
Vec::coord_type coord_type
constexpr void Move(const Vec &aMoveVector)
Move the rectangle by the aMoveVector.
constexpr BOX2< Vec > GetInflated(coord_type aDelta) const
Get a new rectangle that is this one, inflated by aDelta.
ecoord_type Distance(const Vec &aP) const
constexpr BOX2< Vec > GetWithOffset(const Vec &aMoveVector) const
constexpr void SetX(coord_type val)
constexpr bool Contains(coord_type x, coord_type y) const
constexpr ecoord_type SquaredDistance(const Vec &aP) const
constexpr BOX2< Vec > GetInflated(coord_type aDx, coord_type aDy) const
Get a new rectangle that is this one, inflated by aDx and aDy.
constexpr const Vec & GetOrigin() const
constexpr void SetY(coord_type val)
constexpr bool IsValid() 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.
constexpr coord_type GetRight() const
void Compute(const Container &aPointList)
Compute the bounding box from a given list of points.
constexpr const SizeVec & GetSize() const
constexpr BOX2< Vec > & Merge(const Vec &aPoint)
Modify the position and size of the rectangle in order to contain the given point.
constexpr void SetEnd(coord_type x, coord_type y)
constexpr coord_type GetTop() const
constexpr void Offset(coord_type dx, coord_type dy)
constexpr bool Intersects(const BOX2< Vec > &aRect) const
constexpr coord_type GetBottom() const
constexpr Vec FarthestPointTo(const Vec &aPoint) const
Return the point in this rect that is farthest from the provided point.
Define a general 2D-vector/point.
constexpr extended_type SquaredEuclideanNorm() const
Compute the squared euclidean norm of the vector, which is defined as (x ** 2 + y ** 2).
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
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< int32_t > VECTOR2I
VECTOR2< int64_t > VECTOR2L