Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "colorfxutils.h"
Toshihiro Shimizu 890ddd
#include "drawutil.h"
Toshihiro Shimizu 890ddd
#include "tregion.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
RubberDeform::RubberDeform() : m_pPolyOri(0), m_polyLoc() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
RubberDeform::RubberDeform(std::vector<t3dpointd> *pPolyOri, const double rf)</t3dpointd>
Shinya Kitaoka 120a6e
    : m_pPolyOri(pPolyOri), m_polyLoc() {
Shinya Kitaoka 120a6e
  copyOri2Loc();
Shinya Kitaoka 120a6e
  TRectD bbox;
Shinya Kitaoka 120a6e
  getBBox(bbox);
Shinya Kitaoka 120a6e
  double d = tdistance(TPointD(bbox.x0, bbox.y0), TPointD(bbox.x1, bbox.y1));
Shinya Kitaoka 120a6e
  d        = d / 20;
Shinya Kitaoka 120a6e
  refinePoly(d);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
RubberDeform::~RubberDeform() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
void RubberDeform::deformStep() {
Shinya Kitaoka 120a6e
  std::vector<t3dpointd> tmpv;</t3dpointd>
Shinya Kitaoka 120a6e
  std::vector<t3dpointd>::iterator itb = m_polyLoc.begin();</t3dpointd>
Shinya Kitaoka 120a6e
  std::vector<t3dpointd>::iterator ite = m_polyLoc.end();</t3dpointd>
Shinya Kitaoka 120a6e
  for (std::vector<t3dpointd>::iterator it = itb; it != ite; ++it) {</t3dpointd>
Shinya Kitaoka 120a6e
    std::vector<t3dpointd>::iterator it1 = it == (ite - 1) ? itb : it + 1;</t3dpointd>
Shinya Kitaoka 120a6e
    double q                             = 0.5;
Shinya Kitaoka 120a6e
    double qq                            = 1.0 - q;
Shinya Kitaoka 120a6e
    tmpv.push_back(T3DPointD(qq * it->x + q * it1->x, qq * it->y + q * it1->y,
Shinya Kitaoka 120a6e
                             qq * it->z + q * it1->z));
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_polyLoc = tmpv;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RubberDeform::deform(const double n) {
Shinya Kitaoka 120a6e
  if (n <= 0 || n >= 100) return;
Shinya Kitaoka 120a6e
  double q = (double)n / 100.0;
Shinya Kitaoka 120a6e
  TRectD bbox;
Shinya Kitaoka 120a6e
  getBBox(bbox);
Shinya Kitaoka 120a6e
  double d0 = ((bbox.y1 - bbox.y0) * 0.5 + (bbox.x1 - bbox.x0) * 0.5) * 0.5;
Shinya Kitaoka 120a6e
  double d  = d0;
Shinya Kitaoka 120a6e
  while ((d / d0) > q) {
Shinya Kitaoka 120a6e
    deformStep();
Shinya Kitaoka 120a6e
    getBBox(bbox);
Shinya Kitaoka 120a6e
    d = ((bbox.y1 - bbox.y0) * 0.5 + (bbox.x1 - bbox.x0) * 0.5) * 0.5;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  copyLoc2Ori();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
double RubberDeform::avgLength() {
Shinya Kitaoka 120a6e
  if (m_polyLoc.size() <= 0) return 0.0;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double avgD                          = 0.0;
Shinya Kitaoka 120a6e
  std::vector<t3dpointd>::iterator itb = m_polyLoc.begin();</t3dpointd>
Shinya Kitaoka 120a6e
  std::vector<t3dpointd>::iterator ite = m_polyLoc.end();</t3dpointd>
Shinya Kitaoka 120a6e
  for (std::vector<t3dpointd>::iterator it = itb; it != ite; ++it) {</t3dpointd>
Shinya Kitaoka 120a6e
    std::vector<t3dpointd>::iterator it1 = it == (ite - 1) ? itb : it + 1;</t3dpointd>
Shinya Kitaoka 120a6e
    avgD += tdistance(*it, *it1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  return avgD / (double)m_polyLoc.size();
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RubberDeform::getBBox(TRectD &bbox) {
Shinya Kitaoka 120a6e
  if (m_polyLoc.size() <= 0) {
Shinya Kitaoka 120a6e
    bbox.x0 = bbox.y0 = 0;
Shinya Kitaoka 120a6e
    bbox.x1 = bbox.y1 = -1;
Shinya Kitaoka 120a6e
    return;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  bbox.x0 = bbox.x1 = m_polyLoc[0].x;
Shinya Kitaoka 120a6e
  bbox.y0 = bbox.y1 = m_polyLoc[0].y;
Shinya Kitaoka 120a6e
  for (int i = 1; i < (int)m_polyLoc.size(); i++) {
Shinya Kitaoka 120a6e
    bbox.x0 = std::min(bbox.x0, m_polyLoc[i].x);
Shinya Kitaoka 120a6e
    bbox.x1 = std::max(bbox.x1, m_polyLoc[i].x);
Shinya Kitaoka 120a6e
    bbox.y0 = std::min(bbox.y0, m_polyLoc[i].y);
Shinya Kitaoka 120a6e
    bbox.y1 = std::max(bbox.y1, m_polyLoc[i].y);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
void RubberDeform::refinePoly(const double rf) {
Shinya Kitaoka 120a6e
  double refineL = rf <= 0.0 ? avgLength() : rf;
Shinya Kitaoka 120a6e
  std::vector<t3dpointd> tmpv;</t3dpointd>
Shinya Kitaoka 120a6e
  int nb = m_polyLoc.size();
Shinya Kitaoka 120a6e
  for (int j = 0; j < nb; j++) {
Shinya Kitaoka 120a6e
    T3DPointD a(m_polyLoc[j]);
Shinya Kitaoka 120a6e
    T3DPointD b(j == (nb - 1) ? m_polyLoc[0] : m_polyLoc[j + 1]);
Shinya Kitaoka 120a6e
    tmpv.push_back(a);
Shinya Kitaoka 120a6e
    double d = tdistance(a, b);
Shinya Kitaoka 120a6e
    if (d > refineL) {
Shinya Kitaoka 120a6e
      int n    = (int)(d / refineL) + 1;
Shinya Kitaoka 120a6e
      double q = 1.0 / (double)n;
Shinya Kitaoka 120a6e
      for (int i = 1; i < n; i++) {
Shinya Kitaoka 120a6e
        double qq  = q * (double)i;
Shinya Kitaoka 120a6e
        double qq1 = 1.0 - qq;
Shinya Kitaoka 120a6e
        T3DPointD p(T3DPointD(qq1 * a.x + qq * b.x, qq1 * a.y + qq * b.y,
Shinya Kitaoka 120a6e
                              qq1 * a.z + qq * b.z));
Shinya Kitaoka 120a6e
        tmpv.push_back(p);
Shinya Kitaoka 120a6e
      }
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  m_polyLoc = tmpv;
Toshihiro Shimizu 890ddd
}