69 return BOX2( aCorner1, aCorner2 - aCorner1 );
74 return BOX2( aCenter - aSize / 2, aSize );
79 if constexpr( std::is_floating_point<coord_type>() )
81 m_Pos.x =
m_Pos.y = coord_limits::lowest() / 2.0;
105 template <
class Container>
110 typename Container::const_iterator i;
112 if( !aPointList.size() )
115 vmin = vmax = aPointList[0];
117 for( i = aPointList.begin(); i != aPointList.end(); ++i )
120 vmin.x = std::min( vmin.x, p.x );
121 vmin.y = std::min( vmin.y, p.y );
122 vmax.x = std::max( vmax.x, p.x );
123 vmax.y = std::max( vmax.y, p.y );
135 constexpr void Move(
const Vec& aMoveVector )
137 m_Pos += aMoveVector;
167 Vec rel_pos = aPoint -
m_Pos;
182 return ( rel_pos.x >= 0 ) && ( rel_pos.y >= 0 ) && ( rel_pos.y <= size.y) &&
183 ( rel_pos.x <= size.x);
262 constexpr void Offset(
const Vec& offset )
264 Offset( offset.x, offset.y );
270 ret.
Move( aMoveVector );
351 Vec topLeft, bottomRight;
353 topLeft.x = std::max( me.
m_Pos.x, rect.
m_Pos.x );
357 topLeft.y = std::max( me.
m_Pos.y, rect.
m_Pos.y );
361 if( topLeft.x < bottomRight.x && topLeft.y < bottomRight.y )
370 bool Intersects(
const Vec& aPoint1,
const Vec& aPoint2 )
const
421 if(
std::abs( rotation - ii ) < ROT_EPSILON )
428 if(
std::abs( rotation - jj ) < ROT_EPSILON )
456 for(
int i = 0; i < 4; i++ )
477 for(
int j = 0; j < 4; j++ )
480 corners[j] += rCentre;
506 double dx =
static_cast<double>( aCenter.x ) - closest.x;
507 double dy =
static_cast<double>( aCenter.y ) - closest.y;
509 double r =
static_cast<double>( aRadius );
511 return ( dx * dx + dy * dy ) <= ( r * r );
532 double fx = (double) farpt.x - aCenter.x;
533 double fy = (double) farpt.y - aCenter.y;
535 double r = (double) aRadius - (
double) aWidth / 2;
537 return ( fx * fx + fy * fy ) > ( r * r );
542 std::stringstream ss;
544 ss <<
"( box corner " <<
m_Pos.Format() <<
" w " <<
m_Size.x <<
" h " <<
m_Size.y <<
" )";
671 Vec rect_end = rect.
GetEnd();
676 end.x = std::max(
end.x, rect_end.x );
677 end.y = std::max(
end.y, rect_end.y );
704 end.x = std::max(
end.x, aPoint.x );
705 end.y = std::max(
end.y, aPoint.y );
723 corners[1].
x = corners[0].
x;
724 corners[1].
y = corners[2].
y;
725 corners[3].
x = corners[2].
x;
726 corners[3].
y = corners[0].
y;
729 for(
int ii = 0; ii < 4; ii++ )
736 for(
int ii = 1; ii < 4; ii++ )
738 start.
x = std::min( start.
x, corners[ii].
x );
739 start.
y = std::min( start.
y, corners[ii].
y );
740 end.x = std::max(
end.x, corners[ii].
x );
741 end.y = std::max(
end.y, corners[ii].
y );
768 return m_Size.EuclideanNorm();
778 return m_Size.SquaredEuclideanNorm();
789 return xdiff * xdiff + ydiff * ydiff;
794 const double dist = std::sqrt(
static_cast<double>(
SquaredDistance( aP ) ) );
796 if constexpr( std::is_floating_point<ecoord_type>() )
845 const double dist = std::sqrt(
static_cast<double>(
SquaredDistance( aBox ) ) );
847 if constexpr( std::is_floating_point<ecoord_type>() )
866 return Vec( nx, ny );
893 return Vec( fx, fy );
902 return ( t1.m_Pos == t2.m_Pos && t1.m_Size == t2.m_Size );
911 return ( t1.m_Pos != t2.m_Pos || t1.m_Size != t2.m_Size );
936 constexpr double high = std::numeric_limits<int>::max();
937 constexpr double low = -std::numeric_limits<int>::max();
939 int left = (int) std::clamp( aInput.
GetLeft(), low, high );
940 int top = (int) std::clamp( aInput.
GetTop(), low, high );
942 int64_t
right = (int64_t) std::clamp( aInput.
GetRight(), low, high );
943 int64_t bottom = (int64_t) std::clamp( aInput.
GetBottom(), low, high );
953template <
typename Vec>
956 constexpr double high = std::numeric_limits<int>::max();
957 constexpr double low = -std::numeric_limits<int>::max();
959 return ( aInput.
GetLeft() >= low && aInput.
GetTop() >= low &&
966 constexpr double high = std::numeric_limits<int>::max();
967 constexpr double low = -std::numeric_limits<int>::max();
969 int left = (int) std::clamp( aPos.
x, low, high );
970 int top = (int) std::clamp( aPos.
y, low, high );
972 int64_t
right = (int64_t) std::clamp( aPos.
x + aSize.
x, low, high );
973 int64_t bottom = (int64_t) std::clamp( aPos.
y + aSize.
y, low, high );
979template <typename S, std::enable_if_t<std::is_integral<S>::value,
int> = 0>
982 constexpr int64_t high = std::numeric_limits<int>::max();
983 constexpr int64_t low = -std::numeric_limits<int>::max();
985 int64_t ext_right = int64_t( aPos.
x ) + aSize.
x;
986 int64_t ext_bottom = int64_t( aPos.
y ) + aSize.
y;
988 int64_t
right = std::clamp( ext_right, low, high );
989 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.
constexpr Vec NearestPoint(const Vec &aPoint) const
Return the point in this rect that is closest to the provided point.
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 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.
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)
KIBIS top(path, &reporter)
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.
constexpr ret_type KiCheckedCast(in_type v)
Perform a cast between numerical types.
VECTOR2< int32_t > VECTOR2I
VECTOR2< double > VECTOR2D
VECTOR2< int64_t > VECTOR2L