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>
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
//=============================================================================
Ivan Mahonin 911124
Ivan Mahonin 911124
inline double logNormalDistribuitionUnscaled(double x, double x0, double w)
Ivan Mahonin 911124
  { return exp(-0.5*pow(log(x/x0)/w, 2.0))/x; }
Ivan Mahonin 911124
Ivan Mahonin 911124
inline double logNormalDistribuition(double x, double x0, double w)
Ivan Mahonin 911124
  { return logNormalDistribuitionUnscaled(x, x0, w)/(w*sqrt(2.0*M_PI)); }
Ivan Mahonin 911124
Ivan Mahonin 911124
//=============================================================================
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
template <class T> class TPoint4T;
Ivan Mahonin 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>
Shinya Kitaoka 120a6e
class TPointT {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  T x, y;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointT() : x(0), y(0){};
Shinya Kitaoka 120a6e
  TPointT(T _x, T _y) : x(_x), y(_y){};
Shinya Kitaoka 120a6e
  TPointT(const TPointT &point) : x(point.x), y(point.y){};
Ivan Mahonin f9b4ad
  explicit TPointT(const TPoint4T<T> &point);
Ivan Mahonin f9b4ad
Shinya Kitaoka 120a6e
  inline TPointT &operator=(const TPointT &a) {
Shinya Kitaoka 120a6e
    x = a.x;
Shinya Kitaoka 120a6e
    y = a.y;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inline TPointT &operator+=(const TPointT &a) {
Shinya Kitaoka 120a6e
    x += a.x;
Shinya Kitaoka 120a6e
    y += a.y;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
  inline TPointT &operator-=(const TPointT &a) {
Shinya Kitaoka 120a6e
    x -= a.x;
Shinya Kitaoka 120a6e
    y -= a.y;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
  inline TPointT operator+(const TPointT &a) const {
Shinya Kitaoka 120a6e
    return TPointT(x + a.x, y + a.y);
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
  inline TPointT operator-(const TPointT &a) const {
Shinya Kitaoka 120a6e
    return TPointT(x - a.x, y - a.y);
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
  inline TPointT operator-() const { return TPointT(-x, -y); };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator!=(const TPointT &p) const { return x != p.x || y != p.y; }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Ivan Mahonin f9b4ad
template <class T>
Ivan Mahonin f9b4ad
class TPoint4T {
Ivan Mahonin f9b4ad
public:
Ivan Mahonin f9b4ad
  union {
Ivan Mahonin f9b4ad
    struct { T x, y, z, w; };
Ivan Mahonin f9b4ad
    T a[4];
Ivan Mahonin f9b4ad
  };
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  TPoint4T():
Ivan Mahonin f9b4ad
    x(), y(), z(), w() { };
Ivan Mahonin f9b4ad
  TPoint4T(T x, T y, T z, T w):
Ivan Mahonin f9b4ad
    x(x), y(y), z(z), w(w) { };
Ivan Mahonin f9b4ad
  explicit TPoint4T(const TPointT<T> &p, T w = (T)1):
Ivan Mahonin f9b4ad
      x(p.x), y(p.y), z(), w(w) { };
Ivan Mahonin f9b4ad
};
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
template <class T>
Ivan Mahonin f9b4ad
inline TPointT<T>::TPointT(const TPoint4T<T> &point) : x(point.x), y(point.y){};
Ivan Mahonin f9b4ad
Shinya Kitaoka 120a6e
/*! \relates TPointT
Toshihiro Shimizu 890ddd
* Rotate a point 90 degrees (counterclockwise).
Shinya Kitaoka 120a6e
\param p a point.
Toshihiro Shimizu 890ddd
\return the rotated point
Toshihiro Shimizu 890ddd
\sa rotate270
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <class T>
Jeremy Bullock 66c844
inline TPointT<T> rotate90(const TPointT<T> &p)  // 90 counterclockwise
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  return TPointT<T>(-p.y, p.x);
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
/*! \relates TPointT
Toshihiro Shimizu 890ddd
* Rotate a point 270 degrees (clockwise).
Shinya Kitaoka 120a6e
\param p a point.
Toshihiro Shimizu 890ddd
\return the rotated point
Toshihiro Shimizu 890ddd
\sa rotate90
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <class T>
Jeremy Bullock 66c844
inline TPointT<T> rotate270(const TPointT<T> &p)  // 90 clockwise
Toshihiro Shimizu 890ddd
{
Shinya Kitaoka 120a6e
  return TPointT<T>(p.y, -p.x);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
\relates TPointT
Toshihiro Shimizu 890ddd
*/
Jeremy Bullock 66c844
template <class T>  // Scalar(dot) Product
Shinya Kitaoka 120a6e
inline T operator*(const TPointT<T> &a, const TPointT<T> &b) {
Shinya Kitaoka 120a6e
  return a.x * b.x + a.y * b.y;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class T>
Shinya Kitaoka 120a6e
inline std::ostream &operator<<(std::ostream &out, const TPointT<T> &p) {
Shinya Kitaoka 120a6e
  return out << "(" << p.x << ", " << p.y << ")";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef TPointT<int> TPoint, TPointI;
Toshihiro Shimizu 890ddd
typedef TPointT<double> TPointD;
Ivan Mahonin f9b4ad
typedef TPoint4T<double> TPoint4D;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DVAPI TPointT<int>;
Toshihiro Shimizu 890ddd
template class DVAPI TPointT<double>;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class T>
Shinya Kitaoka 120a6e
inline bool operator==(const TPointT<T> &p0, const TPointT<T> &p1) {
Shinya Kitaoka 120a6e
  return p0.x == p1.x && p0.y == p1.y;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!\relates TPointT
Shinya Kitaoka 120a6e
inline TPoint operator*(int a, const TPoint &p) {
Shinya Kitaoka 120a6e
  return TPoint(a * p.x, a * p.y);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!\relates TPointT
Shinya Kitaoka 120a6e
inline TPoint operator*(const TPoint &p, int a) {
Shinya Kitaoka 120a6e
  return TPoint(a * p.x, a * p.y);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!\relates TPointT
Shinya Kitaoka 120a6e
inline TPointD operator*(double a, const TPointD &p) {
Shinya Kitaoka 120a6e
  return TPointD(a * p.x, a * p.y);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!\relates TPointT
Shinya Kitaoka 120a6e
inline TPointD operator*(const TPointD &p, double a) {
Shinya Kitaoka 120a6e
  return TPointD(a * p.x, a * p.y);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
\relates TPointT
Shinya Kitaoka 120a6e
This helper function returns the square of the absolute value of the specified
Shinya Kitaoka 120a6e
point (a TPointI)
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
inline int norm2(const TPointI &p) { return p.x * p.x + p.y * p.y; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
\relates TPointT
Shinya Kitaoka 120a6e
This helper function returns the square of the absolute value of the specified
Shinya Kitaoka 120a6e
point (a TPointD)
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
inline double norm2(const TPointD &p) { return p.x * p.x + p.y * p.y; }
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);
Shinya Kitaoka 120a6e
  assert(n != 0.0);
Shinya Kitaoka 120a6e
  return (1.0 / n) * p;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
\relates TPointT
Toshihiro Shimizu 890ddd
This helper function converts a TPoint (TPointT<int>) into a TPointD
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
inline TPointD convert(const TPoint &p) { return TPointD(p.x, p.y); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
\relates TPointT
Toshihiro Shimizu 890ddd
This helper function converts a TPointD (TPointT<double>) into a TPoint
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
inline TPoint convert(const TPointD &p) {
Shinya Kitaoka 120a6e
  return TPoint(tround(p.x), tround(p.y));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
\relates TPointT
Shinya Kitaoka 120a6e
This helper function returns the square of the distance between two points
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
inline double tdistance2(const TPointD &p1, const TPointD &p2) {
Shinya Kitaoka 120a6e
  return norm2(p2 - p1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline bool operator==(const TPointD &p0, const TPointD &p1) {
Shinya Kitaoka 120a6e
  return tdistance2(p0, p1) < TConsts::epsilon * TConsts::epsilon;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
\relates TPointT
Shinya Kitaoka 120a6e
This helper function returns the distance between two points
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
inline double tdistance(const TPointD &p1, const TPointD &p2) {
Shinya Kitaoka 120a6e
  return norm(p2 - p1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
the cross product
Toshihiro Shimizu 890ddd
\relates TPointT
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
inline double cross(const TPointD &a, const TPointD &b) {
Shinya Kitaoka 120a6e
  return a.x * b.y - a.y * b.x;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
the cross product
Toshihiro Shimizu 890ddd
\relates TPoint
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
inline int cross(const TPoint &a, const TPoint &b) {
Shinya Kitaoka 120a6e
  return a.x * b.y - a.y * b.x;
Toshihiro Shimizu 890ddd
}
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>
Shinya Kitaoka 120a6e
class DVAPI T3DPointT {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  T x, y, z;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  T3DPointT() : x(0), y(0), z(0) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  T3DPointT(T _x, T _y, T _z) : x(_x), y(_y), z(_z) {}
Shinya Kitaoka 120a6e
  T3DPointT(const TPointT<T> &_p, T _z) : x(_p.x), y(_p.y), z(_z) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  T3DPointT(const T3DPointT &_p) : x(_p.x), y(_p.y), z(_p.z) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inline T3DPointT &operator=(const T3DPointT &a) {
Shinya Kitaoka 120a6e
    x = a.x;
Shinya Kitaoka 120a6e
    y = a.y;
Shinya Kitaoka 120a6e
    z = a.z;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inline T3DPointT &operator+=(const T3DPointT &a) {
Shinya Kitaoka 120a6e
    x += a.x;
Shinya Kitaoka 120a6e
    y += a.y;
Shinya Kitaoka 120a6e
    z += a.z;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inline T3DPointT &operator-=(const T3DPointT &a) {
Shinya Kitaoka 120a6e
    x -= a.x;
Shinya Kitaoka 120a6e
    y -= a.y;
Shinya Kitaoka 120a6e
    z -= a.z;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inline T3DPointT operator+(const T3DPointT &a) const {
Shinya Kitaoka 120a6e
    return T3DPointT(x + a.x, y + a.y, z + a.z);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inline T3DPointT operator-(const T3DPointT &a) const {
Shinya Kitaoka 120a6e
    return T3DPointT(x - a.x, y - a.y, z - a.z);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inline T3DPointT operator-() const { return T3DPointT(-x, -y, -z); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator==(const T3DPointT &p) const {
Shinya Kitaoka 120a6e
    return x == p.x && y == p.y && z == p.z;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator!=(const T3DPointT &p) const {
Shinya Kitaoka 120a6e
    return x != p.x || y != p.y || z != p.z;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class T>
Shinya Kitaoka 120a6e
inline std::ostream &operator<<(std::ostream &out, const T3DPointT<T> &p) {
Shinya Kitaoka 120a6e
  return out << "(" << p.x << ", " << p.y << ", " << p.z << ")";
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef T3DPointT<int> T3DPoint, T3DPointI;
Toshihiro Shimizu 890ddd
typedef T3DPointT<double> T3DPointD;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DVAPI T3DPointT<int>;
Toshihiro Shimizu 890ddd
template class DVAPI T3DPointT<double>;
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!\relates T3DPointT
Toshihiro Shimizu 890ddd
template <class T>
Shinya Kitaoka 120a6e
inline T3DPointT<T> operator*(T a, const T3DPointT<T> &p) {
Shinya Kitaoka 120a6e
  return T3DPointT<T>(a * p.x, a * p.y, a * p.z);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!\relates TPointT
Toshihiro Shimizu 890ddd
template <class T>
Shinya Kitaoka 120a6e
inline T3DPointT<T> operator*(const T3DPointT<T> &p, T a) {
Shinya Kitaoka 120a6e
  return T3DPointT<T>(a * p.x, a * p.y, a * p.z);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
\relates TPointT
Shinya Kitaoka 120a6e
This helper function returns the square of the absolute value of the specified
Shinya Kitaoka 120a6e
point (a TPointI)
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <class T>
Shinya Kitaoka 120a6e
inline T norm2(const T3DPointT<T> &p) {
Shinya Kitaoka 120a6e
  return p.x * p.x + p.y * p.y + p.z * p.z;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
template <class T>
Shinya Kitaoka 120a6e
inline T norm(const T3DPointT<T> &p) {
Shinya Kitaoka 120a6e
  return std::sqrt(norm2(p));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
inline T3DPointD normalize(const T3DPointD &p) {
Shinya Kitaoka 120a6e
  double n = norm(p);
Shinya Kitaoka 120a6e
  assert(n != 0.0);
Shinya Kitaoka 120a6e
  return (1.0 / n) * p;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
inline T3DPointD convert(const T3DPoint &p) { return T3DPointD(p.x, p.y, p.z); }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
*/
Shinya Kitaoka 120a6e
inline T3DPoint convert(const T3DPointD &p) {
Shinya Kitaoka 120a6e
  return T3DPoint(tround(p.x), tround(p.y), tround(p.z));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!
Toshihiro Shimizu 890ddd
template <class T>
Shinya Kitaoka 120a6e
inline T tdistance(const T3DPointT<T> &p1, const T3DPointT<T> &p2) {
Shinya Kitaoka 120a6e
  return norm<T>(p2 - p1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!
Toshihiro Shimizu 890ddd
template <class T>
Shinya Kitaoka 120a6e
inline T tdistance2(const T3DPointT<T> &p1, const T3DPointT<T> &p2) {
Shinya Kitaoka 120a6e
  return norm2<T>(p2 - p1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!
Toshihiro Shimizu 890ddd
template <class T>
Shinya Kitaoka 120a6e
inline T3DPointT<T> cross(const T3DPointT<T> &a, const T3DPointT<T> &b) {
Shinya Kitaoka 120a6e
  return T3DPointT<T>(a.y * b.z - b.y * a.z, a.z * b.x - b.z * a.x,
Shinya Kitaoka 120a6e
                      a.x * b.y - b.x * a.y);
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>
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;
Toshihiro Shimizu 890ddd
typedef TDimensionT<double> TDimensionD;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <class T>
Shinya Kitaoka 120a6e
inline std::ostream &operator<<(std::ostream &out, const TDimensionT<T> &p) {
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>;
Toshihiro Shimizu 890ddd
template class DVAPI TDimensionT<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>
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
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);
Jeremy Bullock 66c844
Shinya Kitaoka 120a6e
  TRectT(const TDimensionT<T> &d);
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()); };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TPointT<T> getP00() const { return TPointT<T>(x0, y0); };
Shinya Kitaoka 120a6e
  TPointT<T> getP10() const { return TPointT<T>(x1, y0); };
Shinya Kitaoka 120a6e
  TPointT<T> getP01() const { return TPointT<T>(x0, y1); };
Shinya Kitaoka 120a6e
  TPointT<T> getP11() const { return TPointT<T>(x1, y1); };
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
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), 
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
Shinya Kitaoka 120a6e
    return *this = *this + rect;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
  TRectT<T> &operator*=(const TRectT<T> &rect) {  // intersezione
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
Shinya Kitaoka 120a6e
    if (isEmpty() || rect.isEmpty())
Shinya Kitaoka 120a6e
      return TRectT<T>();
Shinya Kitaoka 120a6e
    else if (rect.x1 < x0 || x1 < rect.x0 || rect.y1 < y0 || y1 < rect.y0)
Shinya Kitaoka 120a6e
      return TRectT<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),
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
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) {
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 {
Shinya Kitaoka 120a6e
    TRectT<T> ris(*this);
Shinya Kitaoka 120a6e
    return ris += p;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
  TRectT<T> operator-(const TPointT<T> &p) const {
Shinya Kitaoka 120a6e
    TRectT<T> ris(*this);
Shinya Kitaoka 120a6e
    return ris -= p;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator==(const TRectT<T> &r) const {
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 {
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 {
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 {
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 {
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 {
Shinya Kitaoka 120a6e
    if (isEmpty()) return *this;
Shinya Kitaoka 120a6e
    return TRectT<T>(x0 - dx, y0 - dy, x1 + dx, y1 + dy);
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TRectT<T> enlarge(T d) const { return enlarge(d, d); };
Shinya Kitaoka 120a6e
  TRectT<T> enlarge(TDimensionT<T> d) const { return enlarge(d.lx, d.ly); };
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
typedef TRectT<int> TRect, TRectI;
Toshihiro Shimizu 890ddd
typedef TRectT<double> TRectD;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 9f5a1b
#ifdef _WIN32
Toshihiro Shimizu 890ddd
template class DVAPI TRectT<int>;
Toshihiro Shimizu 890ddd
template class DVAPI TRectT<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) {}
Toshihiro Shimizu 890ddd
template <>
Shinya Kitaoka 120a6e
inline TRectT<int>::TRectT(const TPointT<int> &bottomLeft,
Shinya Kitaoka 120a6e
                           const TDimensionT<int> &d)
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)
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 {
Shinya Kitaoka 120a6e
  return x0 > x1 || y0 > y1;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
template <>
Shinya Kitaoka 120a6e
inline void TRectT<int>::empty() {
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 {
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 {
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) {}
Toshihiro Shimizu 890ddd
template <>
Shinya Kitaoka 120a6e
inline TRectT<double>::TRectT(const TPointT<double> &bottomLeft,
Shinya Kitaoka 120a6e
                              const TDimensionT<double> &d)
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)
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 {
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() {
Shinya Kitaoka 120a6e
  x0 = y0 = x1 = y1 = 0;
Shinya Kitaoka 120a6e
}
Toshihiro Shimizu 890ddd
template <>
Shinya Kitaoka 120a6e
inline double TRectT<double>::getLx() const {
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 {
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>
Shinya Kitaoka 120a6e
inline std::ostream &operator<<(std::ostream &out, const TRectT<T> &r) {
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){};
Ivan Mahonin 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
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
  /*!
Ivan Mahonin f9b4ad
          Transform point without translation
Ivan Mahonin f9b4ad
  */
Ivan Mahonin f9b4ad
  TPointD transformDirection(const TPointD &p) const;
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  /*!
Ivan Mahonin 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;
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 &center, 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 &center, 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 &center, 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
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
//=============================================================================
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
//! This class performs basic manipulations of affine transformations in 3D space.
Ivan Mahonin f9b4ad
//! the matrix is transposed to TAffine and equal to OpenGL
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
class DVAPI TAffine4 {
Ivan Mahonin f9b4ad
public:
Ivan Mahonin f9b4ad
  union {
Ivan Mahonin f9b4ad
    struct {
Ivan Mahonin f9b4ad
      double a11, a12, a13, a14;
Ivan Mahonin f9b4ad
      double a21, a22, a23, a24;
Ivan Mahonin f9b4ad
      double a31, a32, a33, a34;
Ivan Mahonin f9b4ad
      double a41, a42, a43, a44;
Ivan Mahonin f9b4ad
    };
Ivan Mahonin f9b4ad
    double m[4][4];
Ivan Mahonin f9b4ad
    double a[16];
Ivan Mahonin f9b4ad
  };
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  inline TAffine4():
Ivan Mahonin f9b4ad
    a11(1.0), a12(0.0), a13(0.0), a14(0.0),
Ivan Mahonin f9b4ad
    a21(0.0), a22(1.0), a23(0.0), a24(0.0),
Ivan Mahonin f9b4ad
    a31(0.0), a32(0.0), a33(1.0), a34(0.0),
Ivan Mahonin f9b4ad
    a41(0.0), a42(0.0), a43(0.0), a44(1.0) { }
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  inline explicit TAffine4(const TAffine &a):
Ivan Mahonin f9b4ad
    a11(a.a11), a12(a.a21), a13(0.0), a14(0.0),
Ivan Mahonin f9b4ad
    a21(a.a12), a22(a.a22), a23(0.0), a24(0.0),
Ivan Mahonin f9b4ad
    a31( 0.0 ), a32( 0.0 ), a33(1.0), a34(0.0),
Ivan Mahonin f9b4ad
    a41(a.a13), a42(a.a23), a43(0.0), a44(1.0) { }
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  inline TAffine4(
Ivan Mahonin f9b4ad
    const TPoint4D &rowX,
Ivan Mahonin f9b4ad
    const TPoint4D &rowY,
Ivan Mahonin f9b4ad
    const TPoint4D &rowZ,
Ivan Mahonin f9b4ad
    const TPoint4D &rowW
Ivan Mahonin f9b4ad
  ):
Ivan Mahonin f9b4ad
    a11(rowX.x), a12(rowX.y), a13(rowX.z), a14(rowX.w),
Ivan Mahonin f9b4ad
    a21(rowY.x), a22(rowY.y), a23(rowY.z), a24(rowY.w),
Ivan Mahonin f9b4ad
    a31(rowZ.x), a32(rowZ.y), a33(rowZ.z), a34(rowZ.w),
Ivan Mahonin f9b4ad
    a41(rowW.x), a42(rowW.y), a43(rowW.z), a44(rowW.w) { }
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  inline TPoint4D& row(int index)
Ivan Mahonin f9b4ad
    { return *(TPoint4D*)(m[index]); }
Ivan Mahonin f9b4ad
  inline const TPoint4D& row(int index) const
Ivan Mahonin f9b4ad
    { return *(const TPoint4D*)(m[index]); }
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  inline TPoint4D& rowX() { return row(0); }
Ivan Mahonin f9b4ad
  inline TPoint4D& rowY() { return row(1); }
Ivan Mahonin f9b4ad
  inline TPoint4D& rowZ() { return row(2); }
Ivan Mahonin f9b4ad
  inline TPoint4D& rowW() { return row(3); }
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  inline const TPoint4D& rowX() const { return row(0); }
Ivan Mahonin f9b4ad
  inline const TPoint4D& rowY() const { return row(1); }
Ivan Mahonin f9b4ad
  inline const TPoint4D& rowZ() const { return row(2); }
Ivan Mahonin f9b4ad
  inline const TPoint4D& rowW() const { return row(3); }
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  TPoint4D operator*(const TPoint4D &b) const;
Ivan Mahonin f9b4ad
  TAffine4 operator*(const TAffine4 &b) const;
Ivan Mahonin f9b4ad
  TAffine4 operator*=(const TAffine4 &b);
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  TAffine4 inv() const;
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  TAffine get2d(double z = 0.0) const;
Ivan Mahonin f9b4ad
Ivan Mahonin f9b4ad
  inline static TAffine4 identity() { return TAffine4(); }
Ivan Mahonin f9b4ad
  static TAffine4 translation(double x, double y, double z);
Ivan Mahonin f9b4ad
  static TAffine4 scale(double x, double y, double z);
Ivan Mahonin f9b4ad
  static TAffine4 rotation(double x, double y, double z, double angle);
Ivan Mahonin f9b4ad
  static TAffine4 rotationX(double angle);
Ivan Mahonin f9b4ad
  static TAffine4 rotationY(double angle);
Ivan Mahonin f9b4ad
  static TAffine4 rotationZ(double angle);
Ivan Mahonin f9b4ad
  static TAffine4 perspective(double near, double far, double tangent);
Ivan Mahonin f9b4ad
};
Ivan Mahonin f9b4ad
Shinya Kitaoka 120a6e
#endif  //  __T_GEOMETRY_INCLUDED__