mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-04 22:19:42 +08:00
434 lines
9.9 KiB
C++
434 lines
9.9 KiB
C++
//
|
|
// Copyright (c) 1993-2017 Robert McNeel & Associates. All rights reserved.
|
|
// OpenNURBS, Rhinoceros, and Rhino3D are registered trademarks of Robert
|
|
// McNeel & Associates.
|
|
//
|
|
// THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
|
|
// ALL IMPLIED WARRANTIES OF FITNESS FOR ANY PARTICULAR PURPOSE AND OF
|
|
// MERCHANTABILITY ARE HEREBY DISCLAIMED.
|
|
//
|
|
// For complete openNURBS copyright information see <http://www.opennurbs.org>.
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
|
|
|
|
#if !defined(OPENNURBS_IPOINT_INC_)
|
|
#define OPENNURBS_IPOINT_INC_
|
|
|
|
/*
|
|
A 2 dimensional point with integer coordinates.
|
|
Clear code will distinguish between situation where (x,y) is a
|
|
location (ON_2iPoint) or a direction (ON_2iVector) and use
|
|
the appropriate class.
|
|
*/
|
|
class ON_CLASS ON_2iPoint
|
|
{
|
|
public:
|
|
// Default construction intentionally leaves x and y uninitialized.
|
|
// Use something like
|
|
// ON_2iPoint pt(1,2);
|
|
// or
|
|
// ON_2iPoint pt = ON_2iPoint::Origin;
|
|
// when you need an initialized ON_2iPoint.
|
|
ON_2iPoint() = default;
|
|
|
|
~ON_2iPoint() = default;
|
|
ON_2iPoint(const ON_2iPoint& ) = default;
|
|
ON_2iPoint& operator=(const ON_2iPoint& ) = default;
|
|
|
|
ON_2iPoint(
|
|
int x,
|
|
int y
|
|
);
|
|
|
|
public:
|
|
static const ON_2iPoint Origin; // (0,0)
|
|
static const ON_2iPoint Unset; // (ON_UNSET_INT_INDEX,ON_UNSET_INT_INDEX)
|
|
|
|
/*
|
|
Dictionary order compare.
|
|
*/
|
|
static int Compare(
|
|
const ON_2iPoint& lhs,
|
|
const ON_2iPoint& rhs
|
|
);
|
|
|
|
public:
|
|
ON_2iPoint& operator+=(const class ON_2iVector&);
|
|
ON_2iPoint& operator-=(const class ON_2iVector&);
|
|
|
|
// It is intentional that points are not added to points to encourage
|
|
// code that is clear about what is a location and what is diplacement.
|
|
|
|
public:
|
|
/*
|
|
For those times when a location was incorrectly represented by a vector.
|
|
It is intentional that ther is not an ON_2iPoint constructor from an ON_2iVector.
|
|
*/
|
|
static const ON_2iPoint FromVector(const class ON_2iVector& v);
|
|
|
|
static const ON_2iPoint From2dex(const class ON_2dex& src);
|
|
|
|
public:
|
|
/*
|
|
Returns:
|
|
(0 == x && 0 == y)
|
|
*/
|
|
bool IsOrigin() const;
|
|
|
|
/*
|
|
Returns:
|
|
(ON_UNSET_INT_INDEX == x || ON_UNSET_INT_INDEX ==y)
|
|
*/
|
|
bool IsSet() const;
|
|
|
|
public:
|
|
ON__INT32 x;
|
|
ON__INT32 y;
|
|
};
|
|
|
|
ON_DECL
|
|
bool operator==(const ON_2iPoint&, const ON_2iPoint&);
|
|
|
|
ON_DECL
|
|
bool operator!=(const ON_2iPoint&, const ON_2iPoint&);
|
|
|
|
|
|
/*
|
|
A 2 dimensional vector with integer coordinates.
|
|
Clear code will distinguish between situation where (x,y) is a
|
|
location (ON_2iPoint) or a direction (ON_2iVector) and use
|
|
the appropriate class.
|
|
*/
|
|
class ON_CLASS ON_2iVector
|
|
{
|
|
public:
|
|
// Default construction intentionally leaves x and y uninitialized.
|
|
// Use something like
|
|
// ON_2iVector pt(1,2);
|
|
// or
|
|
// ON_2iVector pt = ON_2iVector::Zero;
|
|
// when you need an initialized ON_2iVector.
|
|
ON_2iVector() = default;
|
|
|
|
~ON_2iVector() = default;
|
|
ON_2iVector(const ON_2iVector& ) = default;
|
|
ON_2iVector& operator=(const ON_2iVector& ) = default;
|
|
|
|
ON_2iVector(
|
|
int x,
|
|
int y
|
|
);
|
|
|
|
/*
|
|
For those times when a direction was incorrectly represented by a point.
|
|
It is intentional that ther is not an ON_2iVector constructor from an ON_2iPoint.
|
|
*/
|
|
static const ON_2iVector FromPoint(const class ON_2iPoint& p);
|
|
|
|
static const ON_2iVector From2dex(const class ON_2dex& src);
|
|
|
|
public:
|
|
static const ON_2iVector Zero; // (0,0)
|
|
static const ON_2iVector UnitX; // (1,0)
|
|
static const ON_2iVector UnitY; // (0,1)
|
|
static const ON_2iVector Unset; // (ON_UNSET_INT_INDEX,ON_UNSET_INT_INDEX)
|
|
|
|
/*
|
|
Dictionary order compare.
|
|
*/
|
|
static int Compare(
|
|
const ON_2iVector& lhs,
|
|
const ON_2iVector& rhs
|
|
);
|
|
|
|
public:
|
|
ON_2iVector& operator+=(const class ON_2iVector&);
|
|
ON_2iVector& operator-=(const class ON_2iVector&);
|
|
ON_2iVector& operator*=(int);
|
|
|
|
ON_2iVector operator-() const;
|
|
|
|
public:
|
|
/*
|
|
Returns:
|
|
(0 == x && 0 == y)
|
|
*/
|
|
bool IsZero() const;
|
|
|
|
/*
|
|
Returns:
|
|
IsSet() && (0 != x || 0 != y)
|
|
*/
|
|
bool IsNotZero() const;
|
|
|
|
/*
|
|
Returns:
|
|
(ON_UNSET_INT_INDEX == x || ON_UNSET_INT_INDEX ==y)
|
|
*/
|
|
bool IsSet() const;
|
|
|
|
public:
|
|
ON__INT32 x;
|
|
ON__INT32 y;
|
|
};
|
|
|
|
ON_DECL
|
|
bool operator==(const ON_2iVector&, const ON_2iVector&);
|
|
|
|
ON_DECL
|
|
bool operator!=(const ON_2iVector&, const ON_2iVector&);
|
|
|
|
ON_DECL
|
|
ON_2iPoint operator+(const ON_2iPoint&, const ON_2iVector&);
|
|
|
|
ON_DECL
|
|
ON_2iPoint operator-(const ON_2iPoint&, const ON_2iVector&);
|
|
|
|
ON_DECL
|
|
ON_2iVector operator+(const ON_2iVector&, const ON_2iVector&);
|
|
|
|
ON_DECL
|
|
ON_2iVector operator-(const ON_2iVector&, const ON_2iVector&);
|
|
|
|
ON_DECL
|
|
ON_2iVector operator*(int, const ON_2iVector&);
|
|
|
|
class ON_CLASS ON_2iBoundingBox
|
|
{
|
|
public:
|
|
// Default construction intentionally leaves m_min and m_max uninitialized.
|
|
// Use something like
|
|
// ON_2iBoundingBox bbox(min_pt,max_pt);
|
|
// or
|
|
// ON_2iBoundingBox bbox = ON_2iBoundingBox::Unset;
|
|
ON_2iBoundingBox() = default;
|
|
|
|
~ON_2iBoundingBox() = default;
|
|
ON_2iBoundingBox(const ON_2iBoundingBox& ) = default;
|
|
ON_2iBoundingBox& operator=(const ON_2iBoundingBox& ) = default;
|
|
|
|
ON_2iBoundingBox(
|
|
const class ON_2iPoint bbox_min,
|
|
const class ON_2iPoint bbox_max
|
|
);
|
|
|
|
public:
|
|
static const ON_2iBoundingBox Zero; // (ON_2iPoint::Origin,ON_2iPoint::Origin);
|
|
static const ON_2iBoundingBox Unset; // (ON_2iPoint::Unset,ON_2iPoint::Unset)
|
|
|
|
public:
|
|
/*
|
|
Returns:
|
|
m_min.IsSet() && m_max.IsSet() && m_min.x <= m_max.x && m_min.y <= m_max.y.
|
|
*/
|
|
bool IsSet() const;
|
|
|
|
const ON_2iPoint Min() const;
|
|
const ON_2iPoint Max() const;
|
|
|
|
public:
|
|
ON_2iPoint m_min;
|
|
ON_2iPoint m_max;
|
|
};
|
|
|
|
ON_DECL
|
|
bool operator==(const ON_2iBoundingBox&, const ON_2iBoundingBox&);
|
|
|
|
ON_DECL
|
|
bool operator!=(const ON_2iBoundingBox&, const ON_2iBoundingBox&);
|
|
|
|
/*
|
|
Class ON_2iSize
|
|
For those situations where a Windows SDK SIZE or MFC CSize
|
|
value needs to be used in code that does not link with MFC.
|
|
*/
|
|
class ON_CLASS ON_2iSize
|
|
{
|
|
public:
|
|
// Default construction intentionally leaves x and y uninitialized.
|
|
// Use something like
|
|
// ON_2iSize pt(1,2);
|
|
// or
|
|
// ON_2iSize pt = ON_2iSize::Zero;
|
|
// when you need an initialized ON_2iSize.
|
|
ON_2iSize() = default;
|
|
|
|
~ON_2iSize() = default;
|
|
ON_2iSize(const ON_2iSize& ) = default;
|
|
ON_2iSize& operator=(const ON_2iSize& ) = default;
|
|
|
|
ON_2iSize(
|
|
int cx,
|
|
int cy
|
|
);
|
|
|
|
/*
|
|
Dictionary compare.
|
|
Returns:
|
|
-1: lhs < rhs
|
|
0: lsh == rsh
|
|
+1: lhs > rhs
|
|
*/
|
|
static int Compare(
|
|
const ON_2iSize& lhs,
|
|
const ON_2iSize& rhs
|
|
);
|
|
|
|
/*
|
|
Dictionary compare.
|
|
Returns:
|
|
-1: lhs < rhs
|
|
0: lsh == rsh
|
|
+1: lhs > rhs
|
|
*/
|
|
static int ComparePointer(
|
|
const ON_2iSize* lhs,
|
|
const ON_2iSize* rhs
|
|
);
|
|
|
|
public:
|
|
static const ON_2iSize Zero; // (0,0)
|
|
static const ON_2iSize Unset; // (ON_UNSET_INT_INDEX,ON_UNSET_INT_INDEX)
|
|
|
|
public:
|
|
/*
|
|
Returns:
|
|
true if both cx and cy are 0.
|
|
*/
|
|
bool IsZero() const;
|
|
|
|
/*
|
|
Returns:
|
|
true if neither cx nor cy are ON_UNSET_INT_INDEX.
|
|
*/
|
|
bool IsSet() const;
|
|
|
|
public:
|
|
ON__INT32 cx;
|
|
ON__INT32 cy;
|
|
};
|
|
|
|
ON_DECL
|
|
bool operator==(
|
|
const ON_2iSize& lhs,
|
|
const ON_2iSize& rhs
|
|
);
|
|
|
|
ON_DECL
|
|
bool operator!=(
|
|
const ON_2iSize& lhs,
|
|
const ON_2iSize& rhs
|
|
);
|
|
|
|
#if defined(ON_DLL_TEMPLATE)
|
|
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2iSize>;
|
|
|
|
#endif
|
|
|
|
/*
|
|
Class ON_4iRect
|
|
For those situations where a Windows SDK RECT or MFC CRect
|
|
value needs to be used in code that does not link with MFC.
|
|
If you want a traditional bounding box, use ON_2dBoundingBox.
|
|
*/
|
|
class ON_CLASS ON_4iRect
|
|
{
|
|
public:
|
|
// Default construction intentionally leaves x and y uninitialized.
|
|
// Use something like
|
|
// ON_4iRect pt(1,2,3,4);
|
|
// or
|
|
// ON_4iRect pt = ON_4iRect::Zero;
|
|
// when you need an initialized ON_4iRect.
|
|
ON_4iRect() = default;
|
|
|
|
~ON_4iRect() = default;
|
|
ON_4iRect(const ON_4iRect& ) = default;
|
|
ON_4iRect& operator=(const ON_4iRect& ) = default;
|
|
|
|
ON_4iRect(
|
|
int left,
|
|
int top,
|
|
int right,
|
|
int bottom
|
|
);
|
|
|
|
ON_4iRect(const ON_2iPoint topLeft, const ON_2iPoint& bottomRight);
|
|
ON_4iRect(const ON_2iPoint& point, const ON_2iSize& size);
|
|
|
|
public:
|
|
static const ON_4iRect Zero; // (0,0,0,0)
|
|
static const ON_4iRect Unset; // (ON_UNSET_INT_INDEX,ON_UNSET_INT_INDEX,ON_UNSET_INT_INDEX,ON_UNSET_INT_INDEX)
|
|
|
|
public:
|
|
/*
|
|
Returns:
|
|
true if all of left, top, right, and bottom are set to 0.
|
|
*/
|
|
bool IsZero() const;
|
|
|
|
void SetZero();
|
|
|
|
/*
|
|
Returns:
|
|
true if none of left, top, right, or bottom is set to ON_UNSET_INT_INDEX
|
|
*/
|
|
bool IsSet() const;
|
|
|
|
int Width(void) const;
|
|
int Height(void) const;
|
|
|
|
const ON_2iSize Size(void) const;
|
|
|
|
const ON_2iPoint CenterPoint(void) const;
|
|
const ON_2iPoint TopLeft(void) const;
|
|
const ON_2iPoint BottomRight(void) const;
|
|
|
|
bool IntersectRect(const ON_4iRect* r1, const ON_4iRect* r2);
|
|
bool IntersectRect(const ON_4iRect& r1, const ON_4iRect& r2);
|
|
|
|
bool IsRectEmpty(void) const;
|
|
bool IsRectNull(void) const;
|
|
void SetRectEmpty(void) { *this = Zero; }
|
|
void SetRect(int l, int t, int r, int b);
|
|
|
|
bool PtInRect(const ON_2iPoint& pt) const;
|
|
|
|
void OffsetRect(int, int);
|
|
void OffsetRect(const ON_2iVector&);
|
|
void InflateRect(int, int);
|
|
void InflateRect(int, int, int, int);
|
|
void DeflateRect(int, int);
|
|
bool SubtractRect(const ON_4iRect* rect1, const ON_4iRect* rect2);
|
|
|
|
void NormalizeRect();
|
|
|
|
public:
|
|
// NOTE WELL:
|
|
// Windows 2d integer device coordinates have a
|
|
// strong y-down bias and it is common for top < bottom.
|
|
// General 2d bounding boxes have a strong lower < upper / min < max bias.
|
|
// Take care when converting between ON_2iBoundingBox and ON_4iRect.
|
|
// It is intentional that no automatic conversion between bounding box
|
|
// and ON_4iRect is supplied because each case must be carefully considered.
|
|
ON__INT32 left;
|
|
ON__INT32 top;
|
|
ON__INT32 right;
|
|
ON__INT32 bottom;
|
|
};
|
|
|
|
#if defined(ON_DLL_TEMPLATE)
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_4iRect>;
|
|
#endif
|
|
|
|
|
|
ON_DECL
|
|
bool operator==(const ON_4iRect&, const ON_4iRect&);
|
|
|
|
ON_DECL
|
|
bool operator!=(const ON_4iRect&, const ON_4iRect&);
|
|
|
|
#endif
|