Files
opennurbs/opennurbs_ipoint.cpp
2024-02-15 08:00:36 -08:00

516 lines
9.9 KiB
C++

//
// Copyright (c) 1993-2022 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>.
//
////////////////////////////////////////////////////////////////
#include "opennurbs.h"
#if !defined(ON_COMPILING_OPENNURBS)
// This check is included in all opennurbs source .c and .cpp files to insure
// ON_COMPILING_OPENNURBS is defined when opennurbs source is compiled.
// When opennurbs source is being compiled, ON_COMPILING_OPENNURBS is defined
// and the opennurbs .h files alter what is declared and how it is declared.
#error ON_COMPILING_OPENNURBS must be defined when compiling opennurbs
#endif
// ON_2iPoint
ON_2iPoint::ON_2iPoint(int xValue, int yValue)
: x(xValue)
, y(yValue)
{}
const ON_2iPoint ON_2iPoint::From2dex(const class ON_2dex& src)
{
return ON_2iPoint(src.i, src.j);
}
bool ON_2iPoint::IsSet() const
{
return (ON_UNSET_INT_INDEX != x && ON_UNSET_INT_INDEX != y );
}
bool ON_2iPoint::IsOrigin() const
{
return (0 == x && 0 == y);
}
ON_2iPoint& ON_2iPoint::operator+=(const class ON_2iVector& v)
{
x += v.x;
y += v.y;
return *this;
}
ON_2iPoint& ON_2iPoint::operator-=(const class ON_2iVector& v)
{
x += v.x;
y += v.y;
return *this;
}
bool operator==(const ON_2iPoint& lhs, const ON_2iPoint& rhs)
{
return (lhs.x == rhs.x && lhs.y == rhs.y);
}
bool operator!=(const ON_2iPoint& lhs, const ON_2iPoint& rhs)
{
return (lhs.x != rhs.x || lhs.y != rhs.y);
}
int ON_2iPoint::Compare(
const ON_2iPoint& lhs,
const ON_2iPoint& rhs
)
{
if (lhs.x < rhs.x)
return -1;
if (lhs.x > rhs.x)
return 1;
if (lhs.y < rhs.y)
return -1;
if (lhs.y > rhs.y)
return 1;
return 0;
}
const ON_2iPoint ON_2iPoint::FromVector(const class ON_2iVector& v)
{
return ON_2iPoint(v.x, v.y);
}
// ON_2iVector
ON_2iVector::ON_2iVector(int xValue, int yValue)
: x(xValue)
, y(yValue)
{}
const ON_2iVector ON_2iVector::From2dex(const class ON_2dex& src)
{
return ON_2iVector(src.i, src.j);
}
bool ON_2iVector::IsSet() const
{
return (ON_UNSET_INT_INDEX != x && ON_UNSET_INT_INDEX != y );
}
bool ON_2iVector::IsZero() const
{
return (0 == x && 0 == y);
}
bool ON_2iVector::IsNotZero() const
{
return ((0 != x || 0 != y) && IsSet());
}
ON_2iVector& ON_2iVector::operator+=(const class ON_2iVector& v)
{
x += v.x;
y += v.y;
return *this;
}
ON_2iVector& ON_2iVector::operator-=(const class ON_2iVector& v)
{
x += v.x;
y += v.y;
return *this;
}
ON_2iVector& ON_2iVector::operator*=(int s)
{
x *= s;
y *= s;
return *this;
}
ON_2iVector ON_2iVector::operator-() const
{
return ON_2iVector(-x, -y);
}
bool operator==(const ON_2iVector& lhs, const ON_2iVector& rhs)
{
return (lhs.x == rhs.x && lhs.y == rhs.y);
}
bool operator!=(const ON_2iVector& lhs, const ON_2iVector& rhs)
{
return (lhs.x != rhs.x || lhs.y != rhs.y);
}
int ON_2iVector::Compare(
const ON_2iVector& lhs,
const ON_2iVector& rhs
)
{
if (lhs.x < rhs.x)
return -1;
if (lhs.x > rhs.x)
return 1;
if (lhs.y < rhs.y)
return -1;
if (lhs.y > rhs.y)
return 1;
return 0;
}
const ON_2iVector ON_2iVector::FromPoint(const class ON_2iPoint& p)
{
return ON_2iVector(p.x, p.y);
}
//////////////////////////////////////////////////////
ON_2iPoint operator+(const ON_2iPoint& lhs, const ON_2iVector& rhs)
{
ON_2iPoint p(lhs.x + rhs.x, lhs.y + rhs.y);
return p;
}
ON_2iPoint operator-(const ON_2iPoint& lhs, const ON_2iVector& rhs)
{
ON_2iPoint p(lhs.x - rhs.x, lhs.y - rhs.y);
return p;
}
ON_2iVector operator+(const ON_2iVector& lhs, const ON_2iVector& rhs)
{
ON_2iVector v(lhs.x + rhs.x, lhs.y + rhs.y);
return v;
}
ON_2iVector operator-(const ON_2iVector& lhs, const ON_2iVector& rhs)
{
ON_2iVector v(lhs.x - rhs.x, lhs.y - rhs.y);
return v;
}
ON_2iVector operator*(int lhs, const ON_2iVector& rhs)
{
ON_2iVector v(lhs*rhs.x, lhs*rhs.y);
return v;
}
// ON_2iBoundingBox
ON_2iBoundingBox::ON_2iBoundingBox(
const class ON_2iPoint bbox_min,
const class ON_2iPoint bbox_max
)
: m_min(bbox_min)
, m_max(bbox_max)
{}
bool ON_2iBoundingBox::IsSet() const
{
return (
m_min.x <= m_max.x
&& m_min.y <= m_max.y
&& m_min.IsSet()
&& m_max.IsSet()
);
}
const ON_2iPoint ON_2iBoundingBox::Min() const
{
return m_min;
}
const ON_2iPoint ON_2iBoundingBox::Max() const
{
return m_max;
}
bool operator==(const ON_2iBoundingBox& lhs, const ON_2iBoundingBox& rhs)
{
return (lhs.m_min == rhs.m_min && lhs.m_max == rhs.m_max);
}
bool operator!=(const ON_2iBoundingBox& lhs, const ON_2iBoundingBox& rhs)
{
return (lhs.m_min != rhs.m_min || lhs.m_max != rhs.m_max);
}
// ON_2iSize
int ON_2iSize::Compare(
const ON_2iSize& lhs,
const ON_2iSize& rhs
)
{
if (lhs.cx < rhs.cx)
return -1;
if (lhs.cx > rhs.cx)
return 1;
if (lhs.cy < rhs.cy)
return -1;
if (lhs.cy > rhs.cy)
return 1;
return 0;
}
int ON_2iSize::ComparePointer(
const ON_2iSize* lhs,
const ON_2iSize* rhs
)
{
if (lhs == rhs)
return 0;
if (nullptr == lhs)
return -1;
if (nullptr == rhs)
return 1;
if (lhs->cx < rhs->cx)
return -1;
if (lhs->cx > rhs->cx)
return 1;
if (lhs->cy < rhs->cy)
return -1;
if (lhs->cy > rhs->cy)
return 1;
return 0;
}
ON_2iSize::ON_2iSize(int cxValue, int cyValue)
: cx(cxValue)
, cy(cyValue)
{}
bool ON_2iSize::IsSet() const
{
return (ON_UNSET_INT_INDEX != cx && ON_UNSET_INT_INDEX != cy);
}
bool ON_2iSize::IsZero() const
{
return (0 == cx && 0 == cy);
}
bool operator==(
const ON_2iSize& lhs,
const ON_2iSize& rhs
)
{
return (lhs.cx == rhs.cx && lhs.cy == rhs.cy);
}
bool operator!=(const ON_2iSize& lhs, const ON_2iSize& rhs)
{
return (lhs.cx != rhs.cx || lhs.cy != rhs.cy);
}
// ON_4iRect
ON_4iRect::ON_4iRect(int leftValue, int topValue, int rightValue, int bottomValue)
: left(leftValue)
, top(topValue)
, right(rightValue)
, bottom(bottomValue)
{}
ON_4iRect::ON_4iRect(const ON_2iPoint topLeft, const ON_2iPoint& bottomRight)
: left(topLeft.x)
, top(topLeft.y)
, right(bottomRight.x)
, bottom(bottomRight.y)
{}
ON_4iRect::ON_4iRect(const ON_2iPoint& point, const ON_2iSize& size)
{
left = point.x;
top = point.y;
right = left + size.cx;
bottom = top + size.cy;
}
bool ON_4iRect::IsSet() const
{
return (
ON_UNSET_INT_INDEX != left
&& ON_UNSET_INT_INDEX != top
&& ON_UNSET_INT_INDEX != right
&& ON_UNSET_INT_INDEX != bottom
);
}
int ON_4iRect::Width(void) const { return std::abs(right - left); }
int ON_4iRect::Height(void) const { return std::abs(bottom - top); }
const ON_2iSize ON_4iRect::Size(void) const { return ON_2iSize(Width(), Height()); }
const ON_2iPoint ON_4iRect::CenterPoint(void) const { return ON_2iPoint((left + right) / 2, (top + bottom) / 2); }
const ON_2iPoint ON_4iRect::TopLeft(void) const { return ON_2iPoint(left, top); }
const ON_2iPoint ON_4iRect::BottomRight(void) const { return ON_2iPoint(right, bottom); }
bool ON_4iRect::IntersectRect(const ON_4iRect * r1, const ON_4iRect * r2)
{
left = ON_Max(r1->left, r2->left);
right = ON_Min(r1->right, r2->right);
if (right > left)
{
top = ON_Max(r1->top, r2->top);
bottom = ON_Min(r1->bottom, r2->bottom);
if (bottom > top)
return true;
}
// degenerate rectangle at this point...
SetRectEmpty();
return false;
}
bool ON_4iRect::IntersectRect(const ON_4iRect & r1, const ON_4iRect & r2) { return IntersectRect(&r1, &r2); }
bool ON_4iRect::IsRectEmpty(void) const
{
return 0 == Width() || 0 == Height();
}
bool ON_4iRect::IsRectNull(void) const
{
return 0 == left &&
0 == top &&
0 == bottom &&
0 == right;
}
void ON_4iRect::SetRect(int l, int t, int r, int b) { left = l; top = t; right = r; bottom = b; }
bool ON_4iRect::PtInRect(const ON_2iPoint & pt) const
{
return pt.x >= left && pt.y >= top && pt.x < right && pt.y < bottom;
}
void ON_4iRect::OffsetRect(int x, int y)
{
left += x;
right += x;
top += y;
bottom += y;
}
void ON_4iRect::OffsetRect(const ON_2iVector& v)
{
left += v.x;
right += v.x;
top += v.y;
bottom += v.y;
}
void ON_4iRect::InflateRect(int x, int y)
{
left -= x;
top -= y;
right += x;
bottom += y;
}
void ON_4iRect::InflateRect(int l, int t, int r, int b)
{
left -= l;
top -= t;
right += r;
bottom += b;
}
void ON_4iRect::DeflateRect(int x, int y)
{
left += x;
top += y;
right -= x;
bottom -= y;
}
bool ON_4iRect::SubtractRect(const ON_4iRect* rect1, const ON_4iRect* rect2)
{
if (rect1 == nullptr)
return false;
*this = *rect1;
if (rect1->IsRectEmpty() || rect2 == nullptr || rect2->IsRectEmpty())
{
return true;
}
if (rect2->top <= rect1->top && rect2->bottom >= rect1->bottom)
{
if (left < rect2->right)
{
left = ON_Min(rect2->right, right);
}
if (right > rect2->left)
{
right = ON_Max(left, rect2->left);
}
}
if (rect2->left <= rect1->left && rect2->right >= rect1->right)
{
if (top < rect2->bottom)
{
top = ON_Min(rect2->bottom, bottom);
}
if (bottom > rect2->top)
{
bottom = ON_Max(top, rect2->top);
}
}
return true;
}
void ON_4iRect::NormalizeRect()
{
int nTemp;
if (left > right)
{
nTemp = left;
left = right;
right = nTemp;
}
if (top > bottom)
{
nTemp = top;
top = bottom;
bottom = nTemp;
}
}
bool ON_4iRect::IsZero() const
{
return (0 == left && 0 == top && 0 == right && 0 == bottom);
}
void ON_4iRect::SetZero() { *this = Zero; }
bool operator==(const ON_4iRect& lhs, const ON_4iRect& rhs)
{
return (lhs.left == rhs.left
&& lhs.top == rhs.top
&& lhs.right == rhs.right
&& lhs.bottom == rhs.bottom);
}
bool operator!=(const ON_4iRect& lhs, const ON_4iRect& rhs)
{
return (lhs.left != rhs.left
|| lhs.top != rhs.top
|| lhs.right != rhs.right
|| lhs.bottom != rhs.bottom);
}