|
Shinya Kitaoka |
810553 |
#pragma once
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#ifndef T_GEOMETRY_INCLUDED
|
|
Toshihiro Shimizu |
890ddd |
#define T_GEOMETRY_INCLUDED
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#include "tutil.h"
|
|
Shinya Kitaoka |
3bfa54 |
#include <cmath></cmath>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
#undef DVAPI
|
|
Toshihiro Shimizu |
890ddd |
#undef DVVAR
|
|
Toshihiro Shimizu |
890ddd |
#ifdef TGEOMETRY_EXPORTS
|
|
Toshihiro Shimizu |
890ddd |
#define DVAPI DV_EXPORT_API
|
|
Toshihiro Shimizu |
890ddd |
#define DVVAR DV_EXPORT_VAR
|
|
Toshihiro Shimizu |
890ddd |
#else
|
|
Toshihiro Shimizu |
890ddd |
#define DVAPI DV_IMPORT_API
|
|
Toshihiro Shimizu |
890ddd |
#define DVVAR DV_IMPORT_VAR
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
|
911124 |
|
|
|
911124 |
inline double logNormalDistribuitionUnscaled(double x, double x0, double w)
|
|
|
911124 |
{ return exp(-0.5*pow(log(x/x0)/w, 2.0))/x; }
|
|
|
911124 |
|
|
|
911124 |
inline double logNormalDistribuition(double x, double x0, double w)
|
|
|
911124 |
{ return logNormalDistribuitionUnscaled(x, x0, w)/(w*sqrt(2.0*M_PI)); }
|
|
|
911124 |
|
|
|
911124 |
//=============================================================================
|
|
|
f9b4ad |
|
|
|
52176e |
template <class t=""> class T3DPointT;</class>
|
|
|
52176e |
template <class t=""> class T4DPointT;</class>
|
|
|
f9b4ad |
|
|
Shinya Kitaoka |
120a6e |
/*
|
|
Shinya Kitaoka |
120a6e |
* This is an example of how to use the TPointT, the TRectT and the TAffine
|
|
Shinya Kitaoka |
120a6e |
* classes.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
/*! The template class TPointT defines the x- and y-coordinates of a point.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
class TPointT {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
T x, y;
|
|
Shinya Kitaoka |
120a6e |
|
|
|
f278a5 |
inline TPointT() : x(0), y(0){};
|
|
|
52176e |
inline TPointT(T x, T y) : x(x), y(y){};
|
|
|
52176e |
inline explicit TPointT(const T3DPointT<t> &p);</t>
|
|
|
52176e |
inline explicit TPointT(const T4DPointT<t> &p);</t>
|
|
|
52176e |
|
|
|
52176e |
inline TPointT& operator+=(const TPointT &a)
|
|
|
52176e |
{ return x += a.x, y += a.y, *this; };
|
|
|
52176e |
inline TPointT& operator-=(const TPointT &a)
|
|
|
52176e |
{ return x -= a.x, y -= a.y, *this; };
|
|
|
52176e |
inline TPointT operator+(const TPointT &a) const
|
|
|
52176e |
{ return TPointT(x + a.x, y + a.y); };
|
|
|
52176e |
inline TPointT operator-(const TPointT &a) const
|
|
|
52176e |
{ return TPointT(x - a.x, y - a.y); };
|
|
|
52176e |
inline TPointT operator-() const
|
|
|
52176e |
{ return TPointT(-x, -y); };
|
|
|
52176e |
|
|
|
52176e |
//! Scalar(dot) Product
|
|
|
52176e |
inline T operator*(const TPointT &a) const
|
|
|
52176e |
{ return x*a.x + y*a.y; }
|
|
|
52176e |
|
|
|
52176e |
inline TPointT operator*=(T a)
|
|
|
52176e |
{ return x *= a, y *= a, *this; }
|
|
|
52176e |
inline TPointT operator*(T a) const
|
|
|
52176e |
{ return TPointT(x*a, y*a); }
|
|
|
52176e |
friend inline TPointT operator*(T a, const TPointT &b)
|
|
|
52176e |
{ return TPointT(a*b.x, a*b.y); }
|
|
|
52176e |
|
|
|
52176e |
inline TPointT operator/(T a) const
|
|
|
52176e |
{ return TPointT(x/a, y/a); }
|
|
|
52176e |
inline TPointT operator/=(T a)
|
|
|
52176e |
{ return x /= a, y /= a, *this; }
|
|
|
52176e |
|
|
|
52176e |
inline bool operator==(const TPointT &a) const
|
|
|
52176e |
{ return x == a.x && y == a.y; }
|
|
|
52176e |
inline bool operator!=(const TPointT &a) const
|
|
|
52176e |
{ return !(*this == a); }
|
|
|
52176e |
|
|
|
52176e |
friend inline std::ostream &operator<<(std::ostream &out, const TPointT &p)
|
|
|
52176e |
{ return out << "(" << p.x << ", " << p.y << ")"; }
|
|
|
52176e |
|
|
|
52176e |
/*! Rotate a point 90 degrees (counterclockwise).
|
|
|
52176e |
\param p a point.
|
|
|
52176e |
\return the rotated point
|
|
|
52176e |
\sa rotate270 */
|
|
|
52176e |
friend inline TPointT rotate90(const TPointT &p) // 90 counterclockwise
|
|
|
52176e |
{ return TPointT(-p.y, p.x); }
|
|
|
52176e |
|
|
|
52176e |
/*! Rotate a point 270 degrees (clockwise).
|
|
|
52176e |
\param p a point.
|
|
|
52176e |
\return the rotated point
|
|
|
52176e |
\sa rotate90 */
|
|
|
52176e |
friend inline TPointT rotate270(const TPointT &p) // 90 clockwise
|
|
|
52176e |
{ return TPointT(p.y, -p.x); }
|
|
|
52176e |
|
|
|
52176e |
//! This helper function returns the square of the absolute value of the point
|
|
|
52176e |
friend inline T norm2(const TPointT &a)
|
|
|
52176e |
{ return a*a; }
|
|
|
52176e |
|
|
|
52176e |
//! This helper function returns the square of the distance between two points
|
|
|
52176e |
friend inline T tdistance2(const TPointT &a, const TPointT &b)
|
|
|
52176e |
{ return norm2(a - b); }
|
|
|
52176e |
|
|
|
52176e |
//! the cross product
|
|
|
52176e |
friend inline T cross(const TPointT &a, const TPointT &b)
|
|
|
52176e |
{ return a.x*b.y - a.y*b.x; }
|
|
|
f9b4ad |
};
|
|
|
f9b4ad |
|
|
|
52176e |
template <>
|
|
|
52176e |
inline bool TPointT<double>::operator==(const TPointT<double> &a) const</double></double>
|
|
|
52176e |
{ return tdistance2(*this, a) <= TConsts::epsilon * TConsts::epsilon; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef TPointT<int> TPoint, TPointI;</int>
|
|
Toshihiro Shimizu |
890ddd |
typedef TPointT<double> TPointD;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
template class DVAPI TPointT<int>;</int>
|
|
Toshihiro Shimizu |
890ddd |
template class DVAPI TPointT<double>;</double>
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TPointT
|
|
|
52176e |
This helper function converts a TPoint (TPointT<int>) into a TPointD</int>
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
|
52176e |
inline TPointD convert(const TPoint &p)
|
|
|
52176e |
{ return TPointD(p.x, p.y); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TPointT
|
|
|
52176e |
This helper function converts a TPointD (TPointT<double>) into a TPoint</double>
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
|
52176e |
inline TPoint convert(const TPointD &p)
|
|
|
52176e |
{ return TPoint(tround(p.x), tround(p.y)); }
|
|
|
52176e |
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TPointT
|
|
Shinya Kitaoka |
120a6e |
This helper function returns the absolute value of the specified point
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
inline double norm(const TPointD &p) { return std::sqrt(norm2(p)); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TPointT
|
|
Shinya Kitaoka |
120a6e |
This helper function returns the normalized version of the specified point
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
inline TPointD normalize(const TPointD &p) {
|
|
Shinya Kitaoka |
120a6e |
double n = norm(p);
|
|
|
52176e |
assert(n);
|
|
|
52176e |
return p*(1/n);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TPointT
|
|
|
fa009d |
This helper function returns the normalized version of the specified point
|
|
|
fa009d |
or zero if it is not possible
|
|
|
fa009d |
*/
|
|
|
fa009d |
inline TPointD normalizeOrZero(const TPointD &p) {
|
|
|
fa009d |
double n = norm2(p);
|
|
|
fa009d |
return fabs(n) > TConsts::epsilon*TConsts::epsilon ? p*(1/sqrt(n)) : TPointD();
|
|
|
fa009d |
}
|
|
|
fa009d |
|
|
|
fa009d |
/*!
|
|
|
fa009d |
\relates TPointT
|
|
Shinya Kitaoka |
120a6e |
This helper function returns the distance between two points
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
|
52176e |
inline double tdistance(const TPointD &p1, const TPointD &p2)
|
|
|
52176e |
{ return norm(p2 - p1); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
returns the angle of the point p in polar coordinates
|
|
Toshihiro Shimizu |
890ddd |
n.b atan(-y) = -pi/2, atan(x) = 0, atan(y) = pi/2, atan(-x) = pi
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
inline double atan(const TPointD &p) { return atan2(p.y, p.x); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
class DVAPI T3DPointT {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
T x, y, z;
|
|
Shinya Kitaoka |
120a6e |
|
|
|
52176e |
inline T3DPointT() : x(), y(), z() {}
|
|
|
52176e |
inline T3DPointT(T x, T y, T z) : x(x), y(y), z(z) {}
|
|
|
52176e |
inline T3DPointT(const TPointT<t> &p, T z) : x(p.x), y(p.y), z(z) {}</t>
|
|
|
52176e |
inline explicit T3DPointT(const T4DPointT<t> &p);</t>
|
|
|
52176e |
|
|
|
52176e |
inline TPointT<t>& xy() { return *(TPointT<t>*)this; }</t></t>
|
|
|
52176e |
inline TPointT<t>& xy() const { return *(const TPointT<t>*)this; }</t></t>
|
|
|
52176e |
|
|
|
52176e |
inline T3DPointT &operator+=(const T3DPointT &a)
|
|
|
52176e |
{ return x += a.x, y += a.y, z += a.z, *this; }
|
|
|
52176e |
inline T3DPointT &operator-=(const T3DPointT &a)
|
|
|
52176e |
{ return x -= a.x, y -= a.y, z -= a.z, *this; }
|
|
|
52176e |
inline T3DPointT operator+(const T3DPointT &a) const
|
|
|
52176e |
{ return T3DPointT(x + a.x, y + a.y, z + a.z); }
|
|
|
52176e |
inline T3DPointT operator-(const T3DPointT &a) const
|
|
|
52176e |
{ return T3DPointT(x - a.x, y - a.y, z - a.z); }
|
|
|
52176e |
inline T3DPointT operator-() const
|
|
|
52176e |
{ return T3DPointT(-x, -y, -z); }
|
|
|
52176e |
|
|
|
52176e |
//! Scalar(dot) Product
|
|
|
52176e |
inline T operator*(const T3DPointT &a) const
|
|
|
52176e |
{ return x*a.x + y*a.y + z*a.z; }
|
|
|
52176e |
|
|
|
52176e |
inline T3DPointT operator*=(T a)
|
|
|
52176e |
{ return x *= a, y *= a, z *= a, *this; }
|
|
|
52176e |
inline T3DPointT operator*(T a) const
|
|
|
52176e |
{ return T3DPointT(x*a, y*a, z*a); }
|
|
|
52176e |
friend inline T3DPointT operator*(T a, const T3DPointT &b)
|
|
|
52176e |
{ return T3DPointT(a*b.x, a*b.y, a*b.z); }
|
|
|
52176e |
|
|
|
52176e |
inline T3DPointT operator/(T a) const
|
|
|
52176e |
{ return T3DPointT(x/a, y/a, z/a); }
|
|
|
52176e |
inline T3DPointT operator/=(T a)
|
|
|
52176e |
{ return x /= a, y /= a, z /= a, *this; }
|
|
|
52176e |
|
|
|
52176e |
inline bool operator==(const T3DPointT &a) const
|
|
|
52176e |
{ return x == a.x && y == a.y && z == a.z; }
|
|
|
52176e |
inline bool operator!=(const T3DPointT &a) const
|
|
|
52176e |
{ return !(*this == a); }
|
|
|
52176e |
|
|
|
52176e |
friend inline std::ostream &operator<<(std::ostream &out, const T3DPointT &p)
|
|
|
52176e |
{ return out << "(" << p.x << ", " << p.y << ", " << p.z << ")"; }
|
|
|
52176e |
|
|
|
52176e |
//! This helper function returns the square of the absolute value of the point
|
|
|
52176e |
friend inline T norm2(const T3DPointT &a)
|
|
|
52176e |
{ return a*a; }
|
|
|
52176e |
|
|
|
52176e |
//! This helper function returns the square of the distance between two points
|
|
|
52176e |
friend inline T tdistance2(const T3DPointT &a, const T3DPointT &b)
|
|
|
52176e |
{ return norm2(a - b); }
|
|
|
52176e |
|
|
|
52176e |
//! the cross product
|
|
|
52176e |
friend inline T3DPointT cross(const T3DPointT &a, const T3DPointT &b) {
|
|
|
52176e |
return T3DPointT( a.y*b.z - b.y*a.z,
|
|
|
52176e |
a.z*b.x - b.z*a.x,
|
|
|
52176e |
a.x*b.y - b.x*a.y);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
52176e |
template <>
|
|
|
52176e |
inline bool T3DPointT<double>::operator==(const T3DPointT<double> &a) const</double></double>
|
|
|
52176e |
{ return tdistance2(*this, a) <= TConsts::epsilon * TConsts::epsilon; }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
|
52176e |
inline TPointT<t>::TPointT(const T3DPointT<t> &p) : x(p.x), y(p.y) {};</t></t>
|
|
|
52176e |
|
|
|
52176e |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef T3DPointT<int> T3DPoint, T3DPointI;</int>
|
|
Toshihiro Shimizu |
890ddd |
typedef T3DPointT<double> T3DPointD;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
template class DVAPI T3DPointT<int>;</int>
|
|
Toshihiro Shimizu |
890ddd |
template class DVAPI T3DPointT<double>;</double>
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
52176e |
inline T3DPointD convert(const T3DPoint &p)
|
|
|
52176e |
{ return T3DPointD(p.x, p.y, p.z); }
|
|
|
52176e |
inline T3DPoint convert(const T3DPointD &p)
|
|
|
52176e |
{ return T3DPoint(tround(p.x), tround(p.y), tround(p.z)); }
|
|
|
52176e |
|
|
|
52176e |
inline double norm(const T3DPointD &p)
|
|
|
52176e |
{ return std::sqrt(norm2(p)); }
|
|
|
52176e |
|
|
|
52176e |
inline T3DPointD normalize(const T3DPointD &p) {
|
|
|
52176e |
double n = norm(p);
|
|
|
52176e |
assert(n);
|
|
|
52176e |
return p*(1/n);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
52176e |
inline T3DPointD normalizeOrZero(const T3DPointD &p) {
|
|
|
52176e |
double n = norm2(p);
|
|
|
52176e |
return fabs(n) > TConsts::epsilon*TConsts::epsilon ? p*(1/sqrt(n)) : T3DPointD();
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
52176e |
inline double tdistance(const T3DPointD &p1, const T3DPointD &p2)
|
|
|
52176e |
{ return norm(p2 - p1); }
|
|
|
52176e |
|
|
|
52176e |
//=============================================================================
|
|
|
52176e |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
|
52176e |
class DVAPI T4DPointT {
|
|
|
52176e |
public:
|
|
|
52176e |
T x, y, z, w;
|
|
|
52176e |
|
|
|
52176e |
inline T4DPointT() : x(), y(), z(), w() {}
|
|
|
52176e |
inline T4DPointT(T x, T y, T z, T w) : x(x), y(y), z(z), w(w) {}
|
|
|
52176e |
inline T4DPointT(const TPointT<t> &p, T z, T w) : x(p.x), y(p.y), z(z), w(w) {}</t>
|
|
|
52176e |
inline T4DPointT(const T3DPointT<t> &p, T w) : x(p.x), y(p.y), z(p.z), w(w) {}</t>
|
|
|
52176e |
|
|
|
52176e |
inline TPointT<t>& xy() { return *(TPointT<t>*)this; }</t></t>
|
|
|
52176e |
inline T3DPointT<t>& xyz() { return *(T3DPointT<t>*)this; }</t></t>
|
|
|
52176e |
|
|
|
52176e |
inline TPointT<t>& xy() const { return *(const TPointT<t>*)this; }</t></t>
|
|
|
52176e |
inline T3DPointT<t>& xyz() const { return *(const T3DPointT<t>*)this; }</t></t>
|
|
|
52176e |
|
|
|
52176e |
inline bool operator==(const T4DPointT &p) const
|
|
|
52176e |
{ return x == p.x && y == p.y && z == p.z && w == p.w; }
|
|
|
52176e |
inline bool operator!=(const T4DPointT &p) const
|
|
|
52176e |
{ return !(*this == p); }
|
|
|
52176e |
|
|
|
52176e |
friend inline std::ostream &operator<<(std::ostream &out, const T4DPointT &p)
|
|
|
52176e |
{ return out << "(" << p.x << ", " << p.y << ", " << p.z << ", " << p.w << ")"; }
|
|
|
52176e |
};
|
|
|
52176e |
|
|
|
52176e |
template <>
|
|
|
52176e |
inline bool T4DPointT<double>::operator==(const T4DPointT<double> &a) const {</double></double>
|
|
|
52176e |
T4DPointT<double> d(x - a.x, y - a.y, z - a.z, w - a.w);</double>
|
|
|
52176e |
return d.x*d.x + d.y*d.y + d.z*d.z + d.w*d.w
|
|
|
52176e |
<= TConsts::epsilon * TConsts::epsilon;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
|
52176e |
inline TPointT<t>::TPointT(const T4DPointT<t> &p) : x(p.x), y(p.y) {};</t></t>
|
|
|
52176e |
template <class t=""></class>
|
|
|
52176e |
inline T3DPointT<t>::T3DPointT(const T4DPointT<t> &p) : x(p.x), y(p.y), z(p.z) {};</t></t>
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
52176e |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
52176e |
typedef T4DPointT<int> T4DPoint, T4DPointI;</int>
|
|
|
52176e |
typedef T4DPointT<double> T4DPointD;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
52176e |
#ifdef _WIN32
|
|
|
52176e |
template class DVAPI T4DPointT<int>;</int>
|
|
|
52176e |
template class DVAPI T4DPointT<double>;</double>
|
|
|
52176e |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
52176e |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
52176e |
//!\relates T4DPointT
|
|
|
52176e |
|
|
|
52176e |
inline T4DPointD convert(const T4DPoint &p)
|
|
|
52176e |
{ return T4DPointD(p.x, p.y, p.z, p.w); }
|
|
|
52176e |
inline T4DPoint convert(const T4DPointD &p)
|
|
|
52176e |
{ return T4DPoint(tround(p.x), tround(p.y), tround(p.z), tround(p.w)); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Toshihiro Shimizu |
890ddd |
TThickPoint describe a thick point.
|
|
Toshihiro Shimizu |
890ddd |
\relates TThickQuadratic, TThickCubic
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
d1f6c4 |
class DVAPI TThickPoint final : public TPointD {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
double thick;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint() : TPointD(), thick(0) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint(double _x, double _y, double _thick = 0)
|
|
Shinya Kitaoka |
120a6e |
: TPointD(_x, _y), thick(_thick) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint(const TPointD &_p, double _thick = 0)
|
|
Shinya Kitaoka |
120a6e |
: TPointD(_p.x, _p.y), thick(_thick) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint(const T3DPointD &_p) : TPointD(_p.x, _p.y), thick(_p.z) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TThickPoint(const TThickPoint &_p) : TPointD(_p.x, _p.y), thick(_p.thick) {}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline TThickPoint &operator=(const TThickPoint &a) {
|
|
Shinya Kitaoka |
120a6e |
x = a.x;
|
|
Shinya Kitaoka |
120a6e |
y = a.y;
|
|
Shinya Kitaoka |
120a6e |
thick = a.thick;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline TThickPoint &operator+=(const TThickPoint &a) {
|
|
Shinya Kitaoka |
120a6e |
x += a.x;
|
|
Shinya Kitaoka |
120a6e |
y += a.y;
|
|
Shinya Kitaoka |
120a6e |
thick += a.thick;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline TThickPoint &operator-=(const TThickPoint &a) {
|
|
Shinya Kitaoka |
120a6e |
x -= a.x;
|
|
Shinya Kitaoka |
120a6e |
y -= a.y;
|
|
Shinya Kitaoka |
120a6e |
thick -= a.thick;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline TThickPoint operator+(const TThickPoint &a) const {
|
|
Shinya Kitaoka |
120a6e |
return TThickPoint(x + a.x, y + a.y, thick + a.thick);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline TThickPoint operator-(const TThickPoint &a) const {
|
|
Shinya Kitaoka |
120a6e |
return TThickPoint(x - a.x, y - a.y, thick - a.thick);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
inline TThickPoint operator-() const { return TThickPoint(-x, -y, -thick); }
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool operator==(const TThickPoint &p) const {
|
|
Shinya Kitaoka |
120a6e |
return x == p.x && y == p.y && thick == p.thick;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool operator!=(const TThickPoint &p) const {
|
|
Shinya Kitaoka |
120a6e |
return x != p.x || y != p.y || thick != p.thick;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline double operator*(const TThickPoint &a, const TThickPoint &b) {
|
|
Shinya Kitaoka |
120a6e |
return a.x * b.x + a.y * b.y + a.thick * b.thick;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline TThickPoint operator*(double a, const TThickPoint &p) {
|
|
Shinya Kitaoka |
120a6e |
return TThickPoint(a * p.x, a * p.y, a * p.thick);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline TThickPoint operator*(const TThickPoint &p, double a) {
|
|
Shinya Kitaoka |
120a6e |
return TThickPoint(a * p.x, a * p.y, a * p.thick);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TPointD
|
|
Toshihiro Shimizu |
890ddd |
This helper function converts a TThickPoint into a TPointD
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
inline TPointD convert(const TThickPoint &p) { return TPointD(p.x, p.y); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TThickPoint
|
|
Shinya Kitaoka |
120a6e |
This helper function returns the square of the distance between two thick points
|
|
Toshihiro Shimizu |
890ddd |
(only x and y are used)
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
inline double tdistance2(const TThickPoint &p1, const TThickPoint &p2) {
|
|
Shinya Kitaoka |
120a6e |
return norm2(convert(p2 - p1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TThickPoint
|
|
Shinya Kitaoka |
120a6e |
This helper function returns the distance between two thick points
|
|
Toshihiro Shimizu |
890ddd |
(only x and y are used)
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
inline double tdistance(const TThickPoint &p1, const TThickPoint &p2) {
|
|
Shinya Kitaoka |
120a6e |
return norm(convert(p2 - p1));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline std::ostream &operator<<(std::ostream &out, const TThickPoint &p) {
|
|
Shinya Kitaoka |
120a6e |
return out << "(" << p.x << ", " << p.y << ", " << p.thick << ")";
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Shinya Kitaoka |
120a6e |
//! This is a template class representing a generic vector in a plane, i.e.
|
|
Shinya Kitaoka |
38fd86 |
//! a point.
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
It is a data structure with two objects in it representing
|
|
Shinya Kitaoka |
120a6e |
coordinate of the point and
|
|
Shinya Kitaoka |
120a6e |
the basic operations on it.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
class DVAPI TDimensionT {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
T lx, ly;
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Constructs a vector of two elements, i.e. a point in a plane.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
TDimensionT() : lx(), ly() {}
|
|
Shinya Kitaoka |
120a6e |
TDimensionT(T _lx, T _ly) : lx(_lx), ly(_ly) {}
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Copy constructor.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
TDimensionT(const TDimensionT &d) : lx(d.lx), ly(d.ly) {}
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Vector addition.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
TDimensionT &operator+=(TDimensionT a) {
|
|
Shinya Kitaoka |
120a6e |
lx += a.lx;
|
|
Shinya Kitaoka |
120a6e |
ly += a.ly;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Difference of two vectors.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
TDimensionT &operator-=(TDimensionT a) {
|
|
Shinya Kitaoka |
120a6e |
lx -= a.lx;
|
|
Shinya Kitaoka |
120a6e |
ly -= a.ly;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Addition of two vectors.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
TDimensionT operator+(TDimensionT a) const {
|
|
Shinya Kitaoka |
120a6e |
TDimensionT ris(*this);
|
|
Shinya Kitaoka |
120a6e |
return ris += a;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Vector difference.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
TDimensionT operator-(TDimensionT a) const {
|
|
Shinya Kitaoka |
120a6e |
TDimensionT ris(*this);
|
|
Shinya Kitaoka |
120a6e |
return ris -= a;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Compare vectors and returns \e true if are equals element by element.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
bool operator==(const TDimensionT &d) const {
|
|
Shinya Kitaoka |
120a6e |
return lx == d.lx && ly == d.ly;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Compare vectors and returns \e true if are not equals element by
|
|
Shinya Kitaoka |
120a6e |
element.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
bool operator!=(const TDimensionT &d) const { return !operator==(d); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef TDimensionT<int> TDimension, TDimensionI;</int>
|
|
Toshihiro Shimizu |
890ddd |
typedef TDimensionT<double> TDimensionD;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
inline std::ostream &operator<<(std::ostream &out, const TDimensionT<t> &p) {</t>
|
|
Shinya Kitaoka |
120a6e |
return out << "(" << p.lx << ", " << p.ly << ")";
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
template class DVAPI TDimensionT<int>;</int>
|
|
Toshihiro Shimizu |
890ddd |
template class DVAPI TDimensionT<double>;</double>
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//! Specifies the corners of a rectangle.
|
|
Jeremy Bullock |
66c844 |
/*!
|
|
Jeremy Bullock |
66c844 |
x0 specifies the x-coordinate of the bottom-left corner of a rectangle.
|
|
Jeremy Bullock |
66c844 |
y0 specifies the y-coordinate of the bottom-left corner of a rectangle.
|
|
Jeremy Bullock |
66c844 |
x1 specifies the x-coordinate of the upper-right corner of a rectangle.
|
|
Jeremy Bullock |
66c844 |
y1 specifies the y-coordinate of the upper-right corner of a rectangle.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
class DVAPI TRectT {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
/*! if x0>x1 || y0>y1 then rect is empty
|
|
Shinya Kitaoka |
120a6e |
if x0==y1 && y0==y1 and rect is a TRectD then rect is empty */
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T x0, y0;
|
|
Shinya Kitaoka |
120a6e |
T x1, y1;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*! makes an empty rect */
|
|
Shinya Kitaoka |
120a6e |
TRectT();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectT(T _x0, T _y0, T _x1, T _y1) : x0(_x0), y0(_y0), x1(_x1), y1(_y1){};
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
TRectT(const TRectT &rect)
|
|
Shinya Kitaoka |
120a6e |
: x0(rect.x0), y0(rect.y0), x1(rect.x1), y1(rect.y1){};
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
TRectT(const TPointT<t> &p0, const TPointT<t> &p1) // non importa l'ordine</t></t>
|
|
Shinya Kitaoka |
120a6e |
: x0(std::min((T)p0.x, (T)p1.x)),
|
|
Shinya Kitaoka |
120a6e |
y0(std::min((T)p0.y, (T)p1.y)),
|
|
Shinya Kitaoka |
120a6e |
x1(std::max((T)p0.x, (T)p1.x)),
|
|
Shinya Kitaoka |
120a6e |
y1(std::max((T)p0.y, (T)p1.y)){};
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
TRectT(const TPointT<t> &bottomLeft, const TDimensionT<t> &d);</t></t>
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
TRectT(const TDimensionT<t> &d);</t>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
void empty();
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*! TRectD is empty if and only if (x0>x1 || y0>y1) || (x0==y1 && y0==y1);
|
|
Shinya Kitaoka |
120a6e |
TRectI is empty if x0>x1 || y0>y1 */
|
|
Shinya Kitaoka |
120a6e |
bool isEmpty() const;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
T getLx() const;
|
|
Shinya Kitaoka |
120a6e |
T getLy() const;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TDimensionT<t> getSize() const { return TDimensionT<t>(getLx(), getLy()); };</t></t>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TPointT<t> getP00() const { return TPointT<t>(x0, y0); };</t></t>
|
|
Shinya Kitaoka |
120a6e |
TPointT<t> getP10() const { return TPointT<t>(x1, y0); };</t></t>
|
|
Shinya Kitaoka |
120a6e |
TPointT<t> getP01() const { return TPointT<t>(x0, y1); };</t></t>
|
|
Shinya Kitaoka |
120a6e |
TPointT<t> getP11() const { return TPointT<t>(x1, y1); };</t></t>
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
//! Returns the union of two source rectangles.
|
|
Jeremy Bullock |
66c844 |
//!The union is the smallest rectangle that contains both source rectangles.
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> operator+(const TRectT<t> &rect) const { // unione</t></t>
|
|
Shinya Kitaoka |
120a6e |
if (isEmpty())
|
|
Shinya Kitaoka |
120a6e |
return rect;
|
|
Shinya Kitaoka |
120a6e |
else if (rect.isEmpty())
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Jeremy Bullock |
66c844 |
return TRectT<t>(std::min((T)x0, (T)rect.x0), </t>
|
|
Jeremy Bullock |
66c844 |
std::min((T)y0, (T)rect.y0),
|
|
Shinya Kitaoka |
120a6e |
std::max((T)x1, (T)rect.x1),
|
|
Shinya Kitaoka |
120a6e |
std::max((T)y1, (T)rect.y1));
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> &operator+=(const TRectT<t> &rect) { // unione</t></t>
|
|
Shinya Kitaoka |
120a6e |
return *this = *this + rect;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> &operator*=(const TRectT<t> &rect) { // intersezione</t></t>
|
|
Shinya Kitaoka |
120a6e |
return *this = *this * rect;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
66c844 |
//!Returns the intersection of two existing rectangles.
|
|
Jeremy Bullock |
66c844 |
//The intersection is the largest rectangle contained in both existing rectangles.
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> operator*(const TRectT<t> &rect) const { // intersezione</t></t>
|
|
Shinya Kitaoka |
120a6e |
if (isEmpty() || rect.isEmpty())
|
|
Shinya Kitaoka |
120a6e |
return TRectT<t>();</t>
|
|
Shinya Kitaoka |
120a6e |
else if (rect.x1 < x0 || x1 < rect.x0 || rect.y1 < y0 || y1 < rect.y0)
|
|
Shinya Kitaoka |
120a6e |
return TRectT<t>();</t>
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
return TRectT<t>(std::max((T)x0, (T)rect.x0), std::max((T)y0, (T)rect.y0),</t>
|
|
Shinya Kitaoka |
120a6e |
std::min((T)x1, (T)rect.x1),
|
|
Shinya Kitaoka |
120a6e |
std::min((T)y1, (T)rect.y1));
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Jeremy Bullock |
66c844 |
TRectT<t> &operator+=(const TPointT<t> &p) { // shift</t></t>
|
|
Shinya Kitaoka |
120a6e |
x0 += p.x;
|
|
Shinya Kitaoka |
120a6e |
y0 += p.y;
|
|
Shinya Kitaoka |
120a6e |
x1 += p.x;
|
|
Shinya Kitaoka |
120a6e |
y1 += p.y;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> &operator-=(const TPointT<t> &p) {</t></t>
|
|
Shinya Kitaoka |
120a6e |
x0 -= p.x;
|
|
Shinya Kitaoka |
120a6e |
y0 -= p.y;
|
|
Shinya Kitaoka |
120a6e |
x1 -= p.x;
|
|
Shinya Kitaoka |
120a6e |
y1 -= p.y;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> operator+(const TPointT<t> &p) const {</t></t>
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> ris(*this);</t>
|
|
Shinya Kitaoka |
120a6e |
return ris += p;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> operator-(const TPointT<t> &p) const {</t></t>
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> ris(*this);</t>
|
|
Shinya Kitaoka |
120a6e |
return ris -= p;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool operator==(const TRectT<t> &r) const {</t>
|
|
Shinya Kitaoka |
120a6e |
return x0 == r.x0 && y0 == r.y0 && x1 == r.x1 && y1 == r.y1;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool operator!=(const TRectT<t> &r) const {</t>
|
|
Shinya Kitaoka |
120a6e |
return x0 != r.x0 || y0 != r.y0 || x1 != r.x1 || y1 != r.y1;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool contains(const TPointT<t> &p) const {</t>
|
|
Shinya Kitaoka |
120a6e |
return x0 <= p.x && p.x <= x1 && y0 <= p.y && p.y <= y1;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool contains(const TRectT<t> &b) const {</t>
|
|
Shinya Kitaoka |
120a6e |
return x0 <= b.x0 && x1 >= b.x1 && y0 <= b.y0 && y1 >= b.y1;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
bool overlaps(const TRectT<t> &b) const {</t>
|
|
Shinya Kitaoka |
120a6e |
return x0 <= b.x1 && x1 >= b.x0 && y0 <= b.y1 && y1 >= b.y0;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> enlarge(T dx, T dy) const {</t>
|
|
Shinya Kitaoka |
120a6e |
if (isEmpty()) return *this;
|
|
Shinya Kitaoka |
120a6e |
return TRectT<t>(x0 - dx, y0 - dy, x1 + dx, y1 + dy);</t>
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> enlarge(T d) const { return enlarge(d, d); };</t>
|
|
Shinya Kitaoka |
120a6e |
TRectT<t> enlarge(TDimensionT<t> d) const { return enlarge(d.lx, d.ly); };</t></t>
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
typedef TRectT<int> TRect, TRectI;</int>
|
|
Toshihiro Shimizu |
890ddd |
typedef TRectT<double> TRectD;</double>
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
9f5a1b |
#ifdef _WIN32
|
|
Toshihiro Shimizu |
890ddd |
template class DVAPI TRectT<int>;</int>
|
|
Toshihiro Shimizu |
890ddd |
template class DVAPI TRectT<double>;</double>
|
|
Toshihiro Shimizu |
890ddd |
#endif
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// check this, not final version
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Toshihiro Shimizu |
890ddd |
\relates TRectT
|
|
Toshihiro Shimizu |
890ddd |
Convert a TRectD into a TRect
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Jeremy Bullock |
66c844 |
|
|
Shinya Kitaoka |
120a6e |
inline TRect convert(const TRectD &r) {
|
|
Shinya Kitaoka |
120a6e |
return TRect((int)(r.x0 + 0.5), (int)(r.y0 + 0.5), (int)(r.x1 + 0.5),
|
|
Shinya Kitaoka |
120a6e |
(int)(r.y1 + 0.5));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TRectT
|
|
Toshihiro Shimizu |
890ddd |
Convert a TRect into a TRectD
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
inline TRectD convert(const TRect &r) { return TRectD(r.x0, r.y0, r.x1, r.y1); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
// template?
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TRectT
|
|
Shinya Kitaoka |
120a6e |
\relates TPointT
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
inline TRectD boundingBox(const TPointD &p0, const TPointD &p1) {
|
|
Jeremy Bullock |
66c844 |
return TRectD(std::min(p0.x, p1.x), std::min(p0.y, p1.y), // bottom left
|
|
Jeremy Bullock |
66c844 |
std::max(p0.x, p1.x), std::max(p0.y, p1.y)); // top right
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TRectT
|
|
Shinya Kitaoka |
120a6e |
\relates TPointT
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
inline TRectD boundingBox(const TPointD &p0, const TPointD &p1,
|
|
Shinya Kitaoka |
120a6e |
const TPointD &p2) {
|
|
Shinya Kitaoka |
120a6e |
return TRectD(std::min({p0.x, p1.x, p2.x}), std::min({p0.y, p1.y, p2.y}),
|
|
Shinya Kitaoka |
120a6e |
std::max({p0.x, p1.x, p2.x}), std::max({p0.y, p1.y, p2.y}));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Shinya Kitaoka |
120a6e |
\relates TRectT
|
|
Shinya Kitaoka |
120a6e |
\relates TPointT
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
inline TRectD boundingBox(const TPointD &p0, const TPointD &p1,
|
|
Shinya Kitaoka |
120a6e |
const TPointD &p2, const TPointD &p3) {
|
|
Shinya Kitaoka |
120a6e |
return TRectD(
|
|
Shinya Kitaoka |
120a6e |
std::min({p0.x, p1.x, p2.x, p3.x}), std::min({p0.y, p1.y, p2.y, p3.y}),
|
|
Shinya Kitaoka |
120a6e |
std::max({p0.x, p1.x, p2.x, p3.x}), std::max({p0.y, p1.y, p2.y, p3.y}));
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Jeremy Bullock |
66c844 |
// TRectT is a rectangle that uses thick points
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Toshihiro Shimizu |
890ddd |
inline TRectT<int>::TRectT() : x0(0), y0(0), x1(-1), y1(-1) {}</int>
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
inline TRectT<int>::TRectT(const TPointT<int> &bottomLeft,</int></int>
|
|
Shinya Kitaoka |
120a6e |
const TDimensionT<int> &d)</int>
|
|
Shinya Kitaoka |
120a6e |
: x0(bottomLeft.x)
|
|
Shinya Kitaoka |
120a6e |
, y0(bottomLeft.y)
|
|
Shinya Kitaoka |
120a6e |
, x1(bottomLeft.x + d.lx - 1)
|
|
Shinya Kitaoka |
120a6e |
, y1(bottomLeft.y + d.ly - 1){};
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Toshihiro Shimizu |
890ddd |
inline TRectT<int>::TRectT(const TDimensionT<int> &d)</int></int>
|
|
Shinya Kitaoka |
120a6e |
: x0(0), y0(0), x1(d.lx - 1), y1(d.ly - 1){};
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
inline bool TRectT<int>::isEmpty() const {</int>
|
|
Shinya Kitaoka |
120a6e |
return x0 > x1 || y0 > y1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
inline void TRectT<int>::empty() {</int>
|
|
Shinya Kitaoka |
120a6e |
x0 = y0 = 0;
|
|
Shinya Kitaoka |
120a6e |
x1 = y1 = -1;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Jeremy Bullock |
66c844 |
|
|
Jeremy Bullock |
66c844 |
// Is the adding of one here to account for the thickness?
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
inline int TRectT<int>::getLx() const {</int>
|
|
Shinya Kitaoka |
120a6e |
return x1 >= x0 ? x1 - x0 + 1 : 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
inline int TRectT<int>::getLy() const {</int>
|
|
Shinya Kitaoka |
120a6e |
return y1 >= y0 ? y1 - y0 + 1 : 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Toshihiro Shimizu |
890ddd |
inline TRectT<double>::TRectT() : x0(0), y0(0), x1(0), y1(0) {}</double>
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
inline TRectT<double>::TRectT(const TPointT<double> &bottomLeft,</double></double>
|
|
Shinya Kitaoka |
120a6e |
const TDimensionT<double> &d)</double>
|
|
Shinya Kitaoka |
120a6e |
: x0(bottomLeft.x)
|
|
Shinya Kitaoka |
120a6e |
, y0(bottomLeft.y)
|
|
Shinya Kitaoka |
120a6e |
, x1(bottomLeft.x + d.lx)
|
|
Shinya Kitaoka |
120a6e |
, y1(bottomLeft.y + d.ly){};
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Toshihiro Shimizu |
890ddd |
inline TRectT<double>::TRectT(const TDimensionT<double> &d)</double></double>
|
|
Shinya Kitaoka |
120a6e |
: x0(0.0), y0(0.0), x1(d.lx), y1(d.ly){};
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
inline bool TRectT<double>::isEmpty() const {</double>
|
|
Shinya Kitaoka |
120a6e |
return (x0 == x1 && y0 == y1) || x0 > x1 || y0 > y1;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
inline void TRectT<double>::empty() {</double>
|
|
Shinya Kitaoka |
120a6e |
x0 = y0 = x1 = y1 = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
inline double TRectT<double>::getLx() const {</double>
|
|
Shinya Kitaoka |
120a6e |
return x1 >= x0 ? x1 - x0 : 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
template <>
|
|
Shinya Kitaoka |
120a6e |
inline double TRectT<double>::getLy() const {</double>
|
|
Shinya Kitaoka |
120a6e |
return y1 >= y0 ? y1 - y0 : 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline TRectD &operator*=(TRectD &rect, double factor) {
|
|
Shinya Kitaoka |
120a6e |
rect.x0 *= factor;
|
|
Shinya Kitaoka |
120a6e |
rect.y0 *= factor;
|
|
Shinya Kitaoka |
120a6e |
rect.x1 *= factor;
|
|
Shinya Kitaoka |
120a6e |
rect.y1 *= factor;
|
|
Shinya Kitaoka |
120a6e |
return rect;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline TRectD operator*(const TRectD &rect, double factor) {
|
|
Shinya Kitaoka |
120a6e |
TRectD result(rect);
|
|
Shinya Kitaoka |
120a6e |
return result *= factor;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline TRectD &operator/=(TRectD &rect, double factor) {
|
|
Shinya Kitaoka |
120a6e |
assert(factor != 0.0);
|
|
Shinya Kitaoka |
120a6e |
return rect *= (1.0 / factor);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline TRectD operator/(const TRectD &rect, double factor) {
|
|
Shinya Kitaoka |
120a6e |
assert(factor != 0.0);
|
|
Shinya Kitaoka |
120a6e |
TRectD result(rect);
|
|
Shinya Kitaoka |
120a6e |
return result *= 1.0 / factor;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
template <class t=""></class>
|
|
Shinya Kitaoka |
120a6e |
inline std::ostream &operator<<(std::ostream &out, const TRectT<t> &r) {</t>
|
|
Shinya Kitaoka |
120a6e |
return out << "(" << r.x0 << "," << r.y0 << ";" << r.x1 << "," << r.y1 << ")";
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
namespace TConsts {
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
extern DVVAR const TPointD napd;
|
|
Toshihiro Shimizu |
890ddd |
extern DVVAR const TPoint nap;
|
|
Toshihiro Shimizu |
890ddd |
extern DVVAR const T3DPointD nap3d;
|
|
Toshihiro Shimizu |
890ddd |
extern DVVAR const TThickPoint natp;
|
|
Toshihiro Shimizu |
890ddd |
extern DVVAR const TRectD infiniteRectD;
|
|
Toshihiro Shimizu |
890ddd |
extern DVVAR const TRectI infiniteRectI;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//=============================================================================
|
|
Shinya Kitaoka |
120a6e |
//! This is the base class for the affine transformations.
|
|
Toshihiro Shimizu |
890ddd |
/*!
|
|
Jeremy Bullock |
66c844 |
This class performs basic manipulations of affine transformations.
|
|
Jeremy Bullock |
66c844 |
An affine transformation is a linear transformation followed by a translation.
|
|
Jeremy Bullock |
66c844 |
|
|
Jeremy Bullock |
66c844 |
[a11, a12, a13]
|
|
Jeremy Bullock |
66c844 |
[a21, a22, a23]
|
|
Jeremy Bullock |
66c844 |
|
|
Jeremy Bullock |
66c844 |
a13 and a23 represent translation (moving sideways or up and down)
|
|
Jeremy Bullock |
66c844 |
the other 4 handle rotation, scale and shear
|
|
Jeremy Bullock |
66c844 |
*/
|
|
Shinya Kitaoka |
120a6e |
class DVAPI TAffine {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
double a11, a12, a13;
|
|
Shinya Kitaoka |
120a6e |
double a21, a22, a23;
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
By default the object is initialized with a null matrix and a null
|
|
Shinya Kitaoka |
120a6e |
translation vector.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
TAffine() : a11(1.0), a12(0.0), a13(0.0), a21(0.0), a22(1.0), a23(0.0){};
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Initializes the internal matrix and vector of translation with the
|
|
Shinya Kitaoka |
120a6e |
user values.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
TAffine(double p11, double p12, double p13, double p21, double p22,
|
|
Shinya Kitaoka |
120a6e |
double p23)
|
|
Shinya Kitaoka |
120a6e |
: a11(p11), a12(p12), a13(p13), a21(p21), a22(p22), a23(p23){};
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Copy constructor.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
TAffine(const TAffine &a)
|
|
Shinya Kitaoka |
120a6e |
: a11(a.a11)
|
|
Shinya Kitaoka |
120a6e |
, a12(a.a12)
|
|
Shinya Kitaoka |
120a6e |
, a13(a.a13)
|
|
Shinya Kitaoka |
120a6e |
, a21(a.a21)
|
|
Shinya Kitaoka |
120a6e |
, a22(a.a22)
|
|
Shinya Kitaoka |
120a6e |
, a23(a.a23){};
|
|
|
f9b4ad |
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Assignment operator.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
TAffine &operator=(const TAffine &a);
|
|
Jeremy Bullock |
66c844 |
/*Moved to tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
a11 = a.a11; a12 = a.a12; a13 = a.a13;
|
|
Shinya Kitaoka |
120a6e |
a21 = a.a21; a22 = a.a22; a23 = a.a23;
|
|
Shinya Kitaoka |
120a6e |
return *this;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Matrix multiplication.
|
|
Shinya Kitaoka |
120a6e |
\f$\left(\begin{array}{cc}\bf{A}&\vec{a}\\\vec{0}&1\end{array}\right)
|
|
Shinya Kitaoka |
120a6e |
\left(\begin{array}{cc}\bf{B}&\vec{b}\\\vec{0}&1\end{array}\right)\f$
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
TAffine operator*(const TAffine &b) const;
|
|
Jeremy Bullock |
66c844 |
/*Moved to in tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
return TAffine (
|
|
Shinya Kitaoka |
120a6e |
a11 * b.a11 + a12 * b.a21,
|
|
Shinya Kitaoka |
120a6e |
a11 * b.a12 + a12 * b.a22,
|
|
Shinya Kitaoka |
120a6e |
a11 * b.a13 + a12 * b.a23 + a13,
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
a21 * b.a11 + a22 * b.a21,
|
|
Shinya Kitaoka |
120a6e |
a21 * b.a12 + a22 * b.a22,
|
|
Shinya Kitaoka |
120a6e |
a21 * b.a13 + a22 * b.a23 + a23);
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
TAffine operator*=(const TAffine &b);
|
|
Jeremy Bullock |
66c844 |
/*Moved to tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
return *this = *this * b;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
luz paz |
6454c4 |
Returns the inverse tansformation as:
|
|
Shinya Kitaoka |
120a6e |
\f$\left(\begin{array}{ccc}\bf{A}^{-1}&-\bf{A}^{-1}&\vec{b}\\\vec{0}&\vec{0}&1\end{array}\right)\f$
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TAffine inv() const;
|
|
Jeremy Bullock |
66c844 |
/*Moved to tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
if(a12 == 0.0 && a21 == 0.0)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
assert(a11 != 0.0);
|
|
Shinya Kitaoka |
120a6e |
assert(a22 != 0.0);
|
|
Shinya Kitaoka |
120a6e |
double inv_a11 = 1.0/a11;
|
|
Shinya Kitaoka |
120a6e |
double inv_a22 = 1.0/a22;
|
|
Shinya Kitaoka |
120a6e |
return TAffine(inv_a11,0, -a13 * inv_a11,
|
|
Shinya Kitaoka |
120a6e |
0,inv_a22, -a23 * inv_a22);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else if(a11 == 0.0 && a22 == 0.0)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
assert(a12 != 0.0);
|
|
Shinya Kitaoka |
120a6e |
assert(a21 != 0.0);
|
|
Shinya Kitaoka |
120a6e |
double inv_a21 = 1.0/a21;
|
|
Shinya Kitaoka |
120a6e |
double inv_a12 = 1.0/a12;
|
|
Shinya Kitaoka |
120a6e |
return TAffine(0, inv_a21, -a23 * inv_a21,
|
|
Shinya Kitaoka |
120a6e |
inv_a12, 0, -a13 * inv_a12);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
double d = 1./det();
|
|
Shinya Kitaoka |
120a6e |
return TAffine(a22*d,-a12*d, (a12*a23-a22*a13)*d,
|
|
Shinya Kitaoka |
120a6e |
-a21*d, a11*d, (a21*a13-a11*a23)*d);
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
double det() const;
|
|
Shinya Kitaoka |
120a6e |
/*Sposto in tgeometry.cpp{
|
|
Shinya Kitaoka |
120a6e |
return a11*a22-a12*a21;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Returns \e true if all elements are equals.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
bool operator==(const TAffine &a) const;
|
|
Shinya Kitaoka |
120a6e |
/*Sposto in tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
return a11==a.a11 && a12==a.a12 && a13==a.a13 &&
|
|
Shinya Kitaoka |
120a6e |
a21==a.a21 && a22==a.a22 && a23==a.a23;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Returns \e true if at least one element is different.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool operator!=(const TAffine &a) const;
|
|
Shinya Kitaoka |
120a6e |
/*Sposto in tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
return a11!=a.a11 || a12!=a.a12 || a13!=a.a13 ||
|
|
Shinya Kitaoka |
120a6e |
a21!=a.a21 || a22!=a.a22 || a23!=a.a23;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Returns \e true if the transformation is an identity,
|
|
Shinya Kitaoka |
120a6e |
i.e in the error limit \e err leaves the vectors unchanged.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool isIdentity(double err = 1.e-8) const;
|
|
Shinya Kitaoka |
120a6e |
/*Sposto in tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
return ((a11-1.0)*(a11-1.0)+(a22-1.0)*(a22-1.0)+
|
|
Shinya Kitaoka |
120a6e |
a12*a12+a13*a13+a21*a21+a23*a23) < err;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Returns \e true if in the error limits \e err \f$\bf{A}\f$ is the
|
|
Shinya Kitaoka |
120a6e |
identity matrix.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
9a49d4 |
bool isZero(double err = 1.e-8) const;
|
|
|
9a49d4 |
|
|
Shinya Kitaoka |
120a6e |
bool isTranslation(double err = 1.e-8) const;
|
|
Shinya Kitaoka |
120a6e |
/*Sposto in tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
return ((a11-1.0)*(a11-1.0)+(a22-1.0)*(a22-1.0)+
|
|
Shinya Kitaoka |
120a6e |
a12*a12+a21*a21) < err;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Returns \e true if in the error limits the matrix \f$\bf{A}\f$ is of
|
|
Shinya Kitaoka |
120a6e |
the form:
|
|
Shinya Kitaoka |
120a6e |
\f$\left(\begin{array}{cc}a&b\\-b&a\end{array}\right)\f$ .
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
bool isIsotropic(double err = 1.e-8) const;
|
|
Shinya Kitaoka |
120a6e |
/*Sposto in tgeometry.cpp
|
|
Toshihiro Shimizu |
890ddd |
{
|
|
Shinya Kitaoka |
120a6e |
return areAlmostEqual(a11, a22, err) && areAlmostEqual(a12, -a21, err);
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
luz paz |
6454c4 |
Returns the transformed point.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
TPointD operator*(const TPointD &p) const;
|
|
Shinya Kitaoka |
120a6e |
/*Sposto in tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
return TPointD(p.x*a11+p.y*a12+a13, p.x*a21+p.y*a22+a23);
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
|
f9b4ad |
Transform point without translation
|
|
|
f9b4ad |
*/
|
|
|
f9b4ad |
TPointD transformDirection(const TPointD &p) const;
|
|
|
f9b4ad |
|
|
|
f9b4ad |
/*!
|
|
|
f9b4ad |
Retruns the transformed box of the bounding box.
|
|
Toshihiro Shimizu |
890ddd |
*/
|
|
Shinya Kitaoka |
120a6e |
TRectD operator*(const TRectD &rect) const;
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
Returns a translated matrix that change the vector (u,v) in (x,y).
|
|
Shinya Kitaoka |
120a6e |
\n It returns a matrix of the form:
|
|
Shinya Kitaoka |
120a6e |
\f$\left(\begin{array}{ccc}\bf{A}&\vec{x}-\bf{A} \vec{u}\\
|
|
Shinya Kitaoka |
120a6e |
\vec{0}&1\end{array}\right)\f$
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
TAffine place(double u, double v, double x, double y) const;
|
|
Shinya Kitaoka |
120a6e |
|
|
Shinya Kitaoka |
120a6e |
/*!
|
|
Shinya Kitaoka |
120a6e |
See above.
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Shinya Kitaoka |
120a6e |
TAffine place(const TPointD &pIn, const TPointD &pOut) const;
|
|
|
9a49d4 |
|
|
|
9a49d4 |
inline static TAffine identity()
|
|
|
9a49d4 |
{ return TAffine(); }
|
|
|
9a49d4 |
inline static TAffine zero()
|
|
|
9a49d4 |
{ return TAffine(0, 0, 0, 0, 0, 0); }
|
|
|
9a49d4 |
|
|
|
9a49d4 |
inline static TAffine translation(double x, double y)
|
|
|
9a49d4 |
{ return TAffine(1, 0, x, 0, 1, y); }
|
|
|
9a49d4 |
inline static TAffine translation(const TPointD &p)
|
|
|
9a49d4 |
{ return translation(p.x, p.y); }
|
|
|
9a49d4 |
|
|
|
9a49d4 |
inline static TAffine scale(double sx, double sy)
|
|
|
9a49d4 |
{ return TAffine(sx, 0, 0, 0, sy, 0); }
|
|
|
9a49d4 |
inline static TAffine scale(double s)
|
|
|
9a49d4 |
{ return scale(s, s); }
|
|
|
9a49d4 |
inline static TAffine scale(const TPointD ¢er, double sx, double sy)
|
|
|
9a49d4 |
{ return translation(center)*scale(sx, sy)*translation(-center); }
|
|
|
9a49d4 |
inline static TAffine scale(const TPointD ¢er, double s)
|
|
|
9a49d4 |
{ return scale(center, s, s); }
|
|
|
9a49d4 |
|
|
|
9a49d4 |
static TAffine rotation(double angle);
|
|
|
9a49d4 |
inline static TAffine rotation(const TPointD ¢er, double angle)
|
|
|
9a49d4 |
{ return translation(center)*rotation(angle)*translation(-center); }
|
|
|
9a49d4 |
|
|
|
9a49d4 |
inline static TAffine shear(double sx, double sy)
|
|
|
9a49d4 |
{ return TAffine(1, sx, 0, sy, 1, 0); }
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// template <>
|
|
Shinya Kitaoka |
120a6e |
inline bool areAlmostEqual(const TPointD &a, const TPointD &b,
|
|
Shinya Kitaoka |
120a6e |
double err = TConsts::epsilon) {
|
|
Shinya Kitaoka |
120a6e |
return tdistance2(a, b) < err * err;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
// template <>
|
|
Shinya Kitaoka |
120a6e |
inline bool areAlmostEqual(const TRectD &a, const TRectD &b,
|
|
Shinya Kitaoka |
120a6e |
double err = TConsts::epsilon) {
|
|
Shinya Kitaoka |
120a6e |
return areAlmostEqual(a.getP00(), b.getP00(), err) &&
|
|
Shinya Kitaoka |
120a6e |
areAlmostEqual(a.getP11(), b.getP11(), err);
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
const TAffine AffI = TAffine();
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class DVAPI TTranslation final : public TAffine {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TTranslation(){};
|
|
Shinya Kitaoka |
120a6e |
TTranslation(double x, double y) : TAffine(1, 0, x, 0, 1, y){};
|
|
Shinya Kitaoka |
120a6e |
TTranslation(const TPointD &p) : TAffine(1, 0, p.x, 0, 1, p.y){};
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class DVAPI TRotation final : public TAffine {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TRotation(){};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*! makes a rotation matrix of "degrees" degrees counterclockwise
|
|
Shinya Kitaoka |
120a6e |
on the origin */
|
|
Shinya Kitaoka |
120a6e |
TRotation(double degrees);
|
|
Shinya Kitaoka |
120a6e |
/*Sposto in tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
double rad, sn, cs;
|
|
Shinya Kitaoka |
120a6e |
int idegrees = (int)degrees;
|
|
Shinya Kitaoka |
120a6e |
if ((double)idegrees == degrees && idegrees % 90 == 0)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
switch ((idegrees / 90) & 3)
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
case 0: sn = 0; cs = 1; break;
|
|
Shinya Kitaoka |
120a6e |
case 1: sn = 1; cs = 0; break;
|
|
Shinya Kitaoka |
120a6e |
case 2: sn = 0; cs = -1; break;
|
|
Shinya Kitaoka |
120a6e |
case 3: sn = -1; cs = 0; break;
|
|
Shinya Kitaoka |
120a6e |
default: sn = 0; cs = 0; break;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
else
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
rad = degrees * (TConsts::pi_180);
|
|
Shinya Kitaoka |
120a6e |
sn = sin (rad);
|
|
Shinya Kitaoka |
120a6e |
cs = cos (rad);
|
|
Shinya Kitaoka |
120a6e |
if (sn == 1 || sn == -1)
|
|
Shinya Kitaoka |
120a6e |
cs = 0;
|
|
Shinya Kitaoka |
120a6e |
if (cs == 1 || cs == -1)
|
|
Shinya Kitaoka |
120a6e |
sn = 0;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
a11=cs;a12= -sn;a21= -a12;a22=a11;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
/*! makes a rotation matrix of "degrees" degrees counterclockwise
|
|
Shinya Kitaoka |
120a6e |
on the given center */
|
|
Shinya Kitaoka |
120a6e |
TRotation(const TPointD ¢er, double degrees);
|
|
Shinya Kitaoka |
120a6e |
/*Sposto in tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TAffine a = TTranslation(center) * TRotation(degrees) * TTranslation(-center);
|
|
Shinya Kitaoka |
120a6e |
a11 = a.a11; a12 = a.a12; a13 = a.a13;
|
|
Shinya Kitaoka |
120a6e |
a21 = a.a21; a22 = a.a22; a23 = a.a23;
|
|
Shinya Kitaoka |
120a6e |
};
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class DVAPI TScale final : public TAffine {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TScale(){};
|
|
Shinya Kitaoka |
120a6e |
TScale(double sx, double sy) : TAffine(sx, 0, 0, 0, sy, 0){};
|
|
Shinya Kitaoka |
120a6e |
TScale(double s) : TAffine(s, 0, 0, 0, s, 0) {}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TScale(const TPointD ¢er, double sx, double sy);
|
|
Shinya Kitaoka |
120a6e |
/*Sposto in tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TAffine a = TTranslation(center) * TScale(sx,sy) * TTranslation(-center);
|
|
Shinya Kitaoka |
120a6e |
a11 = a.a11; a12 = a.a12; a13 = a.a13;
|
|
Shinya Kitaoka |
120a6e |
a21 = a.a21; a22 = a.a22; a23 = a.a23;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
TScale(const TPointD ¢er, double s);
|
|
Shinya Kitaoka |
120a6e |
/*Sposto in tgeometry.cpp
|
|
Shinya Kitaoka |
120a6e |
{
|
|
Shinya Kitaoka |
120a6e |
TAffine a = TTranslation(center) * TScale(s) * TTranslation(-center);
|
|
Shinya Kitaoka |
120a6e |
a11 = a.a11; a12 = a.a12; a13 = a.a13;
|
|
Shinya Kitaoka |
120a6e |
a21 = a.a21; a22 = a.a22; a23 = a.a23;
|
|
Shinya Kitaoka |
120a6e |
}
|
|
Shinya Kitaoka |
120a6e |
*/
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
d1f6c4 |
class DVAPI TShear final : public TAffine {
|
|
Toshihiro Shimizu |
890ddd |
public:
|
|
Shinya Kitaoka |
120a6e |
TShear(){};
|
|
Shinya Kitaoka |
120a6e |
TShear(double sx, double sy) : TAffine(1, sx, 0, sy, 1, 0){};
|
|
Toshihiro Shimizu |
890ddd |
};
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline bool areEquals(const TAffine &a, const TAffine &b, double err = 1e-8) {
|
|
Shinya Kitaoka |
120a6e |
return fabs(a.a11 - b.a11) < err && fabs(a.a12 - b.a12) < err &&
|
|
Shinya Kitaoka |
120a6e |
fabs(a.a13 - b.a13) < err && fabs(a.a21 - b.a21) < err &&
|
|
Shinya Kitaoka |
120a6e |
fabs(a.a22 - b.a22) < err && fabs(a.a23 - b.a23) < err;
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline TAffine inv(const TAffine &a) { return a.inv(); }
|
|
Toshihiro Shimizu |
890ddd |
|
|
Toshihiro Shimizu |
890ddd |
//-----------------------------------------------------------------------------
|
|
Toshihiro Shimizu |
890ddd |
|
|
Shinya Kitaoka |
120a6e |
inline std::ostream &operator<<(std::ostream &out, const TAffine &a) {
|
|
Shinya Kitaoka |
120a6e |
return out << "(" << a.a11 << ", " << a.a12 << ", " << a.a13 << ";" << a.a21
|
|
Shinya Kitaoka |
120a6e |
<< ", " << a.a22 << ", " << a.a23 << ")";
|
|
Toshihiro Shimizu |
890ddd |
}
|
|
Toshihiro Shimizu |
890ddd |
|
|
|
f9b4ad |
|
|
|
f9b4ad |
//=============================================================================
|
|
|
f9b4ad |
|
|
|
9f1fa3 |
//! This class performs basic manipulations of affine transformations in 2D space.
|
|
|
9f1fa3 |
//! with ability of perspective transform
|
|
|
9f1fa3 |
//! the matrix is transposed to TAffine and equal to OpenGL cells order
|
|
|
9f1fa3 |
|
|
|
9f1fa3 |
class DVAPI TAffine3 {
|
|
|
9f1fa3 |
public:
|
|
|
9f1fa3 |
union {
|
|
|
9f1fa3 |
struct {
|
|
|
9f1fa3 |
double a11, a12, a13;
|
|
|
9f1fa3 |
double a21, a22, a23;
|
|
|
9f1fa3 |
double a31, a32, a33;
|
|
|
9f1fa3 |
};
|
|
|
9f1fa3 |
double m[3][3];
|
|
|
9f1fa3 |
double a[9];
|
|
|
9f1fa3 |
};
|
|
|
9f1fa3 |
|
|
|
9f1fa3 |
inline TAffine3():
|
|
|
9f1fa3 |
a11(1.0), a12(0.0), a13(0.0),
|
|
|
9f1fa3 |
a21(0.0), a22(1.0), a23(0.0),
|
|
|
9f1fa3 |
a31(0.0), a32(0.0), a33(1.0) { }
|
|
|
9f1fa3 |
|
|
|
9f1fa3 |
inline explicit TAffine3(const TAffine &a):
|
|
|
9f1fa3 |
a11(a.a11), a12(a.a21), a13(0.0),
|
|
|
9f1fa3 |
a21(a.a12), a22(a.a22), a23(0.0),
|
|
|
9f1fa3 |
a31(a.a13), a32(a.a23), a33(1.0) { }
|
|
|
9f1fa3 |
|
|
|
9f1fa3 |
inline TAffine3(
|
|
|
52176e |
const T3DPointD &rowX,
|
|
|
52176e |
const T3DPointD &rowY,
|
|
|
52176e |
const T3DPointD &rowZ
|
|
|
9f1fa3 |
):
|
|
|
9f1fa3 |
a11(rowX.x), a12(rowX.y), a13(rowX.z),
|
|
|
9f1fa3 |
a21(rowY.x), a22(rowY.y), a23(rowY.z),
|
|
|
9f1fa3 |
a31(rowZ.x), a32(rowZ.y), a33(rowZ.z) { }
|
|
|
9f1fa3 |
|
|
|
52176e |
inline T3DPointD& row(int index)
|
|
|
52176e |
{ return *(T3DPointD*)(m[index]); }
|
|
|
52176e |
inline const T3DPointD& row(int index) const
|
|
|
52176e |
{ return *(const T3DPointD*)(m[index]); }
|
|
|
9f1fa3 |
|
|
|
52176e |
inline T3DPointD& rowX() { return row(0); }
|
|
|
52176e |
inline T3DPointD& rowY() { return row(1); }
|
|
|
52176e |
inline T3DPointD& rowZ() { return row(2); }
|
|
|
9f1fa3 |
|
|
|
52176e |
inline const T3DPointD& rowX() const { return row(0); }
|
|
|
52176e |
inline const T3DPointD& rowY() const { return row(1); }
|
|
|
52176e |
inline const T3DPointD& rowZ() const { return row(2); }
|
|
|
9f1fa3 |
|
|
|
52176e |
T3DPointD operator*(const T3DPointD &b) const;
|
|
|
9f1fa3 |
TAffine3 operator*(const TAffine3 &b) const;
|
|
|
9f1fa3 |
TAffine3 operator*=(const TAffine3 &b);
|
|
|
9f1fa3 |
|
|
|
9f1fa3 |
TAffine3 inv() const;
|
|
|
9f1fa3 |
|
|
|
9f1fa3 |
TAffine get2d() const;
|
|
|
9f1fa3 |
|
|
|
9f1fa3 |
inline static TAffine3 identity() { return TAffine3(); }
|
|
|
9f1fa3 |
static TAffine3 translation2d(double x, double y);
|
|
|
9f1fa3 |
static TAffine3 scale2d(double x, double y);
|
|
|
9f1fa3 |
static TAffine3 rotation2d(double angle);
|
|
|
9f1fa3 |
};
|
|
|
9f1fa3 |
|
|
|
9f1fa3 |
|
|
|
9f1fa3 |
//=============================================================================
|
|
|
9f1fa3 |
|
|
|
f9b4ad |
//! This class performs basic manipulations of affine transformations in 3D space.
|
|
|
f9b4ad |
//! the matrix is transposed to TAffine and equal to OpenGL
|
|
|
f9b4ad |
|
|
|
f9b4ad |
class DVAPI TAffine4 {
|
|
|
f9b4ad |
public:
|
|
|
f9b4ad |
union {
|
|
|
f9b4ad |
struct {
|
|
|
f9b4ad |
double a11, a12, a13, a14;
|
|
|
f9b4ad |
double a21, a22, a23, a24;
|
|
|
f9b4ad |
double a31, a32, a33, a34;
|
|
|
f9b4ad |
double a41, a42, a43, a44;
|
|
|
f9b4ad |
};
|
|
|
f9b4ad |
double m[4][4];
|
|
|
f9b4ad |
double a[16];
|
|
|
f9b4ad |
};
|
|
|
f9b4ad |
|
|
|
f9b4ad |
inline TAffine4():
|
|
|
f9b4ad |
a11(1.0), a12(0.0), a13(0.0), a14(0.0),
|
|
|
f9b4ad |
a21(0.0), a22(1.0), a23(0.0), a24(0.0),
|
|
|
f9b4ad |
a31(0.0), a32(0.0), a33(1.0), a34(0.0),
|
|
|
f9b4ad |
a41(0.0), a42(0.0), a43(0.0), a44(1.0) { }
|
|
|
f9b4ad |
|
|
|
f9b4ad |
inline explicit TAffine4(const TAffine &a):
|
|
|
f9b4ad |
a11(a.a11), a12(a.a21), a13(0.0), a14(0.0),
|
|
|
f9b4ad |
a21(a.a12), a22(a.a22), a23(0.0), a24(0.0),
|
|
|
f9b4ad |
a31( 0.0 ), a32( 0.0 ), a33(1.0), a34(0.0),
|
|
|
f9b4ad |
a41(a.a13), a42(a.a23), a43(0.0), a44(1.0) { }
|
|
|
f9b4ad |
|
|
|
f9b4ad |
inline TAffine4(
|
|
|
52176e |
const T4DPointD &rowX,
|
|
|
52176e |
const T4DPointD &rowY,
|
|
|
52176e |
const T4DPointD &rowZ,
|
|
|
52176e |
const T4DPointD &rowW
|
|
|
f9b4ad |
):
|
|
|
f9b4ad |
a11(rowX.x), a12(rowX.y), a13(rowX.z), a14(rowX.w),
|
|
|
f9b4ad |
a21(rowY.x), a22(rowY.y), a23(rowY.z), a24(rowY.w),
|
|
|
f9b4ad |
a31(rowZ.x), a32(rowZ.y), a33(rowZ.z), a34(rowZ.w),
|
|
|
f9b4ad |
a41(rowW.x), a42(rowW.y), a43(rowW.z), a44(rowW.w) { }
|
|
|
f9b4ad |
|
|
|
52176e |
inline T4DPointD& row(int index)
|
|
|
52176e |
{ return *(T4DPointD*)(m[index]); }
|
|
|
52176e |
inline const T4DPointD& row(int index) const
|
|
|
52176e |
{ return *(const T4DPointD*)(m[index]); }
|
|
|
f9b4ad |
|
|
|
52176e |
inline T4DPointD& rowX() { return row(0); }
|
|
|
52176e |
inline T4DPointD& rowY() { return row(1); }
|
|
|
52176e |
inline T4DPointD& rowZ() { return row(2); }
|
|
|
52176e |
inline T4DPointD& rowW() { return row(3); }
|
|
|
f9b4ad |
|
|
|
52176e |
inline const T4DPointD& rowX() const { return row(0); }
|
|
|
52176e |
inline const T4DPointD& rowY() const { return row(1); }
|
|
|
52176e |
inline const T4DPointD& rowZ() const { return row(2); }
|
|
|
52176e |
inline const T4DPointD& rowW() const { return row(3); }
|
|
|
f9b4ad |
|
|
|
52176e |
T4DPointD operator*(const T4DPointD &b) const;
|
|
|
f9b4ad |
TAffine4 operator*(const TAffine4 &b) const;
|
|
|
f9b4ad |
TAffine4 operator*=(const TAffine4 &b);
|
|
|
f9b4ad |
|
|
|
f9b4ad |
TAffine4 inv() const;
|
|
|
f9b4ad |
|
|
|
f9b4ad |
TAffine get2d(double z = 0.0) const;
|
|
|
9f1fa3 |
TAffine3 get2dPersp(double z = 0.0) const;
|
|
|
f9b4ad |
|
|
|
f9b4ad |
inline static TAffine4 identity() { return TAffine4(); }
|
|
|
f9b4ad |
static TAffine4 translation(double x, double y, double z);
|
|
|
f9b4ad |
static TAffine4 scale(double x, double y, double z);
|
|
|
f9b4ad |
static TAffine4 rotation(double x, double y, double z, double angle);
|
|
|
f9b4ad |
static TAffine4 rotationX(double angle);
|
|
|
f9b4ad |
static TAffine4 rotationY(double angle);
|
|
|
f9b4ad |
static TAffine4 rotationZ(double angle);
|
|
|
f9b4ad |
static TAffine4 perspective(double near, double far, double tangent);
|
|
|
f9b4ad |
};
|
|
|
f9b4ad |
|
|
|
58525d |
|
|
|
58525d |
//=============================================================================
|
|
|
58525d |
|
|
|
58525d |
//! This class performs binary manipulations with angle ranges
|
|
|
58525d |
|
|
|
9a49d4 |
typedef unsigned int TAngleI;
|
|
|
9a49d4 |
|
|
|
58525d |
class DVAPI TAngleRangeSet {
|
|
|
58525d |
public:
|
|
|
9a49d4 |
typedef TAngleI Type;
|
|
|
58525d |
typedef std::vector<type> List;</type>
|
|
|
58525d |
|
|
|
f36ea4 |
static const Type min = Type();
|
|
|
58525d |
static const Type max = Type() - Type(1);
|
|
|
58525d |
static const Type half = ((Type() - Type(1)) >> 1) + Type(1);
|
|
|
58525d |
|
|
|
58525d |
static Type fromDouble(double a)
|
|
|
58525d |
{ return Type(round((a/M_2PI + 0.5)*max)); }
|
|
|
58525d |
static double toDouble(Type a)
|
|
|
58525d |
{ return ((double)a/(double)max - 0.5)*M_2PI; }
|
|
|
5d8766 |
static List::const_iterator empty_iterator()
|
|
|
5d8766 |
{ static List list; return list.end(); }
|
|
|
5d8766 |
|
|
|
58525d |
struct Range {
|
|
|
58525d |
Type a0, a1;
|
|
|
58525d |
Range(): a0(), a1() { }
|
|
|
58525d |
Range(Type a0, Type a1): a0(a0), a1(a1) { }
|
|
|
58525d |
inline bool isEmpty() const { return a0 == a1; }
|
|
|
58525d |
inline Range flip() const { return Range(a1, a0); }
|
|
|
58525d |
};
|
|
|
58525d |
|
|
|
ac9bac |
struct Iterator {
|
|
|
ac9bac |
private:
|
|
|
ac9bac |
bool m_flip;
|
|
|
ac9bac |
List::const_iterator m_prebegin;
|
|
|
ac9bac |
List::const_iterator m_begin;
|
|
|
ac9bac |
List::const_iterator m_end;
|
|
|
ac9bac |
List::const_iterator m_current;
|
|
|
ac9bac |
bool m_lapped;
|
|
|
ac9bac |
|
|
|
ac9bac |
public:
|
|
|
ac9bac |
inline Iterator(): m_flip(), m_lapped(true)
|
|
|
ac9bac |
{ reset(); }
|
|
|
ac9bac |
inline explicit Iterator(const List &list, bool flip = false, bool reverse = false)
|
|
|
ac9bac |
{ set(list, flip, reverse); }
|
|
|
ac9bac |
inline explicit Iterator(const TAngleRangeSet &ranges, bool flip = false, bool reverse = false)
|
|
|
ac9bac |
{ set(ranges, flip, reverse); }
|
|
|
ac9bac |
|
|
|
ac9bac |
inline Iterator& set(bool full) {
|
|
|
ac9bac |
m_flip = full; m_lapped = !m_flip;
|
|
|
036a63 |
m_current = m_prebegin = m_begin = m_end = empty_iterator();
|
|
|
ac9bac |
return *this;
|
|
|
ac9bac |
}
|
|
|
ac9bac |
|
|
|
ac9bac |
inline Iterator& reset()
|
|
|
ac9bac |
{ return set(false); }
|
|
|
ac9bac |
|
|
|
ac9bac |
inline Iterator& set(const List &list, bool flip = false, bool reverse = false) {
|
|
|
ac9bac |
assert(list.size()%2 == 0);
|
|
|
ac9bac |
if (list.empty()) {
|
|
|
ac9bac |
set(flip);
|
|
|
ac9bac |
} else {
|
|
|
ac9bac |
m_flip = flip;
|
|
|
ac9bac |
m_lapped = false;
|
|
|
ac9bac |
if (flip) {
|
|
|
ac9bac |
m_prebegin = list.end() - 1;
|
|
|
ac9bac |
m_begin = list.begin();
|
|
|
ac9bac |
m_end = m_prebegin - 1;
|
|
|
ac9bac |
} else {
|
|
|
ac9bac |
m_prebegin = list.begin();
|
|
|
ac9bac |
m_begin = m_prebegin + 1;
|
|
|
ac9bac |
m_end = list.end() - 1;
|
|
|
ac9bac |
}
|
|
|
ac9bac |
}
|
|
|
ac9bac |
m_current = reverse ? m_end : m_begin;
|
|
|
ac9bac |
return *this;
|
|
|
ac9bac |
}
|
|
|
ac9bac |
|
|
|
ac9bac |
inline Iterator& set(const TAngleRangeSet &ranges, bool flip = false, bool reverse = false)
|
|
|
ac9bac |
{ return set(ranges.angles(), ranges.isFlipped() != flip, reverse); }
|
|
|
ac9bac |
|
|
|
f36ea4 |
inline const Type a0() const
|
|
|
f36ea4 |
{ return valid() ? *(m_current == m_begin ? m_prebegin : m_current - 1) : Type(); }
|
|
|
f36ea4 |
inline const Type a1() const
|
|
|
f36ea4 |
{ return valid() ? *m_current : Type(); }
|
|
|
ac9bac |
inline double d0() const
|
|
|
ac9bac |
{ return toDouble(a0()); }
|
|
|
ac9bac |
inline double d1() const
|
|
|
ac9bac |
{ return toDouble(a1()); }
|
|
|
ac9bac |
inline double d1greater() const {
|
|
|
ac9bac |
return !valid() ? (m_flip ? M_PI : -M_PI)
|
|
|
ac9bac |
: m_current == m_begin && m_prebegin > m_begin
|
|
|
ac9bac |
? toDouble(*m_current) + M_2PI : toDouble(*m_current);
|
|
|
ac9bac |
}
|
|
|
ac9bac |
inline Range range() const
|
|
|
ac9bac |
{ return Range(a0(), a1()); }
|
|
|
ac9bac |
inline int size() const
|
|
|
fa009d |
{ return (int)(m_end - m_begin)/2 + 1; }
|
|
|
ac9bac |
inline int index() const
|
|
|
fa009d |
{ return (int)(m_current - m_begin)/2; }
|
|
|
ac9bac |
inline int reverseIndex() const
|
|
|
ac9bac |
{ int i = index(); return i == 0 ? 0 : size() - i; }
|
|
|
ac9bac |
inline bool lapped() const
|
|
|
ac9bac |
{ return m_lapped; }
|
|
|
ac9bac |
inline bool valid() const
|
|
|
ac9bac |
{ return m_prebegin != m_begin; }
|
|
|
ac9bac |
inline bool isFull() const
|
|
|
ac9bac |
{ return !valid() && m_flip; }
|
|
|
ac9bac |
inline bool isEmpty() const
|
|
|
ac9bac |
{ return !valid() && !m_flip; }
|
|
|
ac9bac |
|
|
|
ac9bac |
inline operator bool() const
|
|
|
ac9bac |
{ return !m_lapped; }
|
|
|
ac9bac |
|
|
|
ac9bac |
inline Iterator& operator++() {
|
|
|
ac9bac |
if (!valid()) { m_lapped = true; return *this; }
|
|
|
ac9bac |
m_lapped = (m_current == m_end);
|
|
|
ac9bac |
if (m_lapped) m_current = m_begin; else m_current += 2;
|
|
|
ac9bac |
return *this;
|
|
|
ac9bac |
}
|
|
|
ac9bac |
|
|
|
ac9bac |
inline Iterator& operator--() {
|
|
|
ac9bac |
if (!valid()) { m_lapped = true; return *this; }
|
|
|
ac9bac |
m_lapped = (m_current == m_end);
|
|
|
ac9bac |
if (m_lapped) m_current = m_end; else m_current -= 2;
|
|
|
ac9bac |
return *this;
|
|
|
ac9bac |
}
|
|
|
ac9bac |
|
|
|
ac9bac |
inline Iterator& operator += (int i) {
|
|
|
ac9bac |
if (i == 0) { m_lapped = isEmpty(); return *this; }
|
|
|
ac9bac |
if (!valid()) { m_lapped = true; return *this; }
|
|
|
ac9bac |
int ii = index();
|
|
|
ac9bac |
int s = size();
|
|
|
ac9bac |
if (ii + i >= 0 && ii + i < s) {
|
|
|
ac9bac |
m_current += i*2;
|
|
|
ac9bac |
m_lapped = false;
|
|
|
ac9bac |
} else {
|
|
|
ac9bac |
m_current = m_begin + ((ii + s + i%s)%s)*2;
|
|
|
ac9bac |
m_lapped = true;
|
|
|
ac9bac |
}
|
|
|
ac9bac |
return *this;
|
|
|
ac9bac |
}
|
|
|
ac9bac |
|
|
|
ac9bac |
inline int operator-(const Iterator &i) const {
|
|
|
ac9bac |
assert(m_flip == i.m_flip && m_begin == i.m_begin && m_end == i.m_end && m_prebegin == i.m_prebegin);
|
|
|
f278a5 |
int ii = (int)(m_current - i.m_current);
|
|
|
ac9bac |
return ii < 0 ? ii + size() : ii;
|
|
|
ac9bac |
}
|
|
|
ac9bac |
|
|
|
ac9bac |
inline Iterator operator++() const
|
|
|
ac9bac |
{ Iterator copy(*this); ++(*this); return copy; }
|
|
|
ac9bac |
inline Iterator operator--() const
|
|
|
ac9bac |
{ Iterator copy(*this); --(*this); return copy; }
|
|
|
ac9bac |
inline Iterator& operator -= (int i)
|
|
|
ac9bac |
{ return (*this) += -i; }
|
|
|
ac9bac |
inline Iterator operator+(int i) const
|
|
|
ac9bac |
{ Iterator ii(*this); return ii += i; }
|
|
|
ac9bac |
inline Iterator operator-(int i) const
|
|
|
ac9bac |
{ Iterator ii(*this); return ii -= i; }
|
|
|
ac9bac |
};
|
|
|
ac9bac |
|
|
|
58525d |
private:
|
|
|
58525d |
bool m_flip;
|
|
|
58525d |
List m_angles;
|
|
|
58525d |
|
|
|
58525d |
int find(Type a) const;
|
|
|
58525d |
void insert(Type a);
|
|
|
812e8c |
void doAdd(Type a0, Type a1);
|
|
|
58525d |
|
|
|
58525d |
public:
|
|
|
58525d |
inline explicit TAngleRangeSet(bool fill = false): m_flip(fill) { }
|
|
|
58525d |
inline TAngleRangeSet(const TAngleRangeSet &x, bool flip = false):
|
|
|
58525d |
m_flip(x.isFlipped() != flip), m_angles(x.angles()) { }
|
|
|
58525d |
|
|
|
58525d |
inline const List& angles() const { return m_angles; }
|
|
|
58525d |
inline bool isFlipped() const { return m_flip; }
|
|
|
58525d |
inline bool isEmpty() const { return !m_flip && m_angles.empty(); }
|
|
|
58525d |
inline bool isFull() const { return m_flip && m_angles.empty(); }
|
|
|
58525d |
|
|
|
58525d |
bool contains(Type a) const;
|
|
|
58525d |
bool check() const;
|
|
|
58525d |
|
|
|
58525d |
inline void clear() { m_flip = false; m_angles.clear(); }
|
|
|
58525d |
inline void fill() { m_flip = true; m_angles.clear(); }
|
|
|
58525d |
inline void invert() { m_flip = !m_flip; }
|
|
|
58525d |
|
|
|
58525d |
void set(Type a0, Type a1);
|
|
|
58525d |
void set(const TAngleRangeSet &x, bool flip = false);
|
|
|
58525d |
|
|
|
58525d |
//! also known as 'xor'
|
|
|
58525d |
void invert(Type a0, Type a1);
|
|
|
58525d |
inline void invert(const Range &x) { invert(x.a0, x.a1); }
|
|
|
58525d |
void invert(const TAngleRangeSet &x);
|
|
|
58525d |
|
|
|
58525d |
void add(Type a0, Type a1);
|
|
|
58525d |
inline void add(const Range &x) { add(x.a0, x.a1); }
|
|
|
58525d |
void add(const TAngleRangeSet &x);
|
|
|
58525d |
|
|
|
58525d |
void subtract(Type a0, Type a1);
|
|
|
58525d |
inline void subtract(const Range &x) { subtract(x.a0, x.a1); }
|
|
|
58525d |
void subtract(const TAngleRangeSet &x);
|
|
|
58525d |
|
|
|
58525d |
void intersect(Type a0, Type a1);
|
|
|
58525d |
inline void intersect(const Range &x) { intersect(x.a0, x.a1); }
|
|
|
58525d |
void intersect(const TAngleRangeSet &x);
|
|
|
58525d |
};
|
|
|
58525d |
|
|
|
58525d |
|
|
Shinya Kitaoka |
120a6e |
#endif // __T_GEOMETRY_INCLUDED__
|