mirror of
https://github.com/mcneel/opennurbs.git
synced 2026-03-04 06:07:00 +08:00
Co-authored-by: Andrew Le Bihan <andy@mcneel.com> Co-authored-by: Dale Fugier <dale@mcneel.com> Co-authored-by: Dale Lear <dalelear@mcneel.com> Co-authored-by: Greg Arden <greg@mcneel.com> Co-authored-by: Jussi <jussi@mcneel.com> Co-authored-by: Lowell <lowell@mcneel.com> Co-authored-by: Rajaa Issa <rajaa@mcneel.com> Co-authored-by: Steve Baer <steve@mcneel.com> Co-authored-by: alain <alain@mcneel.com> Co-authored-by: chuck <chuck@mcneel.com> Co-authored-by: piac <giulio@mcneel.com>
3700 lines
106 KiB
C++
3700 lines
106 KiB
C++
/* $NoKeywords: $ */
|
|
/*
|
|
//
|
|
// Copyright (c) 1993-2012 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>.
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
*/
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// defines double precision point, vector, and array classes
|
|
//
|
|
////////////////////////////////////////////////////////////////
|
|
#if !defined(ON_POINT_INC_)
|
|
#define ON_POINT_INC_
|
|
|
|
class ON_BoundingBox;
|
|
class ON_Xform;
|
|
class ON_Line;
|
|
class ON_Plane;
|
|
|
|
class ON_2dPoint;
|
|
class ON_3dPoint;
|
|
class ON_4dPoint;
|
|
|
|
class ON_2dVector;
|
|
class ON_3dVector;
|
|
|
|
class ON_2fVector;
|
|
class ON_3fVector;
|
|
|
|
class ON_Interval;
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// ON_Interval
|
|
//
|
|
class ON_CLASS ON_Interval
|
|
{
|
|
public:
|
|
static const ON_Interval EmptyInterval; // (ON_UNSET_VALUE,ON_UNSET_VALUE)
|
|
static const ON_Interval ZeroToOne; // (0.0, 1.0)
|
|
static const ON_Interval ZeroToTwoPi; // (0.0, 2.0*ON_PI)
|
|
static const ON_Interval Nan; // (ON_DBL_QNAN,ON_DBL_QNAN)
|
|
|
|
public:
|
|
// The default constructor creates ON_Interval::EmptyInterval (ON_UNSET_VALUE,ON_UNSET_VALUE)
|
|
ON_Interval();
|
|
~ON_Interval() = default;
|
|
ON_Interval(const ON_Interval&) = default;
|
|
ON_Interval& operator=(const ON_Interval&) = default;
|
|
|
|
ON_Interval(double t0,double t1);
|
|
|
|
/*
|
|
Returns:
|
|
ON_Interval(t,t).
|
|
*/
|
|
static const ON_Interval Singleton(double t);
|
|
|
|
public:
|
|
// Interval = (m_t[0], m_t[1])
|
|
double m_t[2];
|
|
|
|
#if defined(OPENNURBS_WALL)
|
|
// Goal is to eventually require = as the only way to modify ON_Interval values.
|
|
ON_DEPRECATED_MSG("Use interval = ON_Interval::EmptyInterval;")
|
|
#endif
|
|
void Destroy();
|
|
|
|
/*
|
|
Description:
|
|
Sets interval to [t0,t1]
|
|
Parameters:
|
|
t0 - [in]
|
|
t1 - [in]
|
|
See Also:
|
|
ON_Interval::ON_Interval( double, double )
|
|
*/
|
|
void Set(
|
|
double t0,
|
|
double t1
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Convert normalized parameter to interval value, or pair of values.
|
|
Parameters:
|
|
normalized_parameter - [in]
|
|
Returns:
|
|
Interval parameter
|
|
min*(1.0-normalized_parameter) + max*normalized_parameter
|
|
See Also:
|
|
ON_Interval::NormalizedParameterAt
|
|
*/
|
|
double ParameterAt (
|
|
double normalized_parameter
|
|
) const;
|
|
ON_Interval ParameterAt (
|
|
ON_Interval normalized_interval
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Convert interval value, or pair of values, to normalized parameter.
|
|
Parameters:
|
|
interval_parameter - [in] value in interval
|
|
Returns:
|
|
Normalized parameter x so that
|
|
min*(1.0-x) + max*x = interval_parameter.
|
|
See Also:
|
|
ON_Interval::ParameterAt
|
|
*/
|
|
double NormalizedParameterAt (
|
|
double interval_parameter
|
|
) const;
|
|
ON_Interval NormalizedParameterAt (
|
|
ON_Interval interval_parameter
|
|
) const;
|
|
|
|
double& operator[](int); // returns (index<=0) ? m_t[0] : m_t[1]
|
|
double operator[](int) const; // returns (index<=0) ? m_t[0] : m_t[1]
|
|
double& operator[](unsigned int); // returns (index<=0) ? m_t[0] : m_t[1]
|
|
double operator[](unsigned int) const; // returns (index<=0) ? m_t[0] : m_t[1]
|
|
|
|
double Min() const; // returns smaller of m_t[0] and m_t[1]
|
|
double Max() const; // returns larger of m_t[0] and m_t[1]
|
|
double Mid() const; // returns 0.5*(m_t[0] + m_t[1])
|
|
double Length() const; // returns signed length, m_t[1]-m_t[0]
|
|
|
|
bool IsIncreasing() const; // returns true if m_t[0] < m_t[1]
|
|
bool IsDecreasing() const; // returns true if m_t[0] > m_t[0];
|
|
bool IsInterval() const; // returns truc if m_t[0] != m_t[1]
|
|
bool IsSingleton() const; // returns true if m_t[0] == m_t[1] != ON_UNSET_VALUE
|
|
bool IsEmptyInterval() const; // returns true if m_t[0] == m_t[1] == ON_UNSET_VALUE
|
|
bool IsValid() const; // returns ON_IsValid(m_t[0]) && ON_IsValid(m_t[1])
|
|
|
|
#if defined(OPENNURBS_WALL)
|
|
ON_DEPRECATED_MSG("Use IsEmptyInterval()")
|
|
#endif
|
|
bool IsEmptySet() const; // returns true if m_t[0] == m_t[1] == ON_UNSET_VALUE
|
|
|
|
bool MakeIncreasing(); // returns true if resulting interval IsIncreasing()
|
|
|
|
/*
|
|
Description:
|
|
A well ordered dictionary compare function that is nan aware and can
|
|
be used for robust sorting.
|
|
*/
|
|
static int Compare(
|
|
const ON_Interval& lhs,
|
|
const ON_Interval& rhs
|
|
);
|
|
|
|
|
|
/*
|
|
Returns:
|
|
True if (lhs.m_t[0] != rhs.m_t[0]) or (lhs.m_t[1] != rhs.m_t[1]) and
|
|
no values are nans.
|
|
*/
|
|
bool operator!=(const ON_Interval& rhs) const;
|
|
|
|
/*
|
|
Returns:
|
|
True if (lhs.m_t[0] == rhs.m_t[0]) and (lhs.m_t[1] === rhs.m_t[1]).
|
|
*/
|
|
bool operator==(const ON_Interval& rhs) const;
|
|
|
|
/*
|
|
Description:
|
|
Test a value t to see if it is inside the interval.
|
|
Parameters:
|
|
t - [in] value to test
|
|
bTestOpenInterval - [in]
|
|
If false, t is tested to see if it satisfies min <= t <= max.
|
|
If true, t is tested to see if it satisfies min < t < max.
|
|
Returns:
|
|
true if t is in the interval and false if t is not
|
|
in the interval.
|
|
*/
|
|
bool Includes(
|
|
double t,
|
|
bool bTestOpenInterval = false
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Test an interval to see if it is contained in this interval.
|
|
Parameters:
|
|
other - [in] interval to test
|
|
bProperSubSet - [in] if true, then the test is for a proper subinterval.
|
|
Returns:
|
|
If bProperSubSet is false, then the result is true when
|
|
this->Min() <= other.Min() and other.Max() <= this->Max().
|
|
If bProperSubSet is true, then the result is true when
|
|
this->Min() <= other.Min() and other.Max() <= this->Max()
|
|
and at least one of the inequalites is strict.
|
|
*/
|
|
bool Includes(
|
|
const ON_Interval& other,
|
|
bool bProperSubSet = false
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
value is clamped to the range of this interval.
|
|
Assumes this interval is not Decreasing().
|
|
Parameters:
|
|
value -[in/out] value is set to x in interval
|
|
such that |x - value|<= |x - y| for all y in this interval
|
|
Returns:
|
|
-1 if value<Min()
|
|
0 if value in interval
|
|
+1 if value>Max()
|
|
*/
|
|
int Clamp(double& value) const;
|
|
|
|
/*
|
|
Description:
|
|
Test a pair of interval to see if they have a non-empty intersection.
|
|
Parameters:
|
|
A - [in] interval to test
|
|
B - [in] interval to test
|
|
Returns:
|
|
true if the intersection is non-empty,
|
|
including if the intersection is a single point.
|
|
false otherwise.
|
|
*/
|
|
static bool IntervalsOverlap(const ON_Interval& A, const ON_Interval& B);
|
|
|
|
/*
|
|
Description:
|
|
Changes interval to [-m_t[1],-m_t[0]].
|
|
*/
|
|
void Reverse();
|
|
|
|
/*
|
|
Description:
|
|
Swaps m_t[0] and m_t[1].
|
|
*/
|
|
void Swap();
|
|
|
|
//////////
|
|
// If the intersection is not empty, then
|
|
// intersection = [max(this.Min(),arg.Min()), min(this.Max(),arg.Max())]
|
|
// Intersection() returns true if the intersection is not empty.
|
|
// The interval [ON_UNSET_VALUE,ON_UNSET_VALUE] is considered to be
|
|
// the empty set interval. The result of any intersection involving an
|
|
// empty set interval or disjoint intervals is the empty set interval.
|
|
bool Intersection( // this = this intersect arg
|
|
const ON_Interval&
|
|
);
|
|
|
|
//////////
|
|
// If the intersection is not empty, then
|
|
// intersection = [max(argA.Min(),argB.Min()), min(argA.Max(),argB.Max())]
|
|
// Intersection() returns true if the intersection is not empty.
|
|
// The interval [ON_UNSET_VALUE,ON_UNSET_VALUE] is considered to be
|
|
// the empty set interval. The result of any intersection involving an
|
|
// empty set interval or disjoint intervals is the empty set interval.
|
|
bool Intersection( // this = intersection of two args
|
|
const ON_Interval&,
|
|
const ON_Interval&
|
|
);
|
|
|
|
//////////
|
|
// The union of an empty set and an increasing interval is the increasing
|
|
// interval. The union of two empty sets is empty. The union of an empty
|
|
// set an a non-empty interval is the non-empty interval.
|
|
// The union of two non-empty intervals is
|
|
// union = [min(this.Min(),arg.Min()), max(this.Max(),arg.Max()),]
|
|
// Union() returns true if the union is not empty.
|
|
bool Union( // this = this union arg
|
|
const ON_Interval&
|
|
);
|
|
|
|
bool Union( // this = this union arg
|
|
double t
|
|
);
|
|
|
|
bool Union( // this = this union arg
|
|
int count,
|
|
const double* t
|
|
);
|
|
|
|
//////////
|
|
// The union of an empty set and an increasing interval is the increasing
|
|
// interval. The union of two empty sets is empty. The union of an empty
|
|
// set an a non-empty interval is the non-empty interval.
|
|
// The union of two non-empty intervals is
|
|
// union = [min(argA.Min(),argB.Min()), max(argA.Max(),argB.Max()),]
|
|
// Union() returns true if the union is not empty.
|
|
bool Union( // this = union of two args
|
|
const ON_Interval&,
|
|
const ON_Interval&
|
|
);
|
|
|
|
/////////////////////////
|
|
// Expand the interval by adding delta to m_t[1] and subtracting
|
|
// it from m_t[0]. So, when delta is positive and the interval is
|
|
// increasing this function expands the interval on each side.
|
|
// returns true if the result is increasing.
|
|
bool Expand(double delta);
|
|
};
|
|
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// ON_2dPoint
|
|
//
|
|
class ON_CLASS ON_2dPoint
|
|
{
|
|
public:
|
|
double x, y;
|
|
|
|
public:
|
|
// x,y not initialized
|
|
ON_2dPoint() = default;
|
|
~ON_2dPoint() = default;
|
|
ON_2dPoint(const ON_2dPoint&) = default;
|
|
ON_2dPoint& operator=(const ON_2dPoint&) = default;
|
|
|
|
public:
|
|
static const ON_2dPoint Origin; // (0.0,0.0)
|
|
static const ON_2dPoint UnsetPoint; // (ON_UNSET_VALUE,ON_UNSET_VALUE)
|
|
static const ON_2dPoint NanPoint; // (ON_DBL_QNAN,ON_DBL_QNAN)
|
|
|
|
/*
|
|
Description:
|
|
A well ordered dictionary compare function that is nan aware and can
|
|
be used for robust sorting.
|
|
*/
|
|
static int Compare(
|
|
const ON_2dPoint& lhs,
|
|
const ON_2dPoint& rhs
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
(A+B)/2
|
|
Remarks:
|
|
Exact when coordinates are equal and prevents overflow.
|
|
*/
|
|
static const ON_2dPoint Midpoint(const ON_2dPoint& A, const ON_2dPoint& B);
|
|
|
|
|
|
explicit ON_2dPoint(double x,double y);
|
|
#if defined(OPENNURBS_WALL)
|
|
// Goal is to eventually have all constructors that discard informtion be explicit.
|
|
explicit
|
|
#endif
|
|
ON_2dPoint(const ON_3dPoint& ); // from 3d point
|
|
|
|
explicit ON_2dPoint(const ON_4dPoint& h); // from 4d point - h.w must be non-zero
|
|
ON_2dPoint(const ON_2dVector& ); // from 2d vector
|
|
explicit ON_2dPoint(const ON_3dVector& ); // from 3d vector
|
|
|
|
explicit ON_2dPoint(const double*); // from double[2] array
|
|
|
|
ON_2dPoint(const class ON_2fPoint&); // from 2f point
|
|
explicit ON_2dPoint(const class ON_3fPoint&); // from 3f point
|
|
explicit ON_2dPoint(const class ON_4fPoint& h); // from 4f point - h.w must be non-zero
|
|
explicit ON_2dPoint(const class ON_2fVector&); // from 2f vector
|
|
explicit ON_2dPoint(const class ON_3fVector&); // from 3f vector
|
|
|
|
explicit ON_2dPoint(const float*); // from float[2] array
|
|
|
|
// (double*) conversion operators
|
|
operator double*();
|
|
operator const double*() const;
|
|
|
|
// use implicit operator=(const ON_2dPoint&)
|
|
ON_2dPoint& operator=(const ON_3dPoint&);
|
|
ON_2dPoint& operator=(const ON_4dPoint&);
|
|
ON_2dPoint& operator=(const ON_2dVector&);
|
|
ON_2dPoint& operator=(const ON_3dVector&);
|
|
ON_2dPoint& operator=(const double*); // point = double[2] support
|
|
|
|
ON_2dPoint& operator=(const ON_2fPoint&);
|
|
ON_2dPoint& operator=(const ON_3fPoint&);
|
|
ON_2dPoint& operator=(const ON_4fPoint&);
|
|
ON_2dPoint& operator=(const ON_2fVector&);
|
|
ON_2dPoint& operator=(const ON_3fVector&);
|
|
ON_2dPoint& operator=(const float*); // point = float[2] support
|
|
|
|
ON_2dPoint& operator*=(double);
|
|
ON_2dPoint& operator/=(double);
|
|
ON_2dPoint& operator+=(const ON_2dVector&);
|
|
ON_2dPoint& operator-=(const ON_2dVector&);
|
|
|
|
ON_2dPoint operator*(int) const;
|
|
ON_2dPoint operator/(int) const;
|
|
ON_2dPoint operator*(float) const;
|
|
ON_2dPoint operator/(float) const;
|
|
ON_2dPoint operator*(double) const;
|
|
ON_2dPoint operator/(double) const;
|
|
|
|
ON_2dPoint operator+(const ON_2dPoint&) const;
|
|
ON_2dPoint operator+(const ON_2dVector&) const;
|
|
ON_2dVector operator-(const ON_2dPoint&) const;
|
|
ON_2dPoint operator-(const ON_2dVector&) const;
|
|
ON_3dPoint operator+(const ON_3dPoint&) const;
|
|
ON_3dPoint operator+(const ON_3dVector&) const;
|
|
ON_3dVector operator-(const ON_3dPoint&) const;
|
|
ON_3dPoint operator-(const ON_3dVector&) const;
|
|
|
|
ON_2dPoint operator+(const ON_2fPoint&) const;
|
|
ON_2dPoint operator+(const ON_2fVector&) const;
|
|
ON_2dVector operator-(const ON_2fPoint&) const;
|
|
ON_2dPoint operator-(const ON_2fVector&) const;
|
|
ON_3dPoint operator+(const ON_3fPoint&) const;
|
|
ON_3dPoint operator+(const ON_3fVector&) const;
|
|
ON_3dVector operator-(const ON_3fPoint&) const;
|
|
ON_3dPoint operator-(const ON_3fVector&) const;
|
|
|
|
double operator*(const ON_2dPoint&) const; // dot product for points acting as vectors
|
|
double operator*(const ON_2dVector&) const; // dot product for points acting as vectors
|
|
|
|
ON_2dPoint operator*(const ON_Xform&) const;
|
|
|
|
bool operator==(const ON_2dPoint&) const;
|
|
bool operator!=(const ON_2dPoint&) const;
|
|
|
|
// dictionary order comparisons
|
|
bool operator<=(const ON_2dPoint&) const;
|
|
bool operator>=(const ON_2dPoint&) const;
|
|
bool operator<(const ON_2dPoint&) const;
|
|
bool operator>(const ON_2dPoint&) const;
|
|
|
|
// index operators mimic double[2] behavior
|
|
double& operator[](int);
|
|
double operator[](int) const;
|
|
double& operator[](unsigned int);
|
|
double operator[](unsigned int) const;
|
|
|
|
/*
|
|
Returns:
|
|
False if any coordinate is infinte, a nan, or ON_UNSET_VALUE.
|
|
*/
|
|
bool IsValid() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
|
|
*/
|
|
bool IsUnset() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is a nan.
|
|
*/
|
|
bool IsNan() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is ON_UNSET_VALUE, ON_UNSET_POSITIVE_VALUE, or a nan
|
|
*/
|
|
bool IsUnsetOrNan() const;
|
|
|
|
// set 2d point value
|
|
void Set(double x,double y);
|
|
|
|
double DistanceTo( const ON_2dPoint& ) const;
|
|
|
|
int MaximumCoordinateIndex() const;
|
|
double MaximumCoordinate() const; // absolute value of maximum coordinate
|
|
|
|
int MinimumCoordinateIndex() const;
|
|
double MinimumCoordinate() const; // absolute value of minimum coordinate
|
|
|
|
ON_DEPRECATED_MSG("Use p = ON_2dPoint::Origin;")
|
|
void Zero(); // set all coordinates to zero;
|
|
|
|
/*
|
|
Returns:
|
|
true if all coordinates are not zero and no coordinates are nans.
|
|
false otherwise.
|
|
*/
|
|
bool IsZero() const;
|
|
|
|
/*
|
|
Returns:
|
|
true if at lease one coordinate is not zero and no coordinates are unset or nans.
|
|
*/
|
|
bool IsNotZero() const;
|
|
|
|
// These transform the point in place. The transformation matrix acts on
|
|
// the left of the point; i.e., result = transformation*point
|
|
void Transform(
|
|
const ON_Xform&
|
|
);
|
|
|
|
void Rotate( // rotatation in XY plane
|
|
double angle, // angle in radians
|
|
const ON_2dPoint& center // center of rotation
|
|
);
|
|
|
|
void Rotate( // rotatation in XY plane
|
|
double sin_angle, // sin(angle)
|
|
double cos_angle, // cos(angle)
|
|
const ON_2dPoint& center // center of rotation
|
|
);
|
|
|
|
ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
|
|
};
|
|
|
|
ON_DECL
|
|
ON_2dPoint operator*(int, const ON_2dPoint&);
|
|
|
|
ON_DECL
|
|
ON_2dPoint operator*(float, const ON_2dPoint&);
|
|
|
|
ON_DECL
|
|
ON_2dPoint operator*(double, const ON_2dPoint&);
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// ON_3dPoint
|
|
//
|
|
class ON_CLASS ON_3dPoint
|
|
{
|
|
public:
|
|
double x, y, z;
|
|
|
|
public:
|
|
// x,y,z not initialized
|
|
ON_3dPoint() = default;
|
|
~ON_3dPoint() = default;
|
|
ON_3dPoint(const ON_3dPoint&) = default;
|
|
ON_3dPoint& operator=(const ON_3dPoint&) = default;
|
|
|
|
public:
|
|
static const ON_3dPoint Origin; // (0.0,0.0,0.0)
|
|
static const ON_3dPoint UnsetPoint; // (ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE)
|
|
static const ON_3dPoint NanPoint; // (ON_DBL_QNAN,ON_DBL_QNAN,ON_DBL_QNAN)
|
|
|
|
/*
|
|
Description:
|
|
A well ordered dictionary compare function that is nan aware and can
|
|
be used for robust sorting.
|
|
*/
|
|
static int Compare(
|
|
const ON_3dPoint& lhs,
|
|
const ON_3dPoint& rhs
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
(A+B)/2
|
|
Remarks:
|
|
Exact when coordinates are equal and prevents overflow.
|
|
*/
|
|
static const ON_3dPoint Midpoint(const ON_3dPoint& A, const ON_3dPoint& B);
|
|
|
|
public:
|
|
explicit ON_3dPoint(double x,double y,double z);
|
|
#if defined(OPENNURBS_WALL)
|
|
// Goal is to eventually have all constructors that discard informtion be explicit.
|
|
explicit
|
|
#endif
|
|
ON_3dPoint(const ON_2dPoint& ); // from 2d point
|
|
explicit ON_3dPoint(const ON_4dPoint& h); // from 4d point - h.w must be non-zero
|
|
explicit ON_3dPoint(const ON_2dVector& ); // from 2d vector
|
|
ON_3dPoint(const ON_3dVector& ); // from 3d vector
|
|
explicit ON_3dPoint(const double*); // from double[3] array
|
|
|
|
explicit ON_3dPoint(const class ON_2fPoint&); // from 2f point
|
|
ON_3dPoint(const class ON_3fPoint&); // from 3f point
|
|
explicit ON_3dPoint(const class ON_4fPoint& h ); // from 4f point- h.w must be non-zero
|
|
explicit ON_3dPoint(const class ON_2fVector&); // from 2f point
|
|
explicit ON_3dPoint(const class ON_3fVector&); // from 3f point
|
|
explicit ON_3dPoint(const float*); // from float[3] array
|
|
|
|
// (double*) conversion operators
|
|
operator double*();
|
|
operator const double*() const;
|
|
|
|
// use implicit operator=(const ON_3dPoint&)
|
|
ON_3dPoint& operator=(const ON_2dPoint&);
|
|
ON_3dPoint& operator=(const ON_4dPoint&);
|
|
ON_3dPoint& operator=(const ON_2dVector&);
|
|
ON_3dPoint& operator=(const ON_3dVector&);
|
|
ON_3dPoint& operator=(const double*); // point = double[3] support
|
|
|
|
ON_3dPoint& operator=(const class ON_2fPoint&);
|
|
ON_3dPoint& operator=(const class ON_3fPoint&);
|
|
ON_3dPoint& operator=(const class ON_4fPoint&);
|
|
ON_3dPoint& operator=(const class ON_2fVector&);
|
|
ON_3dPoint& operator=(const class ON_3fVector&);
|
|
ON_3dPoint& operator=(const float*); // point = float[3] support
|
|
|
|
ON_3dPoint& operator*=(double);
|
|
ON_3dPoint& operator/=(double);
|
|
ON_3dPoint& operator+=(const ON_3dVector&);
|
|
ON_3dPoint& operator-=(const ON_3dVector&);
|
|
|
|
ON_3dPoint operator*(int) const;
|
|
ON_3dPoint operator/(int) const;
|
|
ON_3dPoint operator*(float) const;
|
|
ON_3dPoint operator/(float) const;
|
|
ON_3dPoint operator*(double) const;
|
|
ON_3dPoint operator/(double) const;
|
|
|
|
ON_3dPoint operator+(const ON_3dPoint&) const;
|
|
ON_3dPoint operator+(const ON_3dVector&) const;
|
|
ON_3dVector operator-(const ON_3dPoint&) const;
|
|
ON_3dPoint operator-(const ON_3dVector&) const;
|
|
ON_3dPoint operator+(const ON_2dPoint&) const;
|
|
ON_3dPoint operator+(const ON_2dVector&) const;
|
|
ON_3dVector operator-(const ON_2dPoint&) const;
|
|
ON_3dPoint operator-(const ON_2dVector&) const;
|
|
|
|
ON_3dPoint operator+(const ON_3fPoint&) const;
|
|
ON_3dPoint operator+(const ON_3fVector&) const;
|
|
ON_3dVector operator-(const ON_3fPoint&) const;
|
|
ON_3dPoint operator-(const ON_3fVector&) const;
|
|
ON_3dPoint operator+(const ON_2fPoint&) const;
|
|
ON_3dPoint operator+(const ON_2fVector&) const;
|
|
ON_3dVector operator-(const ON_2fPoint&) const;
|
|
ON_3dPoint operator-(const ON_2fVector&) const;
|
|
|
|
double operator*(const ON_3dPoint&) const; // dot product for points acting as vectors
|
|
double operator*(const ON_3dVector&) const; // dot product for points acting as vectors
|
|
|
|
ON_3dPoint operator*(const ON_Xform&) const;
|
|
|
|
bool operator==(const ON_3dPoint&) const;
|
|
bool operator!=(const ON_3dPoint&) const;
|
|
|
|
// dictionary order comparisons
|
|
bool operator<=(const ON_3dPoint&) const;
|
|
bool operator>=(const ON_3dPoint&) const;
|
|
bool operator<(const ON_3dPoint&) const;
|
|
bool operator>(const ON_3dPoint&) const;
|
|
|
|
// index operators mimic double[3] behavior
|
|
double& operator[](int);
|
|
double operator[](int) const;
|
|
double& operator[](unsigned int);
|
|
double operator[](unsigned int) const;
|
|
|
|
/*
|
|
Returns:
|
|
False if any coordinate is infinte, a nan, or ON_UNSET_VALUE.
|
|
*/
|
|
bool IsValid() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
|
|
*/
|
|
bool IsUnset() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is a nan.
|
|
*/
|
|
bool IsNan() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is ON_UNSET_VALUE, ON_UNSET_POSITIVE_VALUE, or a nan
|
|
*/
|
|
bool IsUnsetOrNan() const;
|
|
|
|
// set 3d point value
|
|
void Set(double x,double y,double z);
|
|
|
|
double DistanceTo( const ON_3dPoint& ) const;
|
|
|
|
int MaximumCoordinateIndex() const;
|
|
double MaximumCoordinate() const; // absolute value of maximum coordinate
|
|
|
|
int MinimumCoordinateIndex() const;
|
|
double MinimumCoordinate() const; // absolute value of minimum coordinate
|
|
|
|
double Fuzz( double tolerance = ON_ZERO_TOLERANCE ) const; // tolerance to use when comparing 3d points
|
|
|
|
#if defined(OPENNURBS_WALL)
|
|
// Goal is to eventually remove all functions that modify points in place.
|
|
ON_DEPRECATED_MSG("Use p = ON_3dPoint::Origin;")
|
|
#endif
|
|
void Zero(); // set all coordinates to zero;
|
|
|
|
/*
|
|
Returns:
|
|
true if all coordinates are not zero and no coordinates are nans.
|
|
false otherwise.
|
|
*/
|
|
bool IsZero() const;
|
|
|
|
/*
|
|
Returns:
|
|
true if at lease one coordinate is not zero and no coordinates are unset or nans.
|
|
*/
|
|
bool IsNotZero() const;
|
|
|
|
// These transform the point in place. The transformation matrix acts on
|
|
// the left of the point; i.e., result = transformation*point
|
|
void Transform(
|
|
const ON_Xform&
|
|
);
|
|
|
|
void Rotate(
|
|
double angle, // angle in radians
|
|
const ON_3dVector& axis, // axis of rotation
|
|
const ON_3dPoint& center // center of rotation
|
|
);
|
|
|
|
void Rotate(
|
|
double sin_angle, // sin(angle)
|
|
double cos_angle, // cos(angle)
|
|
const ON_3dVector& axis, // axis of rotation
|
|
const ON_3dPoint& center // center of rotation
|
|
);
|
|
|
|
ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
|
|
};
|
|
|
|
ON_DECL
|
|
ON_3dPoint operator*(int, const ON_3dPoint&);
|
|
|
|
ON_DECL
|
|
ON_3dPoint operator*(float, const ON_3dPoint&);
|
|
|
|
ON_DECL
|
|
ON_3dPoint operator*(double, const ON_3dPoint&);
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// ON_4dPoint (homogeneous coordinates)
|
|
//
|
|
class ON_CLASS ON_4dPoint
|
|
{
|
|
public:
|
|
double x, y, z, w;
|
|
|
|
/*
|
|
Returns:
|
|
ON_UNSET_VALUE, if x or w is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
|
|
and neither x nor w is a nan.
|
|
x/w, otherwise
|
|
Remarks:
|
|
If w is 0.0 or nan, the result will be a nan.
|
|
*/
|
|
double EuclideanX() const;
|
|
|
|
/*
|
|
Returns:
|
|
ON_UNSET_VALUE, if y or w is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
|
|
and neither y nor w is a nan.
|
|
y/w, otherwise
|
|
Remarks:
|
|
If w is 0.0 or nan, the result will be a nan.
|
|
*/
|
|
double EuclideanY() const;
|
|
|
|
/*
|
|
Returns:
|
|
ON_UNSET_VALUE, if z or w is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
|
|
and neither z nor w is a nan.
|
|
z/w, otherwise
|
|
Remarks:
|
|
If w is 0.0 or nan, the result will be a nan.
|
|
*/
|
|
double EuclideanZ() const;
|
|
|
|
public:
|
|
// x,y,z,w not initialized
|
|
ON_4dPoint() = default;
|
|
~ON_4dPoint() = default;
|
|
ON_4dPoint(const ON_4dPoint&) = default;
|
|
ON_4dPoint& operator=(const ON_4dPoint&) = default;
|
|
|
|
public:
|
|
static const ON_4dPoint Zero; // (0,0,0,0)
|
|
static const ON_4dPoint Nan; // (ON_DBL_QNAN,ON_DBL_QNAN,ON_DBL_QNAN,ON_DBL_QNAN)
|
|
|
|
explicit ON_4dPoint(double x,double y,double z,double w);
|
|
|
|
// These constructors are not explicit because no informtion is lost.
|
|
ON_4dPoint(const ON_2dPoint& ); // from 2d point (z,y,0,1)
|
|
ON_4dPoint(const ON_3dPoint& ); // from 3d point (x,y,z,1)
|
|
ON_4dPoint(const ON_2dVector& ); // from 2d vector (x,y,0,0)
|
|
ON_4dPoint(const ON_3dVector& ); // from 3d vector (x,y,z,0)
|
|
|
|
explicit ON_4dPoint(const double*); // from double[4] array
|
|
|
|
// These constructors are not explicit because no informtion is lost.
|
|
ON_4dPoint(const ON_2fPoint& ); // from 2f point (z,y,0,1)
|
|
ON_4dPoint(const ON_3fPoint& ); // from 3f point (x,y,z,1)
|
|
ON_4dPoint(const ON_4fPoint& ); // from 4f point
|
|
ON_4dPoint(const ON_2fVector& ); // from 2f vector (z,y,0,0)
|
|
ON_4dPoint(const ON_3fVector& ); // from 3f vector (x,y,z,0)
|
|
|
|
explicit ON_4dPoint(const float*); // from float[4] array
|
|
|
|
/*
|
|
Description:
|
|
This function is provided because in rare cases it makes sense.
|
|
If you are not certian why you want this value, think carefully
|
|
or work with vectors and points in Euclidean coordinates.
|
|
Returns:
|
|
lhs.x*rhs.x + lhs.y*rhs.y + lhs.z*rhs.z + lhs.w*rhs.w;
|
|
Remark:
|
|
It is intentional that there is no operator* override for ON_4dPoint.
|
|
This intentional omission helps people pause and think before calling
|
|
ON_4dPoint::InnerProduct().
|
|
*/
|
|
static double InnerProduct(
|
|
const ON_4dPoint& lhs,
|
|
const ON_4dPoint& rhs
|
|
);
|
|
|
|
// (double*) conversion operators
|
|
operator double*();
|
|
operator const double*() const;
|
|
|
|
// use implicit operator=(const ON_4dPoint&)
|
|
ON_4dPoint& operator=(const ON_2dPoint&);
|
|
ON_4dPoint& operator=(const ON_3dPoint&);
|
|
ON_4dPoint& operator=(const ON_2dVector&);
|
|
ON_4dPoint& operator=(const ON_3dVector&);
|
|
ON_4dPoint& operator=(const double*); // point = double[4] support
|
|
|
|
ON_4dPoint& operator=(const class ON_2fPoint&);
|
|
ON_4dPoint& operator=(const class ON_3fPoint&);
|
|
ON_4dPoint& operator=(const class ON_4fPoint&);
|
|
ON_4dPoint& operator=(const class ON_2fVector&);
|
|
ON_4dPoint& operator=(const class ON_3fVector&);
|
|
ON_4dPoint& operator=(const float*); // point = float[4] support
|
|
|
|
ON_4dPoint& operator*=(double);
|
|
ON_4dPoint& operator/=(double);
|
|
ON_4dPoint& operator+=(const ON_4dPoint&); // sum w = sqrt(|w1*w2|)
|
|
ON_4dPoint& operator-=(const ON_4dPoint&); // difference w = sqrt(|w1*w2|)
|
|
|
|
ON_4dPoint operator*(double) const;
|
|
ON_4dPoint operator/(double) const;
|
|
ON_4dPoint operator+(const ON_4dPoint&) const; // sum w = sqrt(|w1*w2|)
|
|
ON_4dPoint operator-(const ON_4dPoint&) const; // difference w = sqrt(|w1*w2|)
|
|
|
|
ON_4dPoint operator*(const ON_Xform&) const;
|
|
|
|
/*
|
|
Description:
|
|
A well ordered projective compare function that is nan aware and can
|
|
be used for robust sorting.
|
|
Remarks:
|
|
double c = non-nan value.
|
|
ON_4dPoint h0 = ...;
|
|
ON_4dPoint h1(c*h0.x,c*h0.x,c*h0.x,c*h0.x);
|
|
0 == ON_4dPoint::ProjectiveCompare(h0,ha);
|
|
*/
|
|
static int ProjectiveCompare(
|
|
const ON_4dPoint& lhs,
|
|
const ON_4dPoint& rhs
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
A well ordered dictionary compare function that is nan aware and can
|
|
be used for robust sorting.
|
|
*/
|
|
static int DictionaryCompare(
|
|
const ON_4dPoint& lhs,
|
|
const ON_4dPoint& rhs
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
True if (lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z && lhs.w == rhs.w).
|
|
*/
|
|
bool operator==(const ON_4dPoint& rhs) const;
|
|
|
|
/*
|
|
Returns:
|
|
True if lhs.* != rhs.* for some coordinate and no values are nans.
|
|
*/
|
|
bool operator!=(const ON_4dPoint& rhs) const;
|
|
|
|
public:
|
|
// index operators mimic double[4] behavior
|
|
double& operator[](int);
|
|
double operator[](int) const;
|
|
double& operator[](unsigned int);
|
|
double operator[](unsigned int) const;
|
|
|
|
/*
|
|
Returns:
|
|
False if any coordinate is infinte, a nan, or ON_UNSET_VALUE.
|
|
*/
|
|
bool IsValid() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
|
|
*/
|
|
bool IsUnset() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is a nan.
|
|
*/
|
|
bool IsNan() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is ON_UNSET_VALUE, ON_UNSET_POSITIVE_VALUE, or a nan
|
|
*/
|
|
bool IsUnsetOrNan() const;
|
|
|
|
// set 4d point value
|
|
void Set(double x,double y,double z,double w);
|
|
|
|
int MaximumCoordinateIndex() const;
|
|
double MaximumCoordinate() const; // absolute value of maximum coordinate
|
|
|
|
int MinimumCoordinateIndex() const;
|
|
double MinimumCoordinate() const; // absolute value of minimum coordinate
|
|
|
|
bool Normalize(); // set so x^2 + y^2 + z^2 + w^2 = 1
|
|
|
|
// These transform the point in place. The transformation matrix acts on
|
|
// the left of the point; i.e., result = transformation*point
|
|
void Transform(
|
|
const ON_Xform&
|
|
);
|
|
|
|
ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
|
|
};
|
|
|
|
ON_DECL
|
|
ON_4dPoint operator*(double, const ON_4dPoint&);
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// ON_2dVector
|
|
//
|
|
class ON_CLASS ON_2dVector
|
|
{
|
|
public:
|
|
double x, y;
|
|
|
|
public:
|
|
// x,y not initialized
|
|
ON_2dVector() = default;
|
|
~ON_2dVector() = default;
|
|
ON_2dVector(const ON_2dVector&) = default;
|
|
ON_2dVector& operator=(const ON_2dVector&) = default;
|
|
|
|
public:
|
|
static const ON_2dVector ZeroVector; // (0.0,0.0)
|
|
static const ON_2dVector XAxis; // (1.0,0.0)
|
|
static const ON_2dVector YAxis; // (0.0,1.0)
|
|
static const ON_2dVector UnsetVector; // (ON_UNSET_VALUE,ON_UNSET_VALUE)
|
|
static const ON_2dVector NanVector; // (ON_DBL_QNAN,ON_DBL_QNAN)
|
|
|
|
/*
|
|
Description:
|
|
A well ordered dictionary compare function that is nan aware and can
|
|
be used for robust sorting.
|
|
*/
|
|
static int Compare(
|
|
const ON_2dVector& lhs,
|
|
const ON_2dVector& rhs
|
|
);
|
|
|
|
// Description:
|
|
// A index driven function to get unit axis vectors.
|
|
// Parameters:
|
|
// index - [in] 0 returns (1,0), 1 returns (0,1)
|
|
// Returns:
|
|
// Unit 2d vector with vector[i] = (i==index)?1:0;
|
|
static const ON_2dVector& UnitVector(
|
|
int // index
|
|
);
|
|
|
|
explicit ON_2dVector(double x,double y);
|
|
|
|
explicit ON_2dVector(const ON_3dVector& ); // from 3d vector
|
|
ON_2dVector(const ON_2dPoint& ); // from 2d point
|
|
explicit ON_2dVector(const ON_3dPoint& ); // from 3d point
|
|
explicit ON_2dVector(const double*); // from double[2] array
|
|
|
|
ON_2dVector(const ON_2fVector& ); // from 2f vector
|
|
explicit ON_2dVector(const ON_3fVector& ); // from 3f vector
|
|
explicit ON_2dVector(const ON_2fPoint& ); // from 2f point
|
|
explicit ON_2dVector(const ON_3fPoint& ); // from 3f point
|
|
explicit ON_2dVector(const float*); // from double[2] array
|
|
|
|
// (double*) conversion operators
|
|
operator double*();
|
|
operator const double*() const;
|
|
|
|
// use implicit operator=(const ON_2dVector&)
|
|
ON_2dVector& operator=(const ON_3dVector&);
|
|
ON_2dVector& operator=(const ON_2dPoint&);
|
|
ON_2dVector& operator=(const ON_3dPoint&);
|
|
ON_2dVector& operator=(const double*); // vector = double[2] support
|
|
|
|
ON_2dVector& operator=(const ON_2fVector&);
|
|
ON_2dVector& operator=(const ON_3fVector&);
|
|
ON_2dVector& operator=(const ON_2fPoint&);
|
|
ON_2dVector& operator=(const ON_3fPoint&);
|
|
ON_2dVector& operator=(const float*); // vector = float[2] support
|
|
|
|
ON_2dVector operator-() const;
|
|
|
|
ON_2dVector& operator*=(double);
|
|
ON_2dVector& operator/=(double);
|
|
ON_2dVector& operator+=(const ON_2dVector&);
|
|
ON_2dVector& operator-=(const ON_2dVector&);
|
|
// DO NOT ADD ANY MORE overrides of += or -=
|
|
|
|
double operator*(const ON_2dVector&) const; // inner (dot) product
|
|
double operator*(const ON_2dPoint&) const; // inner (dot) product (point acting as vector)
|
|
double operator*(const ON_2fVector&) const; // inner (dot) product
|
|
|
|
ON_2dVector operator*(int) const;
|
|
ON_2dVector operator/(int) const;
|
|
ON_2dVector operator*(float) const;
|
|
ON_2dVector operator/(float) const;
|
|
ON_2dVector operator*(double) const;
|
|
ON_2dVector operator/(double) const;
|
|
|
|
ON_2dVector operator+(const ON_2dVector&) const;
|
|
ON_2dPoint operator+(const ON_2dPoint&) const;
|
|
ON_2dVector operator-(const ON_2dVector&) const;
|
|
ON_2dPoint operator-(const ON_2dPoint&) const;
|
|
ON_3dVector operator+(const ON_3dVector&) const;
|
|
ON_3dPoint operator+(const ON_3dPoint&) const;
|
|
ON_3dVector operator-(const ON_3dVector&) const;
|
|
ON_3dPoint operator-(const ON_3dPoint&) const;
|
|
|
|
ON_2dVector operator+(const ON_2fVector&) const;
|
|
ON_2dPoint operator+(const ON_2fPoint&) const;
|
|
ON_2dVector operator-(const ON_2fVector&) const;
|
|
ON_2dPoint operator-(const ON_2fPoint&) const;
|
|
ON_3dVector operator+(const ON_3fVector&) const;
|
|
ON_3dPoint operator+(const ON_3fPoint&) const;
|
|
ON_3dVector operator-(const ON_3fVector&) const;
|
|
ON_3dPoint operator-(const ON_3fPoint&) const;
|
|
|
|
ON_2dVector operator*(const ON_Xform&) const;
|
|
|
|
bool operator==(const ON_2dVector&) const;
|
|
bool operator!=(const ON_2dVector&) const;
|
|
|
|
// dictionary order comparisons
|
|
bool operator<=(const ON_2dVector&) const;
|
|
bool operator>=(const ON_2dVector&) const;
|
|
bool operator<(const ON_2dVector&) const;
|
|
bool operator>(const ON_2dVector&) const;
|
|
|
|
// index operators mimic double[2] behavior
|
|
double& operator[](int);
|
|
double operator[](int) const;
|
|
double& operator[](unsigned int);
|
|
double operator[](unsigned int) const;
|
|
|
|
/*
|
|
Returns:
|
|
False if any coordinate is infinte, a nan, or ON_UNSET_VALUE.
|
|
*/
|
|
bool IsValid() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
|
|
*/
|
|
bool IsUnset() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is a nan.
|
|
*/
|
|
bool IsNan() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is ON_UNSET_VALUE, ON_UNSET_POSITIVE_VALUE, or a nan
|
|
*/
|
|
bool IsUnsetOrNan() const;
|
|
|
|
// set 2d vector value
|
|
void Set(double x,double y);
|
|
|
|
int MaximumCoordinateIndex() const;
|
|
double MaximumCoordinate() const; // absolute value of maximum coordinate
|
|
|
|
int MinimumCoordinateIndex() const;
|
|
double MinimumCoordinate() const; // absolute value of minimum coordinate
|
|
|
|
double LengthSquared() const;
|
|
double Length() const;
|
|
|
|
// Signed area of the parallelagram. The volume element.
|
|
// returns x*B.y - y*B.x
|
|
double WedgeProduct(const ON_2dVector& B) const;
|
|
|
|
bool Decompose( // Computes a, b such that this vector = a*X + b*Y
|
|
// Returns false if unable to solve for a,b. This happens
|
|
// when X,Y is not really a basis.
|
|
//
|
|
// If X,Y is known to be an orthonormal frame,
|
|
// then a = V*X, b = V*Y will compute
|
|
// the same result more quickly.
|
|
const ON_2dVector&, // X
|
|
const ON_2dVector&, // Y
|
|
double*, // a
|
|
double* // b
|
|
) const;
|
|
|
|
int IsParallelTo(
|
|
// returns 1: this and other vectors are parallel
|
|
// -1: this and other vectors are anti-parallel
|
|
// 0: this and other vectors are not parallel
|
|
// or at least one of the vectors is zero
|
|
const ON_2dVector& other, // other vector
|
|
double angle_tolerance = ON_DEFAULT_ANGLE_TOLERANCE // optional angle tolerance (radians)
|
|
) const;
|
|
|
|
bool IsPerpendicularTo(
|
|
// returns true: this and other vectors are perpendicular
|
|
// false: this and other vectors are not perpendicular
|
|
// or at least one of the vectors is zero
|
|
const ON_2dVector& other, // other vector
|
|
double angle_tolerance = ON_DEFAULT_ANGLE_TOLERANCE // optional angle tolerance (radians)
|
|
) const;
|
|
|
|
ON_DEPRECATED_MSG("Use v = ON_2dVector::ZeroVector;")
|
|
void Zero(); // set all coordinates to zero;
|
|
|
|
ON_DEPRECATED_MSG("Use v = -v;")
|
|
void Reverse(); // negate all coordinates
|
|
|
|
bool Unitize(); // returns false if vector has zero length
|
|
|
|
/*
|
|
Returns:
|
|
If this is a valid non-zero vector, a unit vector parallel to this is returned.
|
|
Otherwise the zero vector is returned.
|
|
*/
|
|
ON_2dVector UnitVector() const;
|
|
|
|
|
|
// Description:
|
|
// Test a vector to see if it is very short
|
|
//
|
|
// Parameters:
|
|
// tiny_tol - [in] (default = ON_ZERO_TOLERANCE) a nonzero
|
|
// value used as the coordinate zero tolerance.
|
|
//
|
|
// Returns:
|
|
// ( fabs(x) <= tiny_tol && fabs(y) <= tiny_tol )
|
|
//
|
|
bool IsTiny(
|
|
double tiny_tol = ON_ZERO_TOLERANCE // tiny_tol
|
|
) const;
|
|
|
|
// Returns:
|
|
// true if vector is the zero vector.
|
|
bool IsZero() const;
|
|
|
|
/*
|
|
Returns:
|
|
true if at lease one coordinate is not zero and no coordinates are unset or nans.
|
|
*/
|
|
bool IsNotZero() const;
|
|
|
|
// Returns:
|
|
// true if vector is valid and has length 1.
|
|
bool IsUnitVector() const;
|
|
|
|
// set this vector to be perpendicular to another vector
|
|
bool PerpendicularTo( // Result is not unitized.
|
|
// returns false if input vector is zero
|
|
const ON_2dVector&
|
|
);
|
|
|
|
// set this vector to be perpendicular to a line defined by 2 points
|
|
bool PerpendicularTo(
|
|
const ON_2dPoint&,
|
|
const ON_2dPoint&
|
|
);
|
|
|
|
// These transform the vector in place. The transformation matrix acts on
|
|
// the left of the vector; i.e., result = transformation*vector
|
|
void Transform(
|
|
const ON_Xform& // can use ON_Xform here
|
|
);
|
|
|
|
void Rotate(
|
|
double angle // angle in radians
|
|
);
|
|
|
|
void Rotate(
|
|
double sin_angle, // sin(angle)
|
|
double cos_angle // cos(angle)
|
|
);
|
|
|
|
ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
|
|
};
|
|
|
|
ON_DECL
|
|
ON_2dVector operator*(int, const ON_2dVector&);
|
|
|
|
ON_DECL
|
|
ON_2dVector operator*(float, const ON_2dVector&);
|
|
|
|
ON_DECL
|
|
ON_2dVector operator*(double, const ON_2dVector&);
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
//
|
|
// ON_2dVector utilities
|
|
//
|
|
|
|
ON_DECL
|
|
double
|
|
ON_DotProduct(
|
|
const ON_2dVector&,
|
|
const ON_2dVector&
|
|
);
|
|
|
|
ON_DECL
|
|
ON_3dVector
|
|
ON_CrossProduct(
|
|
const ON_2dVector&,
|
|
const ON_2dVector&
|
|
);
|
|
|
|
ON_DECL
|
|
double
|
|
ON_WedgeProduct( // signed area of the parallelagram. Volume element.
|
|
const ON_2dVector& A, // returns A.x * B.y - A.y * B.x
|
|
const ON_2dVector& B
|
|
);
|
|
|
|
ON_DECL
|
|
bool
|
|
ON_IsOrthogonalFrame( // true if X, Y are nonzero and mutually perpendicular
|
|
const ON_2dVector&, // X
|
|
const ON_2dVector& // Y
|
|
);
|
|
|
|
ON_DECL
|
|
bool
|
|
ON_IsOrthonormalFrame( // true if X, Y are orthogonal and unit length
|
|
const ON_2dVector&, // X
|
|
const ON_2dVector& // Y
|
|
);
|
|
|
|
ON_DECL
|
|
bool
|
|
ON_IsRightHandFrame( // true if X, Y are orthonormal and right handed
|
|
const ON_2dVector&, // X
|
|
const ON_2dVector& // Y
|
|
);
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// ON_3dVector
|
|
//
|
|
class ON_CLASS ON_3dVector
|
|
{
|
|
public:
|
|
double x, y, z;
|
|
|
|
public:
|
|
// x,y,z not initialized
|
|
ON_3dVector() = default;
|
|
~ON_3dVector() = default;
|
|
ON_3dVector(const ON_3dVector&) = default;
|
|
ON_3dVector& operator=(const ON_3dVector&) = default;
|
|
|
|
public:
|
|
static const ON_3dVector ZeroVector; // (0.0,0.0,0.0)
|
|
static const ON_3dVector XAxis; // (1.0,0.0,0.0)
|
|
static const ON_3dVector YAxis; // (0.0,1.0,0.0)
|
|
static const ON_3dVector ZAxis; // (0.0,0.0,1.0)
|
|
static const ON_3dVector UnsetVector; // (ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE)
|
|
static const ON_3dVector NanVector; // (ON_DBL_QNAN,ON_DBL_QNAN,ON_DBL_QNAN)
|
|
|
|
/*
|
|
Description:
|
|
A well ordered dictionary compare function that is nan aware and can
|
|
be used for robust sorting.
|
|
*/
|
|
static int Compare(
|
|
const ON_3dVector& lhs,
|
|
const ON_3dVector& rhs
|
|
);
|
|
|
|
// Description:
|
|
// A index driven function to get unit axis vectors.
|
|
// Parameters:
|
|
// index - [in] 0 returns (1,0,0), 1 returns (0,1,0),
|
|
// 2 returns (0,0,1)
|
|
// Returns:
|
|
// Unit 3d vector with vector[i] = (i==index)?1:0;
|
|
static const ON_3dVector& UnitVector(
|
|
int // index
|
|
);
|
|
|
|
explicit ON_3dVector(double x,double y,double z);
|
|
#if defined(OPENNURBS_WALL)
|
|
// Goal is to eventually have all constructors that change dimension be explicit.
|
|
explicit
|
|
#endif
|
|
ON_3dVector(const ON_2dVector& ); // from 2d vector
|
|
explicit ON_3dVector(const ON_2dPoint& ); // from 2d point
|
|
ON_3dVector(const ON_3dPoint& ); // from 3d point
|
|
explicit ON_3dVector(const double*); // from double[3] array
|
|
|
|
explicit ON_3dVector(const ON_2fVector& ); // from 2f vector
|
|
ON_3dVector(const ON_3fVector& ); // from 3f vector
|
|
explicit ON_3dVector(const ON_2fPoint& ); // from 2f point
|
|
explicit ON_3dVector(const ON_3fPoint& ); // from 3f point
|
|
explicit ON_3dVector(const float*); // from float[3] array
|
|
|
|
// (double*) conversion operators
|
|
operator double*();
|
|
operator const double*() const;
|
|
|
|
// use implicit operator=(const ON_3dVector&)
|
|
ON_3dVector& operator=(const ON_2dVector&);
|
|
ON_3dVector& operator=(const ON_2dPoint&);
|
|
ON_3dVector& operator=(const ON_3dPoint&);
|
|
ON_3dVector& operator=(const double*); // vector = double[3] support
|
|
|
|
ON_3dVector& operator=(const ON_2fVector&);
|
|
ON_3dVector& operator=(const ON_3fVector&);
|
|
ON_3dVector& operator=(const ON_2fPoint&);
|
|
ON_3dVector& operator=(const ON_3fPoint&);
|
|
ON_3dVector& operator=(const float*); // vector = float[3] support
|
|
|
|
ON_3dVector operator-() const;
|
|
|
|
ON_3dVector& operator*=(double);
|
|
ON_3dVector& operator/=(double);
|
|
ON_3dVector& operator+=(const ON_3dVector&);
|
|
ON_3dVector& operator-=(const ON_3dVector&);
|
|
// DO NOT ADD ANY MORE overrides of += or -=
|
|
|
|
double operator*(const ON_3dVector&) const; // inner (dot) product
|
|
double operator*(const ON_3dPoint&) const; // inner (dot) product
|
|
double operator*(const ON_3fVector&) const; // inner (dot) product
|
|
|
|
ON_3dVector operator*(int) const;
|
|
ON_3dVector operator/(int) const;
|
|
ON_3dVector operator*(float) const;
|
|
ON_3dVector operator/(float) const;
|
|
ON_3dVector operator*(double) const;
|
|
ON_3dVector operator/(double) const;
|
|
|
|
ON_3dVector operator+(const ON_3dVector&) const;
|
|
ON_3dPoint operator+(const ON_3dPoint&) const;
|
|
ON_3dVector operator-(const ON_3dVector&) const;
|
|
ON_3dPoint operator-(const ON_3dPoint&) const;
|
|
ON_3dVector operator+(const ON_2dVector&) const;
|
|
ON_3dPoint operator+(const ON_2dPoint&) const;
|
|
ON_3dVector operator-(const ON_2dVector&) const;
|
|
ON_3dPoint operator-(const ON_2dPoint&) const;
|
|
|
|
ON_3dVector operator+(const ON_3fVector&) const;
|
|
ON_3dPoint operator+(const ON_3fPoint&) const;
|
|
ON_3dVector operator-(const ON_3fVector&) const;
|
|
ON_3dPoint operator-(const ON_3fPoint&) const;
|
|
ON_3dVector operator+(const ON_2fVector&) const;
|
|
ON_3dPoint operator+(const ON_2fPoint&) const;
|
|
ON_3dVector operator-(const ON_2fVector&) const;
|
|
ON_3dPoint operator-(const ON_2fPoint&) const;
|
|
|
|
ON_3dVector operator*(const ON_Xform&) const;
|
|
|
|
bool operator==(const ON_3dVector&) const;
|
|
bool operator!=(const ON_3dVector&) const;
|
|
|
|
// dictionary order comparisons
|
|
bool operator<=(const ON_3dVector&) const;
|
|
bool operator>=(const ON_3dVector&) const;
|
|
bool operator<(const ON_3dVector&) const;
|
|
bool operator>(const ON_3dVector&) const;
|
|
|
|
// index operators mimic double[3] behavior
|
|
double& operator[](int);
|
|
double operator[](int) const;
|
|
double& operator[](unsigned int);
|
|
double operator[](unsigned int) const;
|
|
|
|
static double DotProduct(
|
|
ON_3dVector A,
|
|
ON_3dVector B
|
|
);
|
|
|
|
static const ON_3dVector CrossProduct(
|
|
ON_3dVector A,
|
|
ON_3dVector B
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
False if any coordinate is infinte, a nan, or ON_UNSET_VALUE.
|
|
*/
|
|
bool IsValid() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is ON_UNSET_VALUE or ON_UNSET_POSITIVE_VALUE
|
|
*/
|
|
bool IsUnset() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is a nan.
|
|
*/
|
|
bool IsNan() const;
|
|
|
|
/*
|
|
Returns:
|
|
True if any coordinate is ON_UNSET_VALUE, ON_UNSET_POSITIVE_VALUE, or a nan
|
|
*/
|
|
bool IsUnsetOrNan() const;
|
|
|
|
// set 3d vector value
|
|
void Set(double x,double y,double z);
|
|
|
|
int MaximumCoordinateIndex() const;
|
|
double MaximumCoordinate() const; // absolute value of maximum coordinate
|
|
|
|
int MinimumCoordinateIndex() const;
|
|
double MinimumCoordinate() const; // absolute value of minimum coordinate
|
|
|
|
double LengthSquared() const;
|
|
double Length() const;
|
|
|
|
bool Decompose( // Computes a, b, c such that this vector = a*X + b*Y + c*Z
|
|
// Returns false if unable to solve for a,b,c. This happens
|
|
// when X,Y,Z is not really a basis.
|
|
//
|
|
// If X,Y,Z is known to be an orthonormal frame,
|
|
// then a = V*X, b = V*Y, c = V*Z will compute
|
|
// the same result more quickly.
|
|
const ON_3dVector&, // X
|
|
const ON_3dVector&, // Y
|
|
const ON_3dVector&, // Z
|
|
double*, // a
|
|
double*, // b
|
|
double* // c
|
|
) const;
|
|
|
|
int IsParallelTo(
|
|
// returns 1: this and other vectors are parallel
|
|
// -1: this and other vectors are anti-parallel
|
|
// 0: this and other vectors are not parallel
|
|
// or at least one of the vectors is zero
|
|
const ON_3dVector& other, // other vector
|
|
double angle_tolerance = ON_DEFAULT_ANGLE_TOLERANCE // optional angle tolerance (radians)
|
|
) const;
|
|
|
|
bool IsPerpendicularTo(
|
|
// returns true: this and other vectors are perpendicular
|
|
// false: this and other vectors are not perpendicular
|
|
// or at least one of the vectors is zero
|
|
const ON_3dVector& other, // other vector
|
|
double angle_tolerance = ON_DEFAULT_ANGLE_TOLERANCE // optional angle tolerance (radians)
|
|
) const;
|
|
|
|
double Fuzz( double tolerance = ON_ZERO_TOLERANCE ) const; // tolerance to use when comparing 3d vectors
|
|
|
|
#if defined(OPENNURBS_WALL)
|
|
// Goal is to eventually remove all functions that modify vectors in place.
|
|
ON_DEPRECATED_MSG("Use v = ON_3dVector::ZeroVector;")
|
|
#endif
|
|
void Zero(); // set all coordinates to zero;
|
|
|
|
#if defined(OPENNURBS_WALL)
|
|
// Goal is to eventually remove all functions that modify vectors in place.
|
|
ON_DEPRECATED_MSG("Use v = -v;")
|
|
#endif
|
|
void Reverse(); // negate all coordinates
|
|
|
|
bool Unitize(); // returns false if vector has zero length
|
|
double LengthAndUnitize(); // unitizes and returns initial length
|
|
|
|
/*
|
|
Returns:
|
|
If this is a valid non-zero vector, a unit vector parallel to this is returned.
|
|
Otherwise the zero vector is returned.
|
|
*/
|
|
ON_3dVector UnitVector() const;
|
|
|
|
// Description:
|
|
// Test a vector to see if it is very short
|
|
//
|
|
// Parameters:
|
|
// tiny_tol - [in] (default = ON_ZERO_TOLERANCE) a nonzero
|
|
// value used as the coordinate zero tolerance.
|
|
//
|
|
// Returns:
|
|
// ( fabs(x) <= tiny_tol && fabs(y) <= tiny_tol && fabs(z) <= tiny_tol )
|
|
//
|
|
bool IsTiny(
|
|
double tiny_tol = ON_ZERO_TOLERANCE // tiny_tol
|
|
) const;
|
|
|
|
// Returns:
|
|
// true if vector is the zero vector.
|
|
bool IsZero() const;
|
|
|
|
/*
|
|
Returns:
|
|
true if at lease one coordinate is not zero and no coordinates are unset or nans.
|
|
*/
|
|
bool IsNotZero() const;
|
|
|
|
|
|
// Returns:
|
|
// true if vector is valid and has length 1.
|
|
bool IsUnitVector() const;
|
|
|
|
// set this vector to be perpendicular to another vector
|
|
bool PerpendicularTo( // Result is not unitized.
|
|
// returns false if input vector is zero
|
|
const ON_3dVector&
|
|
);
|
|
|
|
// set this vector to be perpendicular to a plane defined by 3 points
|
|
bool PerpendicularTo(
|
|
// about 3 times slower than
|
|
// ON_3dVector N = ON_CrossProduct(P1-P0,P2-P0);
|
|
// N.Unitize();
|
|
// returns false if points are coincident or collinear
|
|
const ON_3dPoint&, const ON_3dPoint&, const ON_3dPoint&
|
|
);
|
|
|
|
/*
|
|
Parameters:
|
|
failure_result - [in]
|
|
vector to return if this is zero or unset.
|
|
When in doubt, pass ON_3dVector::NanVector.
|
|
Returns:
|
|
If this is nonzero, a vector perpindicular to this.
|
|
The returned vector is not unitized.
|
|
Otherwise failure_result is returned.
|
|
*/
|
|
const ON_3dVector Perpendicular(
|
|
ON_3dVector failure_result
|
|
) const;
|
|
|
|
// These transform the vector in place. The transformation matrix acts on
|
|
// the left of the vector; i.e., result = transformation*vector
|
|
void Transform(
|
|
const ON_Xform& // can use ON_Xform here
|
|
);
|
|
|
|
void Rotate(
|
|
double angle, // angle in radians
|
|
const ON_3dVector& axis // axis of rotation
|
|
);
|
|
|
|
void Rotate(
|
|
double sin_angle, // sin(angle)
|
|
double cos_angle, // cos(angle)
|
|
const ON_3dVector& axis // axis of rotation
|
|
);
|
|
|
|
ON__UINT32 DataCRC(ON__UINT32 current_remainder) const;
|
|
};
|
|
|
|
class ON_CLASS ON_3dRay
|
|
{
|
|
public:
|
|
ON_3dPoint m_P;
|
|
ON_3dVector m_V;
|
|
};
|
|
|
|
/*
|
|
Description:
|
|
Typically the vector portion is a unit vector and
|
|
m_d = -(x*P.x + y*P.y + z*P.z) for a point P on the plane.
|
|
*/
|
|
class ON_CLASS ON_PlaneEquation
|
|
{
|
|
public:
|
|
// C++ defaults for construction, destruction, copys, and operator=
|
|
// work fine.
|
|
|
|
static const ON_PlaneEquation UnsetPlaneEquation; // (ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE,ON_UNSET_VALUE)
|
|
static const ON_PlaneEquation ZeroPlaneEquation; // (0.0,0.0,0.0,0.0)
|
|
static const ON_PlaneEquation NanPlaneEquation; // (ON_DBL_QNAN,ON_DBL_QNAN,ON_DBL_QNAN,ON_DBL_QNAN)
|
|
|
|
static const ON_PlaneEquation WorldXY; // (0,0,1,0)
|
|
static const ON_PlaneEquation WorldYZ; // (1,0,0,0)
|
|
static const ON_PlaneEquation WorldZX; // (0,1,0,0)
|
|
|
|
/*
|
|
Returns:
|
|
If the three points are valid and not colinear, a unitized plane equation is returned.
|
|
Otherwise ON_PlaneEquation::NanPlaneEquation is returned.
|
|
*/
|
|
static const ON_PlaneEquation CreateFromThreePoints(
|
|
ON_3dPoint pointA,
|
|
ON_3dPoint pointB,
|
|
ON_3dPoint pointC
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
If point is valid and normal is nonzero, a unitized plane equation is returned.
|
|
Otherwise ON_PlaneEquation::NanPlaneEquation is returned.
|
|
*/
|
|
static const ON_PlaneEquation CreateFromPointAndNormal(
|
|
ON_3dPoint point,
|
|
ON_3dVector normal
|
|
);
|
|
|
|
ON_PlaneEquation();
|
|
|
|
ON_PlaneEquation(
|
|
double xx, double yy, double zz, double dd
|
|
);
|
|
|
|
static void Set(
|
|
ON_PlaneEquation& plane_equation,
|
|
double x, double y, double z, double d
|
|
);
|
|
|
|
double MaximumCoefficient() const;
|
|
|
|
/*
|
|
Returns:
|
|
The plane equation whose coefficient values are
|
|
the negative of the coefficent values in this,
|
|
provided the coeffient value is valid. Any invalid
|
|
coefficent values are copied.
|
|
*/
|
|
ON_PlaneEquation NegatedPlaneEquation() const;
|
|
|
|
|
|
/*
|
|
Returns:
|
|
The plane equation whose first three coefficient values
|
|
are a unit vector.
|
|
*/
|
|
ON_PlaneEquation UnitizedPlaneEquation() const;
|
|
|
|
|
|
|
|
/*
|
|
Description:
|
|
returns true if x, y, z, d are valid, finite doubles.
|
|
Remarks:
|
|
this function will return true if x, y and z are all zero.
|
|
See Also:
|
|
ON_PlaneEquation::IsSet().
|
|
*/
|
|
bool IsValid() const;
|
|
|
|
/*
|
|
Description:
|
|
returns true if x, y, z, d are valid, finite doubles and at least one of x, y or z is not zero.
|
|
*/
|
|
bool IsSet() const;
|
|
|
|
/*
|
|
Description:
|
|
returns true if x, y, z, d are valid, finite doubles and x^2 + y^2 + z^2 = 1.
|
|
*/
|
|
bool IsUnitized() const;
|
|
|
|
/*
|
|
Description:
|
|
Sets (x,y,z) to a unitized N and then sets
|
|
d = -(x*P.x + y*P.y + z*P.z).
|
|
Parameters:
|
|
P - [in] point on the plane
|
|
N - [in] vector perpendicular to the plane
|
|
Returns:
|
|
true if input is valid.
|
|
*/
|
|
bool Create( ON_3dPoint P, ON_3dVector N );
|
|
|
|
// index operators mimic double[4] behavior
|
|
// Return null refs or ON_UNSET_VALUE for out-of-range indices
|
|
double& operator[](int);
|
|
double& operator[](unsigned int);
|
|
double operator[](int) const;
|
|
double operator[](unsigned int) const;
|
|
|
|
/*
|
|
Returns:
|
|
Direction (x,y,z)
|
|
*/
|
|
ON_3dVector Direction() const;
|
|
|
|
double DirectionLength() const;
|
|
|
|
/*
|
|
Returns:
|
|
Unitized direction or zero vector if not set.
|
|
*/
|
|
ON_3dVector UnitNormal() const;
|
|
|
|
/*
|
|
Returns 1: this and other vectors are parallel
|
|
-1: this and other vectors are anti-parallel
|
|
0: this and other vectors are not parallel
|
|
or at least one of the vectors is zero
|
|
*/
|
|
int IsParallelTo(
|
|
const ON_PlaneEquation& other, // other plane equation
|
|
double angle_tolerance = ON_DEFAULT_ANGLE_TOLERANCE // optional angle tolerance (radians)
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Evaluate the plane at a point.
|
|
Parameters:
|
|
P - [in]
|
|
Returns:
|
|
x*P.x + y*P.y + z*P.z + d;
|
|
*/
|
|
double ValueAt(ON_3dPoint P) const;
|
|
double ValueAt(ON_4dPoint P) const;
|
|
double ValueAt(ON_3dVector P) const;
|
|
double ValueAt(double x, double y, double z) const;
|
|
|
|
/*
|
|
Returns:
|
|
ON_Interval::EmptyInterval if input is not valid.
|
|
*/
|
|
ON_Interval ValueRange(
|
|
size_t point_list_count,
|
|
const ON_3dPoint* point_list
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
ON_Interval::EmptyInterval if input is not valid.
|
|
*/
|
|
ON_Interval ValueRange(
|
|
const ON_SimpleArray< ON_3dPoint >& point_list
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
ON_Interval::EmptyInterval if input is not valid.
|
|
*/
|
|
ON_Interval ValueRange(
|
|
size_t point_list_count,
|
|
const ON_3fPoint* point_list
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
ON_Interval::EmptyInterval if input is not valid.
|
|
*/
|
|
ON_Interval ValueRange(
|
|
const ON_SimpleArray< ON_3fPoint >& point_list
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
ON_Interval::EmptyInterval if input is not valid.
|
|
*/
|
|
ON_Interval ValueRange(
|
|
const class ON_3dPointListRef& point_list
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
ON_Interval::EmptyInterval if input is not valid.
|
|
*/
|
|
ON_Interval ValueRange(
|
|
size_t point_index_count,
|
|
const unsigned int* point_index_list,
|
|
const class ON_3dPointListRef& point_list
|
|
) const;
|
|
|
|
ON_Interval ValueRange(
|
|
size_t point_index_count,
|
|
size_t point_index_stride,
|
|
const unsigned int* point_index_list,
|
|
const class ON_3dPointListRef& point_list
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Evaluate the plane at a list of point values.
|
|
Parameters:
|
|
Pcount - [in]
|
|
number of points
|
|
P - [in]
|
|
points
|
|
value - [in]
|
|
If not null, value[] must be an array of length at least Pcount.
|
|
The values will be stored in this array. If null, the an array
|
|
will be allocated with onmalloc() and returned.
|
|
value_range - [out]
|
|
If not null, the range of values will be returned here.
|
|
Returns:
|
|
An array of Pcount values. If the input parameter value was null,
|
|
then the array is allocated on the heap using onmalloc() and the
|
|
caller is responsible for calling onfree() when finished. If the
|
|
input is not valid, null is returned.
|
|
*/
|
|
double* ValueAt(
|
|
int Pcount,
|
|
const ON_3fPoint* P,
|
|
double* value,
|
|
double value_range[2]
|
|
) const;
|
|
|
|
double* ValueAt(
|
|
int Pcount,
|
|
const ON_3dPoint* P,
|
|
double* value,
|
|
double value_range[2]
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
This function calculates and evalutes points that
|
|
would be exactly on the plane if double precision
|
|
aritmetic were mathematically perfect and returns
|
|
the largest value of the evaluations.
|
|
*/
|
|
double ZeroTolerance() const;
|
|
|
|
/*
|
|
Description:
|
|
Transform the plane equation so that, if e0 is the initial
|
|
equation, e1 is transformed equation and P is a point,
|
|
then e0.ValueAt(P) = e1.ValueAt(xform*P).
|
|
Parameters:
|
|
xform - [in]
|
|
Invertable transformation.
|
|
Returns:
|
|
True if the plane equation was successfully transformed.
|
|
False if xform is not invertable or the equation is not
|
|
valid.
|
|
Remarks:
|
|
This function has to invert xform. If you have apply the
|
|
same transformation to a bunch of planes, then it will be
|
|
more efficient to calculate xform's inverse transpose
|
|
and apply the resultingt transformation to the equation's
|
|
coefficients as if they were 4d point coordinates.
|
|
*/
|
|
bool Transform( const ON_Xform& xform );
|
|
|
|
/*
|
|
Description:
|
|
Get point on plane that is closest to a given point.
|
|
Parameters:
|
|
point - [in]
|
|
Returns:
|
|
A 3d point on the plane that is closest to the input point.
|
|
*/
|
|
ON_3dPoint ClosestPointTo( ON_3dPoint point ) const;
|
|
|
|
/*
|
|
Description:
|
|
Get the minimum value of the plane equation
|
|
on a bounding box.
|
|
Parameters:
|
|
bbox - [in]
|
|
Returns:
|
|
Minimum value of the plane equation on the bounding box.
|
|
*/
|
|
double MinimumValueAt(const ON_BoundingBox& bbox) const;
|
|
|
|
/*
|
|
Description:
|
|
Get the maximum value of the plane equation
|
|
on a bounding box.
|
|
Parameters:
|
|
bbox - [in]
|
|
Returns:
|
|
Maximum value of the plane equation on the bounding box.
|
|
*/
|
|
double MaximumValueAt(const ON_BoundingBox& bbox) const;
|
|
|
|
|
|
/*
|
|
Description:
|
|
Get the maximum value of the plane equation on a set of 3d points.
|
|
Parameters:
|
|
bRational - [in]
|
|
False if the points are euclidean (x,y,z)
|
|
True if the points are homogenous rational (x,y,z,w)
|
|
(x/w,y/w,z/w) is used to evaluate the value.
|
|
point_count - [in]
|
|
point_stride - [in]
|
|
i-th point's x coordinate = points[i*point_stride]
|
|
points - [in]
|
|
coordinates of points
|
|
stop_value - [in]
|
|
If stop_value is valid and not ON_UNSET_VALUE, then the
|
|
evaulation stops if a value > stop_value is found.
|
|
If stop_value = ON_UNSET_VALUE, then stop_value is ignored.
|
|
Returns:
|
|
Maximum value of the plane equation on the point list.
|
|
If the input is not valid, then ON_UNSET_VALUE is returned.
|
|
*/
|
|
double MaximumValueAt(
|
|
bool bRational,
|
|
int point_count,
|
|
int point_stride,
|
|
const double* points,
|
|
double stop_value
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Get the minimum value of the plane equation on a set of 3d points.
|
|
Parameters:
|
|
bRational - [in]
|
|
False if the points are euclidean (x,y,z)
|
|
True if the points are homogenous rational (x,y,z,w)
|
|
(x/w,y/w,z/w) is used to evaluate the value.
|
|
point_count - [in]
|
|
point_stride - [in]
|
|
i-th point's x coordinate = points[i*point_stride]
|
|
points - [in]
|
|
coordinates of points
|
|
stop_value - [in]
|
|
If stop_value is valid and not ON_UNSET_VALUE, then the
|
|
evaulation stops if a value < stop_value is found.
|
|
If stop_value = ON_UNSET_VALUE, then stop_value is ignored.
|
|
Returns:
|
|
Maximum value of the plane equation on the point list.
|
|
If the input is not valid, then ON_UNSET_VALUE is returned.
|
|
*/
|
|
double MinimumValueAt(
|
|
bool bRational,
|
|
int point_count,
|
|
int point_stride,
|
|
const double* points,
|
|
double stop_value
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Get the maximum absolute value of the plane equation
|
|
on a set of 3d points.
|
|
Parameters:
|
|
bRational - [in]
|
|
False if the points are euclidean (x,y,z)
|
|
True if the points are homogenous rational (x,y,z,w)
|
|
(x/w,y/w,z/w) is used to evaluate the value.
|
|
point_count - [in]
|
|
point_stride - [in]
|
|
i-th point's x coordinate = points[i*point_stride]
|
|
points - [in]
|
|
coordinates of points
|
|
stop_value - [in]
|
|
If stop_value >= 0.0, then the evaulation stops if an
|
|
absolute value > stop_value is found. If stop_value < 0.0
|
|
or stop_value is invalid, then stop_value is ignored.
|
|
Returns:
|
|
Maximum value of the plane equation on the point list.
|
|
If the input is not valid, then ON_UNSET_VALUE is returned.
|
|
*/
|
|
double MaximumAbsoluteValueAt(
|
|
bool bRational,
|
|
int point_count,
|
|
int point_stride,
|
|
const double* points,
|
|
double stop_value
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Test points on a bezier curve to see if they are near the plane.
|
|
Parameters:
|
|
bezcrv - [in]
|
|
s0 - [in]
|
|
s1 - [in] the interval from s0 to s1 is tested (s0 < s1)
|
|
sample_count - [in] number of interior points to test.
|
|
Numbers like 1, 3, 7, 15, ... work best.
|
|
endpoint_tolerance - [in] If >= 0, then the end points are
|
|
tested to see if the distance from the endpoints
|
|
is <= endpoint_tolerance.
|
|
interior_tolerance - [in] (>=0 and >=endpoint_tolerance)
|
|
This tolerance is used to test the interior sample points.
|
|
smin - [put] If not nullptr, *smin = bezier parameter of nearest
|
|
test point.
|
|
smax - [put] If not nullptr, *smax = bezier parameter of farthest
|
|
test point. If false is returned, this is the
|
|
parameter of the test point that failed.
|
|
Returns:
|
|
True if all the tested points passed the tolerance test.
|
|
False if at least one tested point failed the tolerance test.
|
|
(The test terminates when the first failure is encountered.)
|
|
*/
|
|
bool IsNearerThan(
|
|
const class ON_BezierCurve& bezcrv,
|
|
double s0,
|
|
double s1,
|
|
int sample_count,
|
|
double endpoint_tolerance,
|
|
double interior_tolerance,
|
|
double* smin,
|
|
double* smax
|
|
) const;
|
|
|
|
bool operator==(const ON_PlaneEquation&) const;
|
|
bool operator!=(const ON_PlaneEquation&) const;
|
|
|
|
double x;
|
|
double y;
|
|
double z;
|
|
double d; // 4th coefficient of the plane equation.
|
|
|
|
void Dump(class ON_TextLog&) const;
|
|
};
|
|
|
|
ON_DECL
|
|
const ON_PlaneEquation operator*(const ON_Xform&, const ON_PlaneEquation&);
|
|
|
|
|
|
#if defined(ON_DLL_TEMPLATE)
|
|
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_PlaneEquation>;
|
|
|
|
#endif
|
|
|
|
ON_DECL
|
|
ON_3dVector operator*(int, const ON_3dVector&);
|
|
|
|
ON_DECL
|
|
ON_3dVector operator*(float, const ON_3dVector&);
|
|
|
|
ON_DECL
|
|
ON_3dVector operator*(double, const ON_3dVector&);
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
//
|
|
// ON_3dVector utilities
|
|
//
|
|
|
|
ON_DECL
|
|
double
|
|
ON_DotProduct(
|
|
const ON_3dVector&,
|
|
const ON_3dVector&
|
|
);
|
|
|
|
|
|
ON_DECL
|
|
ON_3dVector
|
|
ON_CrossProduct(
|
|
const ON_3dVector&,
|
|
const ON_3dVector&
|
|
);
|
|
|
|
ON_DECL
|
|
ON_3dVector
|
|
ON_CrossProduct( // 3d cross product for old fashioned arrays
|
|
const double*, // array of 3d doubles
|
|
const double* // array of 3d doubles
|
|
);
|
|
|
|
ON_DECL
|
|
double
|
|
ON_TripleProduct(
|
|
const ON_3dVector&,
|
|
const ON_3dVector&,
|
|
const ON_3dVector&
|
|
);
|
|
|
|
ON_DECL
|
|
double
|
|
ON_TripleProduct( // 3d triple product for old fashioned arrays
|
|
const double*, // array of 3d doubles
|
|
const double*, // array of 3d doubles
|
|
const double* // array of 3d doubles
|
|
);
|
|
|
|
ON_DECL
|
|
bool
|
|
ON_IsOrthogonalFrame( // true if X, Y, Z are nonzero and mutually perpendicular
|
|
const ON_3dVector&, // X
|
|
const ON_3dVector&, // Y
|
|
const ON_3dVector& // Z
|
|
);
|
|
|
|
ON_DECL
|
|
bool
|
|
ON_IsOrthonormalFrame( // true if X, Y, Z are orthogonal and unit length
|
|
const ON_3dVector&, // X
|
|
const ON_3dVector&, // Y
|
|
const ON_3dVector& // Z
|
|
);
|
|
|
|
ON_DECL
|
|
bool
|
|
ON_IsRightHandFrame( // true if X, Y, Z are orthonormal and right handed
|
|
const ON_3dVector&, // X
|
|
const ON_3dVector&, // Y
|
|
const ON_3dVector& // Z
|
|
);
|
|
|
|
// Find the largest absolute value of coordinates from an array of points (possibly homogeneous).
|
|
ON_DECL
|
|
double ON_MaximumCoordinate(const double* data, int dim, bool is_rat, int count);
|
|
|
|
///////////////////////////////////////////////////////////////
|
|
//
|
|
// common points and vectors
|
|
//
|
|
// ON_unset_point is obsolete - use ON_3dPoint::UnsetPoint
|
|
#if !defined(OPENNURBS_WALL)
|
|
|
|
// OBSOLETE - use ON_3dPoint::UnsetPoint
|
|
#define ON_unset_point ON_3dPoint::UnsetPoint
|
|
// OBSOLETE - use ON_3dPoint::UnsetPoint
|
|
#define ON_UNSET_POINT ON_3dPoint::UnsetPoint
|
|
// OBSOLETE - use ON_3dPoint::UnsetVector
|
|
#define ON_UNSET_VECTOR ON_3dVector::UnsetVector
|
|
// OBSOLETE - use ON_3dPoint::Origin
|
|
#define ON_origin ON_3dPoint::Origin
|
|
// OBSOLETE - use ON_3dVector::XAxis
|
|
#define ON_xaxis ON_3dVector::XAxis
|
|
// OBSOLETE - use ON_3dVector::YAxis
|
|
#define ON_yaxis ON_3dVector::YAxis
|
|
// OBSOLETE - use ON_3dVector::ZAxis
|
|
#define ON_zaxis ON_3dVector::ZAxis
|
|
// OBSOLETE - use ON_3fPoint::Origin
|
|
#define ON_forigin ON_3fPoint::Origin
|
|
// OBSOLETE - use ON_3fVector::XAxis
|
|
#define ON_fxaxis ON_3fVector::XAxis
|
|
// OBSOLETE - use ON_3fVector::YAxis
|
|
#define ON_fyaxis ON_3fVector::YAxis
|
|
// OBSOLETE - use ON_3fVector::ZAxis
|
|
#define ON_fzaxis ON_3fVector::ZAxis
|
|
|
|
#endif
|
|
|
|
#include "opennurbs_fpoint.h"
|
|
|
|
////////////////////////////////////////////////////////////////
|
|
//
|
|
// ON_SurfaceCurvature
|
|
//
|
|
class ON_CLASS ON_SurfaceCurvature
|
|
{
|
|
public:
|
|
static const ON_SurfaceCurvature CreateFromPrincipalCurvatures(
|
|
double k1,
|
|
double k2
|
|
);
|
|
|
|
static const ON_SurfaceCurvature Nan;
|
|
static const ON_SurfaceCurvature Zero;
|
|
|
|
public:
|
|
double k1, k2; // principal curvatures
|
|
|
|
public:
|
|
bool IsSet() const;
|
|
bool IsZero() const;
|
|
bool IsUnset() const;
|
|
|
|
public:
|
|
double GaussianCurvature() const;
|
|
double MeanCurvature() const;
|
|
double MinimumRadius() const;
|
|
double MaximumRadius() const;
|
|
};
|
|
|
|
|
|
#if defined(ON_DLL_TEMPLATE)
|
|
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2dPoint>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3dPoint>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_4dPoint>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2dVector>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3dVector>;
|
|
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2fPoint>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3fPoint>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_4fPoint>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2fVector>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3fVector>;
|
|
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Color>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_SurfaceCurvature>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_Interval>;
|
|
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2dex>;
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_3dex>;
|
|
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_COMPONENT_INDEX>;
|
|
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class ON_CLASS ON_2dPointArray : public ON_SimpleArray<ON_2dPoint>
|
|
{
|
|
public:
|
|
// see ON_SimpleArray class definition comments for constructor documentation
|
|
ON_2dPointArray();
|
|
ON_2dPointArray(int);
|
|
ON_2dPointArray( const ON_2dPointArray& );
|
|
ON_2dPointArray& operator=( const ON_2dPointArray& );
|
|
|
|
bool GetBBox( // returns true if successful
|
|
double boxmin[2],
|
|
double boxmax[2],
|
|
bool bGrowBox = false // true means grow box
|
|
) const;
|
|
|
|
bool Transform( const ON_Xform& );
|
|
bool SwapCoordinates(int,int);
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class ON_CLASS ON_2fPointArray : public ON_SimpleArray<ON_2fPoint>
|
|
{
|
|
public:
|
|
// see ON_SimpleArray class definition comments for constructor documentation
|
|
ON_2fPointArray();
|
|
ON_2fPointArray(int);
|
|
ON_2fPointArray(const ON_2fPointArray&);
|
|
ON_2fPointArray& operator=( const ON_2fPointArray& );
|
|
|
|
bool GetBBox( // returns true if successful
|
|
float boxmin[2],
|
|
float boxmax[2],
|
|
bool bGrowBox = false // true means grow box
|
|
) const;
|
|
bool Transform( const ON_Xform& );
|
|
bool SwapCoordinates(int,int);
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class ON_CLASS ON_3dPointArray : public ON_SimpleArray<ON_3dPoint>
|
|
{
|
|
public:
|
|
// see ON_SimpleArray class definition comments for constructor documentation
|
|
ON_3dPointArray();
|
|
ON_3dPointArray(int);
|
|
ON_3dPointArray(const ON_SimpleArray<ON_3dPoint>&);
|
|
ON_3dPointArray& operator=( const ON_3dPointArray& );
|
|
ON_3dPointArray(const ON_SimpleArray<ON_3fPoint>&);
|
|
ON_3dPointArray& operator=( const ON_SimpleArray<ON_3fPoint>& );
|
|
|
|
// Description:
|
|
// Create 3d point list
|
|
// Parameters:
|
|
// point_dimension - [in] dimension of input points (2 or 3)
|
|
// bRational - [in] true if points are in homogenous rational form
|
|
// point_count - [in] number of points
|
|
// point_stride - [in] number of doubles to skip between points
|
|
// points - [in] array of point coordinates
|
|
bool Create(
|
|
int point_dimension,
|
|
int bRational,
|
|
int point_count,
|
|
int point_stride,
|
|
const double* points
|
|
);
|
|
|
|
// Description:
|
|
// Create 3d point list
|
|
// Parameters:
|
|
// point_dimension - [in] dimension of input points (2 or 3)
|
|
// bRational - [in] true if points are in homogenous rational form
|
|
// point_count - [in] number of points
|
|
// point_stride - [in] number of doubles to skip between points
|
|
// points - [in] array of point coordinates
|
|
bool Create(
|
|
int point_dimension,
|
|
int bRational,
|
|
int point_count,
|
|
int point_stride,
|
|
const float* points
|
|
);
|
|
|
|
// Description:
|
|
// Get 3d axis aligned bounding box.
|
|
// Returns:
|
|
// 3d bounding box of point list.
|
|
ON_BoundingBox BoundingBox() const;
|
|
|
|
// Description:
|
|
// Get 3d axis aligned bounding box
|
|
// of a subset of the points.
|
|
// Parameters:
|
|
// from - [in] start of the box calculation
|
|
// count - [in] number of items computed
|
|
// Returns:
|
|
// 3d bounding box of point list.
|
|
ON_BoundingBox BoundingBox(int from, int count) const;
|
|
|
|
// Description:
|
|
// Get 3d axis aligned bounding box or the union
|
|
// of the input box with the point list's bounding box.
|
|
// Parameters:
|
|
// bbox - [in/out] 3d axis aligned bounding box
|
|
// bGrowBox - [in] (default=false)
|
|
// If true, then the union of the input bbox and the
|
|
// point list's bounding box is returned in bbox.
|
|
// If false, the point list's bounding box is returned in bbox.
|
|
// Returns:
|
|
// true if successful.
|
|
bool GetBoundingBox(
|
|
ON_BoundingBox& bbox,
|
|
int bGrowBox = false
|
|
) const;
|
|
|
|
// Description:
|
|
// Get axis aligned bounding box.
|
|
// Parameters:
|
|
// boxmin - [in/out] array of 3 doubles
|
|
// boxmax - [in/out] array of 3 doubles
|
|
// bGrowBox - [in] (default=false)
|
|
// If true, then the union of the input bounding box and the
|
|
// object's bounding box is returned.
|
|
// If false, the object's bounding box is returned.
|
|
// Returns:
|
|
// true if object has bounding box and calculation was successful
|
|
bool GetBBox(
|
|
double boxmin[3],
|
|
double boxmax[3],
|
|
bool bGrowBox = false
|
|
) const;
|
|
|
|
/*
|
|
Description:
|
|
Get tight bounding box of the point list.
|
|
Parameters:
|
|
tight_bbox - [in/out] tight bounding box
|
|
bGrowBox -[in] (default=false)
|
|
If true and the input tight_bbox is valid, then returned
|
|
tight_bbox is the union of the input tight_bbox and the
|
|
tight bounding box of the point list.
|
|
xform -[in] (default=nullptr)
|
|
If not nullptr, the tight bounding box of the transformed
|
|
point list is calculated. The point list is not modified.
|
|
Returns:
|
|
True if the returned tight_bbox is set to a valid
|
|
bounding box.
|
|
*/
|
|
bool GetTightBoundingBox(
|
|
ON_BoundingBox& tight_bbox,
|
|
bool bGrowBox = false,
|
|
const ON_Xform* xform = nullptr
|
|
) const;
|
|
|
|
// Description:
|
|
// Transform points by applying xform to each point.
|
|
// Parameters:
|
|
// xform - [in] transformation matrix
|
|
// Returns:
|
|
// true if successful.
|
|
bool Transform(
|
|
const ON_Xform& xform
|
|
);
|
|
|
|
// Description:
|
|
// Swaps point coordinate values with indices i and j.
|
|
// Parameters:
|
|
// i - [in] coordinate index
|
|
// j - [in] coordinate index
|
|
// Returns:
|
|
// true if successful.
|
|
// Example:
|
|
// The call SwapCoordinates(0,2) would swap the x and z
|
|
// coordinates of each point in the array.
|
|
bool SwapCoordinates(
|
|
int i,
|
|
int j
|
|
);
|
|
|
|
// Description:
|
|
// Rotate points about a center and axis. A positive angle
|
|
// results in a counter-clockwise rotation about the axis
|
|
// of rotation.
|
|
// Parameters:
|
|
// sin_angle - [in] sine of rotation angle
|
|
// cos_angle - [in] cosine of rotation angle
|
|
// axis_of_rotation - [in] axis of rotation
|
|
// center_of_rotation - [in] center (fixed point) of rotation
|
|
// Returns:
|
|
// true if successful.
|
|
bool Rotate(
|
|
double sin_angle,
|
|
double cos_angle,
|
|
const ON_3dVector& axis_of_rotation,
|
|
const ON_3dPoint& center_of_rotation
|
|
);
|
|
|
|
// Description:
|
|
// Rotate points about a center and axis. A positive angle
|
|
// results in a counter-clockwise rotation about the axis
|
|
// of rotation.
|
|
// Parameters:
|
|
// angle - [in] angle in radians. Polsine of rotation angle
|
|
// cos_angle - [in] cosine of rotation angle
|
|
// axis_of_rotation - [in] axis of rotation
|
|
// center_of_rotation - [in] center (fixed point) of rotation
|
|
// Returns:
|
|
// true if successful.
|
|
bool Rotate(
|
|
double angle_in_radians,
|
|
const ON_3dVector& axis_of_rotation,
|
|
const ON_3dPoint& center_of_rotation
|
|
);
|
|
|
|
// Description:
|
|
// Translate a polyline
|
|
// Parameters:
|
|
// delta - [in] translation vectorsine of rotation angle
|
|
// Returns:
|
|
// true if successful.
|
|
bool Translate(
|
|
const ON_3dVector& delta
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Get the index of the point in the array that is closest
|
|
to P.
|
|
Parameters:
|
|
P - [in]
|
|
closest_point_index - [out]
|
|
maximum_distance - [in] optional distance constraint.
|
|
If maximum_distance > 0, then only points Q with
|
|
|P-Q| <= maximum_distance are returned.
|
|
Returns:
|
|
True if a point is found; in which case *closest_point_index
|
|
is the index of the point. False if no point is found
|
|
or the input is not valid.
|
|
See Also:
|
|
ON_GetClosestPointInPointList
|
|
ON_PointCloud::GetClosestPoint
|
|
*/
|
|
bool GetClosestPoint(
|
|
ON_3dPoint P,
|
|
int* closest_point_index,
|
|
double maximum_distance = 0.0
|
|
) const;
|
|
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class ON_CLASS ON_3fPointArray : public ON_SimpleArray<ON_3fPoint>
|
|
{
|
|
public:
|
|
// see ON_SimpleArray class definition comments for constructor documentation
|
|
ON_3fPointArray();
|
|
ON_3fPointArray(int);
|
|
ON_3fPointArray(const ON_3fPointArray&);
|
|
ON_3fPointArray& operator=( const ON_3fPointArray& );
|
|
|
|
bool GetBBox(
|
|
float boxmin[3],
|
|
float boxmax[3],
|
|
bool bGrowBox = false
|
|
) const;
|
|
|
|
bool Transform( const ON_Xform& );
|
|
|
|
bool SwapCoordinates(int,int);
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class ON_CLASS ON_4dPointArray : public ON_SimpleArray<ON_4dPoint>
|
|
{
|
|
public:
|
|
// see ON_SimpleArray class definition comments for constructor documentation
|
|
ON_4dPointArray();
|
|
ON_4dPointArray(int);
|
|
ON_4dPointArray(const ON_4dPointArray&);
|
|
ON_4dPointArray& operator=( const ON_4dPointArray& );
|
|
|
|
bool Transform( const ON_Xform& );
|
|
bool SwapCoordinates(int,int);
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class ON_CLASS ON_4fPointArray : public ON_SimpleArray<ON_4fPoint>
|
|
{
|
|
public:
|
|
// see ON_SimpleArray class definition comments for constructor documentation
|
|
ON_4fPointArray();
|
|
ON_4fPointArray(int);
|
|
ON_4fPointArray(const ON_4fPointArray&);
|
|
ON_4fPointArray& operator=( const ON_4fPointArray& );
|
|
|
|
bool Transform( const ON_Xform& );
|
|
bool SwapCoordinates(int,int);
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class ON_CLASS ON_2dVectorArray : public ON_SimpleArray<ON_2dVector>
|
|
{
|
|
public:
|
|
// see ON_SimpleArray class definition comments for constructor documentation
|
|
ON_2dVectorArray();
|
|
ON_2dVectorArray(int);
|
|
ON_2dVectorArray(const ON_2dVectorArray&);
|
|
ON_2dVectorArray& operator=( const ON_2dVectorArray& );
|
|
|
|
bool GetBBox(
|
|
double boxmin[2],
|
|
double boxmax[2],
|
|
bool bGrowBox = false
|
|
) const;
|
|
|
|
bool Transform( const ON_Xform& );
|
|
bool SwapCoordinates(int,int);
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class ON_CLASS ON_2fVectorArray : public ON_SimpleArray<ON_2fVector>
|
|
{
|
|
public:
|
|
// see ON_SimpleArray class definition comments for constructor documentation
|
|
ON_2fVectorArray();
|
|
ON_2fVectorArray(int);
|
|
ON_2fVectorArray(const ON_2fVectorArray&);
|
|
ON_2fVectorArray& operator=( const ON_2fVectorArray& );
|
|
|
|
bool GetBBox(
|
|
float boxmin[2],
|
|
float boxmax[2],
|
|
bool = false
|
|
) const;
|
|
|
|
bool Transform( const ON_Xform& );
|
|
bool SwapCoordinates(int,int);
|
|
};
|
|
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class ON_CLASS ON_3dVectorArray : public ON_SimpleArray<ON_3dVector>
|
|
{
|
|
public:
|
|
ON_3dVectorArray();
|
|
ON_3dVectorArray(int);
|
|
ON_3dVectorArray(const ON_3dVectorArray&);
|
|
ON_3dVectorArray& operator=( const ON_3dVectorArray& );
|
|
|
|
bool GetBBox(
|
|
double boxmin[3],
|
|
double boxmax[3],
|
|
bool bGrowBow = false
|
|
) const;
|
|
|
|
bool Transform( const ON_Xform& );
|
|
bool SwapCoordinates(int,int);
|
|
};
|
|
|
|
/////////////////////////////////////////////////////////////////
|
|
//
|
|
|
|
class ON_CLASS ON_3fVectorArray : public ON_SimpleArray<ON_3fVector>
|
|
{
|
|
public:
|
|
ON_3fVectorArray();
|
|
ON_3fVectorArray(int);
|
|
ON_3fVectorArray(const ON_3fVectorArray&);
|
|
ON_3fVectorArray& operator=( const ON_3fVectorArray& );
|
|
|
|
bool GetBBox(
|
|
float boxmin[3],
|
|
float boxmax[3],
|
|
bool bGrowBox = false
|
|
) const;
|
|
|
|
bool Transform( const ON_Xform& );
|
|
bool SwapCoordinates(int,int);
|
|
};
|
|
|
|
class ON_CLASS ON_3dPointListRef
|
|
{
|
|
public:
|
|
|
|
|
|
ON_3dPointListRef()
|
|
: m_point_count(0)
|
|
, m_point_stride(0)
|
|
, m_dP(0)
|
|
, m_fP(0)
|
|
{}
|
|
|
|
/*
|
|
Description:
|
|
Construct a point list that references the mesh vertex list.
|
|
Remarks:
|
|
If the mesh has double precision vertices, then the point
|
|
list will refer to them; otherwise, the point list will
|
|
refer to the single precision vertices.
|
|
*/
|
|
ON_3dPointListRef(
|
|
const class ON_Mesh* mesh
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Construct a point list that references the points
|
|
in a simple array of ON_3dPoint objects.
|
|
*/
|
|
ON_3dPointListRef(
|
|
const class ON_SimpleArray<ON_3dPoint>& point_array
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Construct a point list that references the points
|
|
in a simple array of ON_3fPoint objects.
|
|
*/
|
|
ON_3dPointListRef(
|
|
const class ON_SimpleArray<ON_3fPoint>& point_array
|
|
);
|
|
|
|
static const ON_3dPointListRef EmptyPointList;
|
|
|
|
static
|
|
ON_3dPointListRef FromDoubleArray(
|
|
size_t point_count,
|
|
size_t point_stride,
|
|
const double* point_array
|
|
);
|
|
|
|
static
|
|
ON_3dPointListRef FromFloatArray(
|
|
size_t point_count,
|
|
size_t point_stride,
|
|
const float* point_array
|
|
);
|
|
|
|
static
|
|
ON_3dPointListRef FromPointArray(
|
|
const class ON_SimpleArray<ON_3dPoint>& point_array
|
|
);
|
|
|
|
static
|
|
ON_3dPointListRef FromPointArray(
|
|
const class ON_SimpleArray<ON_3fPoint>& point_array
|
|
);
|
|
|
|
static
|
|
ON_3dPointListRef FromMesh(
|
|
const class ON_Mesh* mesh
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
A copy of the refenced points in an ON_SimpleArray<ON_3dPoint>.
|
|
*/
|
|
ON_SimpleArray<ON_3dPoint> To3dPointArray() const;
|
|
|
|
/*
|
|
Returns:
|
|
A copy of the refenced points in an ON_SimpleArray<ON_3fPoint>.
|
|
*/
|
|
ON_SimpleArray<ON_3fPoint> To3fPointArray() const;
|
|
|
|
/*
|
|
Description:
|
|
Set this point list to reference points with double coordinates.
|
|
Parameters:
|
|
point_count - [in]
|
|
number of points
|
|
point_stride - [in] (>= 3)
|
|
number of doubles between points.
|
|
point_array - [in]
|
|
pointer to the first coordinate of the first point.
|
|
Returns:
|
|
Number of points in the list.
|
|
*/
|
|
unsigned int SetFromDoubleArray(
|
|
size_t point_count,
|
|
size_t point_stride,
|
|
const double* point_array
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Set this point list to reference points with float coordinates.
|
|
Parameters:
|
|
point_count - [in]
|
|
number of points
|
|
point_stride - [in] (>= 3)
|
|
number of floats between points.
|
|
point_array - [in]
|
|
pointer to the first coordinate of the first point.
|
|
Returns:
|
|
Number of points in the list.
|
|
*/
|
|
unsigned int SetFromFloatArray(
|
|
size_t point_count,
|
|
size_t point_stride,
|
|
const float* point_array
|
|
);
|
|
|
|
/*
|
|
Description:
|
|
Set this point list to reference a mesh vertex list.
|
|
Parameters:
|
|
mesh - [in]
|
|
Returns:
|
|
Number of points in the list.
|
|
*/
|
|
unsigned int SetFromMesh(
|
|
const class ON_Mesh* mesh
|
|
);
|
|
|
|
/*
|
|
Returns:
|
|
0: no points
|
|
1: single precison points (float coordinates)
|
|
2: double precison points (double coordinates)
|
|
*/
|
|
unsigned int Precision() const;
|
|
|
|
/*
|
|
Returns:
|
|
true if the points are double precision
|
|
*/
|
|
bool DoublePrecision() const;
|
|
|
|
/*
|
|
Returns:
|
|
true if the points are single precision
|
|
*/
|
|
bool SinglePrecision() const;
|
|
|
|
/*
|
|
Description:
|
|
Copy point location into buffer and return it as an ON_3dPoint.
|
|
Parameters:
|
|
point_index - [in]
|
|
buffer - [out]
|
|
If point_index is a valid index, the point coordinates
|
|
are copied to buffer[]; oherwise the buffer coordinates
|
|
are set to ON_UNSET_VALUE.
|
|
You must insure buffer is not null, has proper alignment
|
|
for storing doubles, and is large enough to store three
|
|
doubles.
|
|
Returns:
|
|
A reference to an ON_3dPoint which is a cast of buffer.
|
|
Remarks:
|
|
This is the fastest and most efficient way to get a the
|
|
location of a point into memory you are managing.
|
|
*/
|
|
inline const class ON_3dPoint& GetPoint(
|
|
unsigned int point_index,
|
|
double buffer[3]
|
|
) const
|
|
{
|
|
if ( point_index < m_point_count )
|
|
{
|
|
if ( m_dP )
|
|
{
|
|
const double* p = m_dP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
else
|
|
{
|
|
const float* p = m_fP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
|
|
}
|
|
return *((const ON_3dPoint*)buffer);
|
|
}
|
|
|
|
/*
|
|
Parameters:
|
|
point_index - [in]
|
|
Returns:
|
|
If point_index is a valid index, the point location is returned.
|
|
Otherwise ON_3dPoint::UnsetPoint is returned.
|
|
*/
|
|
inline ON_3dPoint Point(
|
|
unsigned int point_index
|
|
) const
|
|
{
|
|
double buffer[3];
|
|
if ( point_index < m_point_count )
|
|
{
|
|
if ( m_dP )
|
|
{
|
|
const double* p = m_dP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
else
|
|
{
|
|
const float* p = m_fP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
|
|
}
|
|
return *((const ON_3dPoint*)buffer);
|
|
}
|
|
|
|
inline ON_3dPoint operator[](int point_index) const
|
|
{
|
|
double buffer[3];
|
|
if ( point_index >= 0 && ((unsigned int)point_index) < m_point_count )
|
|
{
|
|
if ( m_dP )
|
|
{
|
|
const double* p = m_dP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
else
|
|
{
|
|
const float* p = m_fP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
|
|
}
|
|
return *((const ON_3dPoint*)buffer);
|
|
}
|
|
|
|
inline ON_3dPoint operator[](unsigned int point_index) const
|
|
{
|
|
double buffer[3];
|
|
if ( point_index < m_point_count )
|
|
{
|
|
if ( m_dP )
|
|
{
|
|
const double* p = m_dP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
else
|
|
{
|
|
const float* p = m_fP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
|
|
}
|
|
return *((const ON_3dPoint*)buffer);
|
|
}
|
|
|
|
inline ON_3dPoint operator[](ON__INT64 point_index) const
|
|
{
|
|
double buffer[3];
|
|
if ( point_index >= 0 && ((ON__UINT64)point_index) < m_point_count )
|
|
{
|
|
if ( m_dP )
|
|
{
|
|
const double* p = m_dP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
else
|
|
{
|
|
const float* p = m_fP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
|
|
}
|
|
return *((const ON_3dPoint*)buffer);
|
|
}
|
|
|
|
inline ON_3dPoint operator[](ON__UINT64 point_index) const
|
|
{
|
|
double buffer[3];
|
|
if ( point_index < m_point_count )
|
|
{
|
|
if ( m_dP )
|
|
{
|
|
const double* p = m_dP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
else
|
|
{
|
|
const float* p = m_fP + (point_index*m_point_stride);
|
|
buffer[0] = *p++;
|
|
buffer[1] = *p++;
|
|
buffer[2] = *p;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
buffer[0] = buffer[1] = buffer[2] = ON_UNSET_VALUE;
|
|
}
|
|
return *((const ON_3dPoint*)buffer);
|
|
}
|
|
|
|
inline unsigned int PointCount() const
|
|
{
|
|
return m_point_count;
|
|
}
|
|
|
|
inline unsigned int PointStride() const
|
|
{
|
|
return m_point_stride;
|
|
}
|
|
|
|
inline const double* PointDoubleArray() const
|
|
{
|
|
return m_dP;
|
|
}
|
|
|
|
inline const float* PointFloatArray() const
|
|
{
|
|
return m_fP;
|
|
}
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to face_points[] array.
|
|
*/
|
|
unsigned int GetMeshFacePoints(
|
|
const class ON_MeshFace* mesh_face,
|
|
ON_3dPoint face_points[4]
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to ngon_points[] array.
|
|
*/
|
|
unsigned int GetMeshNgonPoints(
|
|
const class ON_MeshNgon* mesh_ngon,
|
|
size_t ngon_points_capacity,
|
|
class ON_3dPoint* ngon_points
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to ngon_points[] array.
|
|
*/
|
|
unsigned int GetMeshNgonPoints(
|
|
const class ON_MeshNgon* mesh_ngon,
|
|
ON_SimpleArray<ON_3dPoint>& ngon_points
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to quad_points[] array.
|
|
*/
|
|
unsigned int GetQuadPoints(
|
|
const int quad_point_indices[4],
|
|
class ON_3dPoint quad_points[4]
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to quad_points[] array.
|
|
*/
|
|
unsigned int GetQuadPoints(
|
|
const unsigned int quad_point_indices[4],
|
|
class ON_3dPoint quad_points[4]
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to triangle_points[] array.
|
|
*/
|
|
unsigned int GetTrianglePoints(
|
|
const int triangle_point_indices[3],
|
|
class ON_3dPoint triangle_points[3]
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to triangle_points[] array.
|
|
*/
|
|
unsigned int GetTrianglePoints(
|
|
const unsigned int triangle_point_indices[3],
|
|
class ON_3dPoint triangle_points[3]
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to points[] array.
|
|
*/
|
|
unsigned int GetPoints(
|
|
int point_index_count,
|
|
const int* point_index_list,
|
|
class ON_3dPoint* points
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to points[] array.
|
|
*/
|
|
unsigned int GetPoints(
|
|
unsigned int point_index_count,
|
|
const unsigned int* point_index_list,
|
|
class ON_3dPoint* points
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to points[] array.
|
|
*/
|
|
unsigned int GetPoints(
|
|
const ON_SimpleArray<int>& point_index_list,
|
|
ON_SimpleArray<ON_3dPoint>& points
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to points[] array.
|
|
*/
|
|
unsigned int GetPoints(
|
|
int point_index_count,
|
|
const int* point_index_list,
|
|
ON_SimpleArray<ON_3dPoint>& points
|
|
) const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of points copied to points[] array.
|
|
*/
|
|
unsigned int GetPoints(
|
|
unsigned int point_index_count,
|
|
const unsigned int* point_index_list,
|
|
ON_SimpleArray<ON_3dPoint>& points
|
|
) const;
|
|
|
|
private:
|
|
unsigned int m_point_count;
|
|
unsigned int m_point_stride;
|
|
const double* m_dP;
|
|
const float* m_fP;
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/*
|
|
Class ON_2dSize
|
|
*/
|
|
class ON_CLASS ON_2dSize
|
|
{
|
|
public:
|
|
// Default construction intentionally leaves x and y uninitialized.
|
|
// Use something like
|
|
// ON_2dSize pt(1.0,2.0);
|
|
// or
|
|
// ON_2dSize pt = ON_2dSize::Zero;
|
|
// when you need an initialized ON_2dSize.
|
|
ON_2dSize() = default;
|
|
|
|
~ON_2dSize() = default;
|
|
ON_2dSize(const ON_2dSize& ) = default;
|
|
ON_2dSize& operator=(const ON_2dSize& ) = default;
|
|
|
|
ON_2dSize(
|
|
double cx,
|
|
double cy
|
|
);
|
|
|
|
/*
|
|
Dictionary compare.
|
|
Returns:
|
|
-1: lhs < rhs
|
|
0: lsh == rsh
|
|
+1: lhs > rhs
|
|
*/
|
|
static int Compare(
|
|
const ON_2dSize& lhs,
|
|
const ON_2dSize& rhs
|
|
);
|
|
|
|
/*
|
|
Dictionary compare.
|
|
Returns:
|
|
-1: lhs < rhs
|
|
0: lsh == rsh
|
|
+1: lhs > rhs
|
|
*/
|
|
static int ComparePointer(
|
|
const ON_2dSize* lhs,
|
|
const ON_2dSize* rhs
|
|
);
|
|
|
|
public:
|
|
static const ON_2dSize Zero; // (0.0,0.0)
|
|
static const ON_2dSize Unset; // (ON_UNSET_DOUBLE,ON_UNSET_DOUBLE)
|
|
|
|
public:
|
|
/*
|
|
Returns:
|
|
true if both cx and cy are 0.0
|
|
*/
|
|
bool IsZero() const;
|
|
|
|
/*
|
|
Returns:
|
|
true if neither cx nor cy are ON_UNSET_DOUBLE.
|
|
*/
|
|
bool IsSet() const;
|
|
|
|
public:
|
|
double cx;
|
|
double cy;
|
|
};
|
|
|
|
ON_DECL
|
|
bool operator==(
|
|
const ON_2dSize& lhs,
|
|
const ON_2dSize& rhs
|
|
);
|
|
|
|
ON_DECL
|
|
bool operator!=(
|
|
const ON_2dSize& lhs,
|
|
const ON_2dSize& rhs
|
|
);
|
|
|
|
#if defined(ON_DLL_TEMPLATE)
|
|
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_2dSize>;
|
|
|
|
#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_4dRect
|
|
{
|
|
public:
|
|
// Default construction intentionally leaves x and y uninitialized.
|
|
// Use something like
|
|
// ON_4dRect pt(1.0,2.0,3.0,4.0);
|
|
// or
|
|
// ON_4dRect pt = ON_4dRect::Zero;
|
|
// when you need an initialized ON_4dRect.
|
|
ON_4dRect() = default;
|
|
|
|
~ON_4dRect() = default;
|
|
ON_4dRect(const ON_4dRect& ) = default;
|
|
ON_4dRect& operator=(const ON_4dRect& ) = default;
|
|
|
|
ON_4dRect(
|
|
double left,
|
|
double top,
|
|
double right,
|
|
double bottom
|
|
);
|
|
|
|
ON_4dRect(const ON_2dPoint topLeft, const ON_2dPoint& bottomRight);
|
|
ON_4dRect(const ON_2dPoint& point, const ON_2dSize& size);
|
|
|
|
public:
|
|
static const ON_4dRect Zero; // (0.0,0.0,0.0,0.0)
|
|
static const ON_4dRect 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;
|
|
|
|
double Width(void) const;
|
|
double Height(void) const;
|
|
|
|
const ON_2dSize Size(void) const;
|
|
|
|
const ON_2dPoint CenterPoint(void) const;
|
|
const ON_2dPoint TopLeft(void) const;
|
|
const ON_2dPoint BottomRight(void) const;
|
|
|
|
bool IntersectRect(const ON_4dRect* r1, const ON_4dRect* r2);
|
|
bool IntersectRect(const ON_4dRect& r1, const ON_4dRect& r2);
|
|
|
|
bool IsRectEmpty(void) const;
|
|
bool IsRectNull(void) const;
|
|
void SetRectEmpty(void) { *this = Zero; }
|
|
void SetRect(double l, double t, double r, double b);
|
|
|
|
bool PtInRect(const ON_2dPoint& pt) const;
|
|
|
|
void OffsetRect(double, double);
|
|
void OffsetRect(const ON_2dVector&);
|
|
void InflateRect(double, double);
|
|
void InflateRect(double, double, double, double);
|
|
void DeflateRect(double, double);
|
|
bool SubtractRect(const ON_4dRect* rect1, const ON_4dRect* rect2);
|
|
|
|
void NormalizeRect();
|
|
|
|
public:
|
|
double left;
|
|
double top;
|
|
double right;
|
|
double bottom;
|
|
};
|
|
|
|
#if defined(ON_DLL_TEMPLATE)
|
|
ON_DLL_TEMPLATE template class ON_CLASS ON_SimpleArray<ON_4dRect>;
|
|
#endif
|
|
|
|
|
|
ON_DECL
|
|
bool operator==(const ON_4dRect&, const ON_4dRect&);
|
|
|
|
ON_DECL
|
|
bool operator!=(const ON_4dRect&, const ON_4dRect&);
|
|
|
|
/*
|
|
Description:
|
|
Tool for efficiently calculating a boundary polyline winding number
|
|
with input tools that do not require the boundary polyline to be
|
|
a contiguous array of points.
|
|
*/
|
|
class ON_CLASS ON_WindingNumber
|
|
{
|
|
public:
|
|
ON_WindingNumber() = default;
|
|
~ON_WindingNumber() = default;
|
|
ON_WindingNumber(const ON_WindingNumber&) = default;
|
|
ON_WindingNumber& operator=(const ON_WindingNumber&) = default;
|
|
|
|
public:
|
|
static const ON_WindingNumber Unset;
|
|
|
|
public:
|
|
/*
|
|
Description:
|
|
The calculation of the winding number begins with a call to SetWindingPoint().
|
|
Parameters:
|
|
x - [in]
|
|
y - [in]
|
|
The coordinates of the winding point are (x,y).
|
|
Remarks:
|
|
Calling SetWindingPoint() erases results of any previous calculations.
|
|
*/
|
|
void SetWindingPoint(double x, double y);
|
|
|
|
/*
|
|
Description:
|
|
The calculation of the winding number begins with a call to SetWindingPoint().
|
|
Parameters:
|
|
winding_point - [in]
|
|
Remarks:
|
|
Calling SetWindingPoint() erases results of any previous calculations.
|
|
*/
|
|
void SetWindingPoint(ON_2dPoint winding_point);
|
|
|
|
/*
|
|
Description:
|
|
After calling SetWindingPoint(), the boundary may be specified by one or more calls to
|
|
various AddBoundary functions.
|
|
The boundary may be specified one point at a time, one edge at a time, portions of the boundary
|
|
at a time, or the entire boundary in a single call. The edges may be added in any order.
|
|
The caller is responsible for insuring the collection calls to AddBoundary() results in a
|
|
a continuous, oriented, and closed polyline.
|
|
Parameters:
|
|
p - [in]
|
|
next point in boundary.
|
|
Returns:
|
|
Number of boundary edge segments added.
|
|
*/
|
|
ON__UINT32 AddBoundary(ON_2dPoint p);
|
|
|
|
/*
|
|
Description:
|
|
After calling SetWindingPoint(), the boundary may be specified by one or more calls to
|
|
various AddBoundary functions.
|
|
The boundary may be specified one point at a time, one edge at a time, portions of the boundary
|
|
at a time, or the entire boundary in a single call. The edges may be added in any order.
|
|
The caller is responsible for insuring the collection calls to AddBoundary() results in a
|
|
a continuous, oriented, and closed polyline.
|
|
Parameters:
|
|
p - [in]
|
|
start of edge segment.
|
|
Caller is responsible for insuring coordinates of p are valid doubles.
|
|
q - [in]
|
|
end of edge segment
|
|
Caller is responsible for insuring coordinates of q are valid doubles.
|
|
The calculation tolerates p==q.
|
|
Returns:
|
|
Number of boundary edge segments added.
|
|
*/
|
|
ON__UINT32 AddBoundary(ON_2dPoint p, ON_2dPoint q);
|
|
|
|
/*
|
|
Description:
|
|
After calling SetWindingPoint(), the boundary may be specified by one or more calls to
|
|
various AddBoundary functions.
|
|
The boundary may be specified one point at a time, one edge at a time, portions of the boundary
|
|
at a time, or the entire boundary in a single call. The edges may be added in any order.
|
|
The caller is responsible for insuring the collection calls to AddBoundary() results in a
|
|
a continuous, oriented, and closed polyline.
|
|
Parameters:
|
|
point_count - [in] >= 2
|
|
number of points in boundary_points[] array.
|
|
point_stride - [in] >= 2
|
|
The i-th point has coordinates (boundary_points[i*point_stride],boundary_points[i*point_stride+1]).
|
|
boundary_points - [in]
|
|
Boundary points.
|
|
bCloseBoundary - [in]
|
|
If true, an edge segment is added from the last boundary point to the first boundary point.
|
|
Returns:
|
|
Number of boundary edge segments added.
|
|
Remarks:
|
|
The calculation tolerates zero length edge segments. The caller is responsible for insuring the
|
|
coordinates in boundary_points[] are valid doubles.
|
|
*/
|
|
ON__UINT32 AddBoundary(size_t point_count, size_t point_stride, const double* boundary_points, bool bCloseBoundary);
|
|
|
|
/*
|
|
Description:
|
|
After calling SetWindingPoint(), the boundary may be specified by one or more calls to
|
|
various AddBoundary functions.
|
|
The boundary may be specified one point at a time, one edge at a time, portions of the boundary
|
|
at a time, or the entire boundary in a single call. The edges may be added in any order.
|
|
The caller is responsible for insuring the collection calls to AddBoundary() results in a
|
|
a continuous, oriented, and closed polyline.
|
|
Parameters:
|
|
point_count - [in] >= 2
|
|
number of points in boundary_points[] array.
|
|
point_stride - [in] >= 2
|
|
The i-th point has coordinates (boundary_points[i*point_stride],boundary_points[i*point_stride+1]).
|
|
boundary_points - [in]
|
|
Boundary points.
|
|
bCloseBoundary - [in]
|
|
If true, an edge segment is added from the last boundary point to the first boundary point.
|
|
Returns:
|
|
Number of boundary edge segments added.
|
|
Remarks:
|
|
The calculation tolerates zero length edge segments. The caller is responsible for insuring the
|
|
coordinates in boundary_points[] are valid doubles.
|
|
*/
|
|
ON__UINT32 AddBoundary(size_t point_count, size_t point_stride, const float* boundary_points, bool bCloseBoundary);
|
|
|
|
/*
|
|
Description:
|
|
After calling SetWindingPoint(), the boundary may be specified by one or more calls to
|
|
various AddBoundary functions.
|
|
The boundary may be specified one point at a time, one edge at a time, portions of the boundary
|
|
at a time, or the entire boundary in a single call. The edges may be added in any order.
|
|
The caller is responsible for insuring the collection calls to AddBoundary() results in a
|
|
a continuous, oriented, and closed polyline.
|
|
Parameters:
|
|
point_count - [in] >= 2
|
|
number of points in boundary_points[] array.
|
|
point_stride - [in] >= 2
|
|
The i-th point has coordinates (boundary_points[i*point_stride],boundary_points[i*point_stride+1]).
|
|
boundary_points - [in]
|
|
Boundary points.
|
|
bCloseBoundary - [in]
|
|
If true, an edge segment is added from the last boundary point to the first boundary point.
|
|
Returns:
|
|
Number of boundary edge segments added.
|
|
Remarks:
|
|
The calculation tolerates zero length edge segments. The caller is responsible for insuring the
|
|
coordinates in boundary_points[] are valid doubles.
|
|
*/
|
|
ON__UINT32 AddBoundary(size_t point_count, size_t point_stride, const int* boundary_points, bool bCloseBoundary);
|
|
|
|
/*
|
|
Description:
|
|
After calling SetWindingPoint(), the boundary may be specified by one or more calls to
|
|
various AddBoundary functions.
|
|
The boundary may be specified one point at a time, one edge at a time, portions of the boundary
|
|
at a time, or the entire boundary in a single call. The edges may be added in any order.
|
|
The caller is responsible for insuring the collection calls to AddBoundary() results in a
|
|
a continuous, oriented, and closed polyline.
|
|
Parameters:
|
|
point_count - [in] >= 2
|
|
number of points in boundary_points[] array.
|
|
boundary_points - [in]
|
|
Boundary points.
|
|
bCloseBoundary - [in]
|
|
If true, an edge segment is added from the last boundary point to the first boundary point.
|
|
Returns:
|
|
Number of boundary edge segments added.
|
|
Remarks:
|
|
The calculation tolerates zero length edge segments. The caller is responsible for insuring the
|
|
coordinates in boundary_points[] are valid doubles.
|
|
*/
|
|
ON__UINT32 AddBoundary(size_t point_count, const ON_2dPoint* boundary_points, bool bCloseBoundary);
|
|
|
|
/*
|
|
Description:
|
|
After calling SetWindingPoint(), the boundary may be specified by one or more calls to
|
|
various AddBoundary functions.
|
|
The boundary may be specified one point at a time, one edge at a time, portions of the boundary
|
|
at a time, or the entire boundary in a single call. The edges may be added in any order.
|
|
The caller is responsible for insuring the collection calls to AddBoundary() results in a
|
|
a continuous, oriented, and closed polyline.
|
|
Parameters:
|
|
point_count - [in] >= 2
|
|
number of points in boundary_points[] array.
|
|
boundary_points - [in]
|
|
Boundary points.
|
|
bCloseBoundary - [in]
|
|
If true, an edge segment is added from the last boundary point to the first boundary point.
|
|
Returns:
|
|
Number of boundary edge segments added.
|
|
Remarks:
|
|
The calculation tolerates zero length edge segments. The caller is responsible for insuring the
|
|
coordinates in boundary_points[] are valid doubles.
|
|
*/
|
|
ON__UINT32 AddBoundary(size_t point_count, const ON_3dPoint* boundary_points, bool bCloseBoundary);
|
|
|
|
/*
|
|
Description:
|
|
After calling SetWindingPoint(), the boundary may be specified by one or more calls to
|
|
various AddBoundary functions.
|
|
The boundary may be specified one point at a time, one edge at a time, portions of the boundary
|
|
at a time, or the entire boundary in a single call. The edges may be added in any order.
|
|
The caller is responsible for insuring the collection calls to AddBoundary() results in a
|
|
a continuous, oriented, and closed polyline.
|
|
Parameters:
|
|
point_count - [in] >= 2
|
|
number of points in boundary_points[] array.
|
|
boundary_points - [in]
|
|
Boundary points.
|
|
bCloseBoundary - [in]
|
|
If true, an edge segment is added from the last boundary point to the first boundary point.
|
|
Returns:
|
|
Number of boundary edge segments added.
|
|
Remarks:
|
|
The calculation tolerates zero length edge segments. The caller is responsible for insuring the
|
|
coordinates in boundary_points[] are valid doubles.
|
|
*/
|
|
ON__UINT32 AddBoundary(size_t point_count, const ON_2fPoint* boundary_points, bool bCloseBoundary);
|
|
|
|
/*
|
|
Description:
|
|
After calling SetWindingPoint(), the boundary may be specified by one or more calls to
|
|
various AddBoundary functions.
|
|
The boundary may be specified one point at a time, one edge at a time, portions of the boundary
|
|
at a time, or the entire boundary in a single call. The edges may be added in any order.
|
|
The caller is responsible for insuring the collection calls to AddBoundary() results in a
|
|
a continuous, oriented, and closed polyline.
|
|
Parameters:
|
|
point_count - [in] >= 2
|
|
number of points in boundary_points[] array.
|
|
boundary_points - [in]
|
|
Boundary points.
|
|
bCloseBoundary - [in]
|
|
If true, an edge segment is added from the last boundary point to the first boundary point.
|
|
Returns:
|
|
Number of boundary edge segments added.
|
|
Remarks:
|
|
The calculation tolerates zero length edge segments. The caller is responsible for insuring the
|
|
coordinates in boundary_points[] are valid doubles.
|
|
*/
|
|
ON__UINT32 AddBoundary(size_t point_count, const ON_3fPoint* boundary_points, bool bCloseBoundary);
|
|
|
|
/*
|
|
Returns:
|
|
The winding number of the boundary about the winding point.
|
|
*/
|
|
ON__INT32 WindingNumber() const;
|
|
|
|
/*
|
|
Returns:
|
|
The winding point.
|
|
*/
|
|
const ON_2dPoint WindingPoint() const;
|
|
|
|
/*
|
|
Returns:
|
|
Number of segments in the boundary.
|
|
*/
|
|
ON__UINT32 BoundarySegmentCount() const;
|
|
|
|
/*
|
|
Returns:
|
|
The end of the previous call to AddBoundary()
|
|
*/
|
|
const ON_2dPoint PreviousBoundaryPoint() const;
|
|
|
|
private:
|
|
// Location of the winding point.
|
|
ON_2dPoint m_winding_point = ON_2dPoint::NanPoint;
|
|
|
|
// Location of the last boundary point added. This is used
|
|
// by AddBoundary(ON_2dPoint p) to generate a segment
|
|
// from m_prev_boundary_point to p in situations where
|
|
// points are streamed so the caller doesn't have to
|
|
// deal with accumulating the previous point and can
|
|
// mix streamed points with other forms of boundary input.
|
|
ON_2dPoint m_prev_boundary_point = ON_2dPoint::NanPoint;
|
|
|
|
// Number of boundary segments in the polyline
|
|
ON__UINT32 m_boundary_segment_count = 0;
|
|
|
|
// In the comments below, H is the horizontal line throught the winding point
|
|
// and V is the vertical line through the winding point.
|
|
|
|
// signed net number of times polyline crosses H to the left of the winding point.
|
|
// A below to above crossing is -1.
|
|
ON__INT32 m_left_crossing_number = 0;
|
|
|
|
// signed net number of times polyline crosses H to the right of the winding point.
|
|
// A below to above crossing is +1.
|
|
ON__INT32 m_right_crossing_number = 0;
|
|
|
|
// signed net number of times polyline crosses V to the below of the winding point.
|
|
// A left to right crossing is +1.
|
|
ON__INT32 m_below_crossing_number = 0;
|
|
|
|
// signed net number of times polyline crosses V to the above of the winding point.
|
|
// A left to right crossing is -1.
|
|
ON__INT32 m_above_crossing_number = 0;
|
|
|
|
// 0 != (m_status_bits & 1): left crossing occured
|
|
// 0 != (m_status_bits & 2): right crossing occured
|
|
// 0 != (m_status_bits & 4): below crossing occured
|
|
// 0 != (m_status_bits & 8): above crossing occured
|
|
// 0 != (m_status_bits & 16): winding point on horizontal segment
|
|
// 0 != (m_status_bits & 32): winding point on vertical segment
|
|
ON__INT32 m_status_bits = 0;
|
|
|
|
void Internal_AddBoundarySegment(const double* p, const double* q);
|
|
|
|
// Input: p and q are 2d points with p.y <= 0 and q.y > 0
|
|
//
|
|
// Returns:
|
|
// Sign of the x coordinate of the intersection of the line segment from p to q
|
|
// and the x axis.
|
|
static int Internal_SignOfX(const ON_2dPoint& p, const ON_2dPoint& q);
|
|
|
|
// Input: p and q are 2d points with p.x <= 0 and q.x > 0
|
|
//
|
|
// Returns:
|
|
// Sign of the y coordinate of the intersection of the line segment from p to q
|
|
// and the y axis.
|
|
static int Internal_SignOfY(const ON_2dPoint& p, const ON_2dPoint& q);
|
|
|
|
bool Internal_HaveWindingPoint() const;
|
|
};
|
|
|
|
|
|
/*
|
|
ON_PeriodicDomain is a helper class for dealing with closed or periodic surfaces using the idea of a covering space.
|
|
|
|
If a surface is closed in the u-direction (or v respectively), a curve on the surface that crosses the seam
|
|
will not have a continuous pull back to parameter space. However, if we extend the surface domain
|
|
in the u-coordinates and allow the surface to cover itself periodicly, i.e S(u,v) = S(u + T, v) with period T, then we
|
|
can pull back the curve to the domain covering space (-inf,inf) x dom[1].
|
|
|
|
*/
|
|
class ON_CLASS ON_PeriodicDomain
|
|
{
|
|
public:
|
|
ON_PeriodicDomain() = default;
|
|
ON_PeriodicDomain(const ON_Interval dom[2], const bool closed[2], double normband = 1.0 / 3.0);
|
|
void Initialize(const ON_Interval dom[2], const bool closed[2], double normband = 1.0 / 3.0);
|
|
/*
|
|
Construction or Initialization
|
|
Parameters:
|
|
dom -[in] surface domain
|
|
closed -[in] closed[0] is true if the surface is closed in u direction (similary for 1 and v)
|
|
Use ON_IsG1Closed(...) to test for G1-closed surfaces.
|
|
normband - [in] 0<normband<.5 is a normalized coordinate defining a band on each side of the seam.
|
|
The bands are {(u,v): dom[0].NormalizedParameterAt(u)< normband } and
|
|
{(u,v): dom[0].NormalizedParameterAt(u)> 1.0 - normband }
|
|
The point sequence crosses the seam if consecutive points are in opposite bands along the seam.
|
|
*/
|
|
|
|
// Repeatedly call LiftToCover( Pin) with Pin in the domain covering space. The resulting
|
|
// output sequence will be lifted to the domain covering space, and will be 'continuous' in that
|
|
// consecutive points will be in the same or an adjacent band.
|
|
// Use stealth=true to lift this point without affecting the state, this allows one to compute a trial end
|
|
// of sequence.
|
|
// see also ON_LiftToCover(...).
|
|
ON_2dPoint LiftToCover(ON_2dPoint Pin, bool stealth = false);
|
|
|
|
// The projection from covering space back to domain. LiftInverse(LiftToCover(p))==p
|
|
ON_2dPoint LiftInverse(ON_2dPoint p);
|
|
|
|
ON_Interval m_dom[2];
|
|
bool m_closed[2];
|
|
double m_normband;
|
|
private:
|
|
int m_deck[2];
|
|
ON_2dPoint m_nprev = ON_2dPoint::UnsetPoint;
|
|
};
|
|
|
|
|
|
/*
|
|
Lift a sequence of surface points to the covering space.
|
|
|
|
If a surface is closed in the u-direction (or v respectively), a curve on the surface that crosses the seam
|
|
will not have a continuous pull back to parameter space. However, if we extend the surface domain
|
|
in the u-coordinates and allow the surface to cover itself periodiclly then we
|
|
we can pull back the curve to the covering space (-inf,inf) x dom[1].
|
|
Parameters
|
|
in - [in] surface parameter points in dom[0] x dom[1]
|
|
dom -[in] surface domain
|
|
closed -[in] closed[0] is true if the surface is closed in u direction (similary for 1 and v)
|
|
normband - [in] 0<normband<.5 is a normalized coordinate defining a band on each side of the seam.
|
|
The point sequence crosses the seam if consecutive points are in opposite bands
|
|
along the seam.
|
|
Returns
|
|
A sequence out with out[0] = in[0] and out.Count()==in.Count()
|
|
*/
|
|
ON_DECL
|
|
ON_SimpleArray<ON_2dPoint> ON_LiftToCover(
|
|
const ON_SimpleArray<ON_2dPoint>& in,
|
|
const ON_Interval dom[2], bool closed[2],
|
|
double normband = 1.0 / 3.0);
|
|
|
|
/*
|
|
LiftInverse is the projection map that inverts ON_LiftToCover
|
|
Parameters
|
|
P -[in] A point in the domain covering space.
|
|
Returns a point in dom.
|
|
*/
|
|
ON_2dPoint ON_DECL ON_LiftInverse(ON_2dPoint P, ON_Interval dom[2], bool closed[2]);
|
|
|
|
#endif
|
|
|