Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tgeometry.h"
Toshihiro Shimizu 890ddd
#ifdef LINUX
Toshihiro Shimizu 890ddd
#include <values.h></values.h>
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
using namespace std;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const T3DPointD TConsts::nap3d((numeric_limits<double>::max)(),</double>
Shinya Kitaoka 120a6e
                               (numeric_limits<double>::max)(),</double>
Shinya Kitaoka 120a6e
                               (numeric_limits<double>::max)());</double>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TThickPoint TConsts::natp((numeric_limits<double>::max)(),</double>
Shinya Kitaoka 120a6e
                                (numeric_limits<double>::max)(),</double>
Shinya Kitaoka 120a6e
                                (numeric_limits<double>::max)());</double>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TPointD TConsts::napd((numeric_limits<double>::max)(),</double>
Shinya Kitaoka 120a6e
                            (numeric_limits<double>::max)());</double>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TPointI TConsts::nap((numeric_limits<int>::max)(),</int>
Shinya Kitaoka 120a6e
                           (numeric_limits<int>::max)());</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TRectD TConsts::infiniteRectD(-(numeric_limits<double>::max)(),</double>
Shinya Kitaoka 120a6e
                                    -(numeric_limits<double>::max)(),</double>
Shinya Kitaoka 120a6e
                                    (numeric_limits<double>::max)(),</double>
Shinya Kitaoka 120a6e
                                    (numeric_limits<double>::max)());</double>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
const TRectI TConsts::infiniteRectI(-(numeric_limits<int>::max)(),</int>
Shinya Kitaoka 120a6e
                                    -(numeric_limits<int>::max)(),</int>
Shinya Kitaoka 120a6e
                                    (numeric_limits<int>::max)(),</int>
Shinya Kitaoka 120a6e
                                    (numeric_limits<int>::max)());</int>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// operazioni fra affini
Shinya Kitaoka 120a6e
TAffine &TAffine::operator=(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;
Shinya Kitaoka 120a6e
  return *this;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
TAffine TAffine::operator*(const TAffine &b) const {
Shinya Kitaoka 120a6e
  return TAffine(a11 * b.a11 + a12 * b.a21, a11 * b.a12 + a12 * b.a22,
Shinya Kitaoka 120a6e
                 a11 * b.a13 + a12 * b.a23 + a13,
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
                 a21 * b.a11 + a22 * b.a21, a21 * b.a12 + a22 * b.a22,
Shinya Kitaoka 120a6e
                 a21 * b.a13 + a22 * b.a23 + a23);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
TAffine TAffine::operator*=(const TAffine &b) { return *this = *this * b; }
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
TAffine TAffine::inv() const {
Shinya Kitaoka 120a6e
  if (a12 == 0.0 && a21 == 0.0) {
manongjohn 54e85d
    double inv_a11 =
manongjohn 54e85d
        (a11 == 0.0 ? std::numeric_limits<double>::max() / (1 << 16)</double>
manongjohn 54e85d
                    : 1.0 / a11);
manongjohn 54e85d
    double inv_a22 =
manongjohn 54e85d
        (a22 == 0.0 ? std::numeric_limits<double>::max() / (1 << 16)</double>
manongjohn 54e85d
                    : 1.0 / a22);
Shinya Kitaoka 120a6e
    return TAffine(inv_a11, 0, -a13 * inv_a11, 0, inv_a22, -a23 * inv_a22);
Shinya Kitaoka 120a6e
  } else if (a11 == 0.0 && a22 == 0.0) {
Shinya Kitaoka 120a6e
    assert(a12 != 0.0);
Shinya Kitaoka 120a6e
    assert(a21 != 0.0);
manongjohn 54e85d
    double inv_a21 =
manongjohn 54e85d
        (a21 == 0.0 ? std::numeric_limits<double>::max() / (1 << 16)</double>
manongjohn 54e85d
                    : 1.0 / a21);
manongjohn 54e85d
    double inv_a12 =
manongjohn 54e85d
        (a12 == 0.0 ? std::numeric_limits<double>::max() / (1 << 16)</double>
manongjohn 54e85d
                    : 1.0 / a12);
Shinya Kitaoka 120a6e
    return TAffine(0, inv_a21, -a23 * inv_a21, inv_a12, 0, -a13 * inv_a12);
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    double d = 1. / det();
Shinya Kitaoka 120a6e
    return TAffine(a22 * d, -a12 * d, (a12 * a23 - a22 * a13) * d, -a21 * d,
Shinya Kitaoka 120a6e
                   a11 * d, (a21 * a13 - a11 * a23) * d);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
double TAffine::det() const { return a11 * a22 - a12 * a21; }
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Confronti tra affini
Shinya Kitaoka 120a6e
bool TAffine::operator==(const TAffine &a) const {
Shinya Kitaoka 120a6e
  return a11 == a.a11 && a12 == a.a12 && a13 == a.a13 && a21 == a.a21 &&
Shinya Kitaoka 120a6e
         a22 == a.a22 && a23 == a.a23;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
bool TAffine::operator!=(const TAffine &a) const {
Shinya Kitaoka 120a6e
  return a11 != a.a11 || a12 != a.a12 || a13 != a.a13 || a21 != a.a21 ||
Shinya Kitaoka 120a6e
         a22 != a.a22 || a23 != a.a23;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
bool TAffine::isIdentity(double err) const {
Shinya Kitaoka 120a6e
  return ((a11 - 1.0) * (a11 - 1.0) + (a22 - 1.0) * (a22 - 1.0) + a12 * a12 +
Shinya Kitaoka 120a6e
          a13 * a13 + a21 * a21 + a23 * a23) < err;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
bool TAffine::isTranslation(double err) const {
Shinya Kitaoka 120a6e
  return ((a11 - 1.0) * (a11 - 1.0) + (a22 - 1.0) * (a22 - 1.0) + a12 * a12 +
Shinya Kitaoka 120a6e
          a21 * a21) < err;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
bool TAffine::isIsotropic(double err) const {
Shinya Kitaoka 120a6e
  return areAlmostEqual(a11, a22, err) && areAlmostEqual(a12, -a21, err);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// applicazione
Shinya Kitaoka 120a6e
TPointD TAffine::operator*(const TPointD &p) const {
Shinya Kitaoka 120a6e
  return TPointD(p.x * a11 + p.y * a12 + a13, p.x * a21 + p.y * a22 + a23);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRectD TAffine::operator*(const TRectD &rect) const {
Shinya Kitaoka 120a6e
  if (rect != TConsts::infiniteRectD) {
Shinya Kitaoka 120a6e
    TPointD p1 = *this * rect.getP00(), p2 = *this * rect.getP01(),
Shinya Kitaoka 120a6e
            p3 = *this * rect.getP10(), p4 = *this * rect.getP11();
Shinya Kitaoka 120a6e
    return TRectD(
Shinya Kitaoka 120a6e
        std::min({p1.x, p2.x, p3.x, p4.x}), std::min({p1.y, p2.y, p3.y, p4.y}),
Shinya Kitaoka 120a6e
        std::max({p1.x, p2.x, p3.x, p4.x}), std::max({p1.y, p2.y, p3.y, p4.y}));
Shinya Kitaoka 120a6e
  } else
Shinya Kitaoka 120a6e
    return TConsts::infiniteRectD;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine TAffine::place(double u, double v, double x, double y) const {
Shinya Kitaoka 120a6e
  return TAffine(a11, a12, x - (a11 * u + a12 * v), a21, a22,
Shinya Kitaoka 120a6e
                 y - (a21 * u + a22 * v));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TAffine TAffine::place(const TPointD &pIn, const TPointD &pOut) const {
Shinya Kitaoka 120a6e
  return TAffine(a11, a12, pOut.x - (a11 * pIn.x + a12 * pIn.y), a21, a22,
Shinya Kitaoka 120a6e
                 pOut.y - (a21 * pIn.x + a22 * pIn.y));
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TRotation::TRotation(double degrees) {
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
    switch ((idegrees / 90) & 3) {
Shinya Kitaoka 120a6e
    case 0:
Shinya Kitaoka 120a6e
      sn = 0;
Shinya Kitaoka 120a6e
      cs = 1;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case 1:
Shinya Kitaoka 120a6e
      sn = 1;
Shinya Kitaoka 120a6e
      cs = 0;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case 2:
Shinya Kitaoka 120a6e
      sn = 0;
Shinya Kitaoka 120a6e
      cs = -1;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    case 3:
Shinya Kitaoka 120a6e
      sn = -1;
Shinya Kitaoka 120a6e
      cs = 0;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    default:
Shinya Kitaoka 120a6e
      sn = 0;
Shinya Kitaoka 120a6e
      cs = 0;
Shinya Kitaoka 120a6e
      break;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  } else {
Shinya Kitaoka 120a6e
    rad                         = degrees * M_PI_180;
Shinya Kitaoka 120a6e
    sn                          = sin(rad);
Shinya Kitaoka 120a6e
    cs                          = cos(rad);
Shinya Kitaoka 120a6e
    if (sn == 1 || sn == -1) cs = 0;
Shinya Kitaoka 120a6e
    if (cs == 1 || cs == -1) sn = 0;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  a11 = cs;
Shinya Kitaoka 120a6e
  a12 = -sn;
Shinya Kitaoka 120a6e
  a21 = -a12;
Shinya Kitaoka 120a6e
  a22 = a11;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
TRotation::TRotation(const TPointD ¢er, double degrees) {
Shinya Kitaoka 120a6e
  TAffine a = TTranslation(center) * TRotation(degrees) * TTranslation(-center);
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;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//==================================================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
TScale::TScale(const TPointD ¢er, double sx, double sy) {
Shinya Kitaoka 120a6e
  TAffine a = TTranslation(center) * TScale(sx, sy) * TTranslation(-center);
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;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------------------------------
Shinya Kitaoka 120a6e
TScale::TScale(const TPointD ¢er, double s) {
Shinya Kitaoka 120a6e
  TAffine a = TTranslation(center) * TScale(s) * TTranslation(-center);
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;
Toshihiro Shimizu 890ddd
}