Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef T_CURVES_INCLUDED
Toshihiro Shimizu 890ddd
#define T_CURVES_INCLUDED
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "tgeometry.h"
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
//=============================================================================
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  TSegment Class to manage a segment
Toshihiro Shimizu 890ddd
 */
Shinya Kitaoka 120a6e
class DVAPI TSegment {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  TPointD m_c0, m_c1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TSegment() : m_c0(), m_c1(){};
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! p0,p1  are the two control points
Shinya Kitaoka 120a6e
  TSegment(const TPointD &p0, const TPointD &p1) : m_c0(p0), m_c1(p1 - p0) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TSegment(double x0, double y0, double x1, double y1)
Shinya Kitaoka 120a6e
      : m_c0(x0, y0), m_c1(x1 - x0, y1 - y0) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TSegment(const TSegment &src) : m_c0(src.m_c0), m_c1(src.m_c1) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return the point of segment at parameter \b t.
Shinya Kitaoka 120a6e
  TPointD getPoint(double t) const { return m_c0 + t * m_c1; };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return speed of segment.
Shinya Kitaoka 120a6e
  TPointD getSpeed(double = 0) const { return m_c1; };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return first control point \b P0.
Shinya Kitaoka 120a6e
  TPointD getP0() const { return m_c0; }
Shinya Kitaoka 120a6e
  //! Return second control point \b P1.
Shinya Kitaoka 120a6e
  TPointD getP1() const { return m_c0 + m_c1; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Set the value of first control point \b P0 to \b p.
Shinya Kitaoka 120a6e
  void setP0(const TPointD &p) {
Shinya Kitaoka 120a6e
    m_c1 += m_c0 - p;
Shinya Kitaoka 120a6e
    m_c0 = p;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  //! Set the value of second control point \b P1 to \b p.
Shinya Kitaoka 120a6e
  void setP1(const TPointD &p) { m_c1 = p - m_c0; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator==(const TSegment &c) const {
Shinya Kitaoka 120a6e
    return m_c0 == c.m_c0 && m_c1 == c.m_c1;
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator!=(const TSegment &c) const { return !operator==(c); };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return rect that contains the segment.
Shinya Kitaoka 120a6e
  TRectD getBBox() const { return TRectD(getP0(), getP1()); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return the length of segment
Shinya Kitaoka 120a6e
  double getLength() const { return norm(m_c1); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return true if segment is a point
Shinya Kitaoka 120a6e
  bool isPoint(double err2 = TConsts::epsilon) const {
Shinya Kitaoka 120a6e
    return norm2(m_c1) < err2;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
DVAPI std::ostream &operator<<(std::ostream &out, const TSegment &segment);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!\relates TAffine, TSegment
Shinya Kitaoka 120a6e
inline TSegment operator*(const TAffine &aff, const TSegment &seg) {
Shinya Kitaoka 120a6e
  return TSegment(aff * seg.getP0(), aff * seg.getP1());
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
   TQuadratic class to manage a quadratic
Toshihiro Shimizu 890ddd
 */
Shinya Kitaoka 120a6e
class DVAPI TQuadratic {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  TPointD m_p0, m_p1, m_p2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TQuadratic() : m_p0(), m_p1(), m_p2() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! p0,p1,p2 are the three control points
Shinya Kitaoka 120a6e
  TQuadratic(const TPointD &p0, const TPointD &p1, const TPointD &p2)
Shinya Kitaoka 120a6e
      : m_p0(p0), m_p1(p1), m_p2(p2) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TQuadratic(const TQuadratic &src)
Shinya Kitaoka 120a6e
      : m_p0(src.m_p0), m_p1(src.m_p1), m_p2(src.m_p2) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TQuadratic &operator=(const TQuadratic &src) {
Shinya Kitaoka 120a6e
    m_p0 = src.m_p0;
Shinya Kitaoka 120a6e
    m_p1 = src.m_p1;
Shinya Kitaoka 120a6e
    m_p2 = src.m_p2;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return the point of quadratic at parameter \b t.
Shinya Kitaoka 120a6e
  TPointD getPoint(double t) const;
Shinya Kitaoka 120a6e
  double getX(double t) const;
Shinya Kitaoka 120a6e
  double getY(double t) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return speed of quadratic at parameter \b t.
Shinya Kitaoka 120a6e
  TPointD getSpeed(double t) const {
Shinya Kitaoka 120a6e
    return 2 * ((t - 1) * m_p0 + (1.0 - 2.0 * t) * m_p1 + t * m_p2);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return the y value of quadratic speed at parameter \b t.
Shinya Kitaoka 120a6e
  double getSpeedY(double t) const {
Shinya Kitaoka 120a6e
    return 2 * ((t - 1) * m_p0.y + (1.0 - 2.0 * t) * m_p1.y + t * m_p2.y);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return acceleration of quadratic.
Shinya Kitaoka 120a6e
  TPointD getAcceleration(double = 0) const {
Shinya Kitaoka 120a6e
    return 2.0 * (m_p0 + m_p2 - 2.0 * m_p1);
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return curvature of quadratic at parameter \b t.
Shinya Kitaoka 120a6e
  /*! Calcolo della curvatura per una Quadratica.
Shinya Kitaoka 120a6e
  Vedi Farin pag.176 per la spiegazione della formula
Shinya Kitaoka 120a6e
  usata.
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  double getCurvature(double t) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return first control point \b P0.
Shinya Kitaoka 120a6e
  TPointD getP0() const { return m_p0; }
Shinya Kitaoka 120a6e
  //! Return second control point \b P1.
Shinya Kitaoka 120a6e
  TPointD getP1() const { return m_p1; }
Shinya Kitaoka 120a6e
  //! Return third control point \b P2.
Shinya Kitaoka 120a6e
  TPointD getP2() const { return m_p2; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Set the value of first control point \b P0 to \b p.
Shinya Kitaoka 120a6e
  void setP0(const TPointD &p) { m_p0 = p; }
Shinya Kitaoka 120a6e
  //! Set the value of second control point \b P1 to \b p.
Shinya Kitaoka 120a6e
  void setP1(const TPointD &p) { m_p1 = p; }
Shinya Kitaoka 120a6e
  //! Set the value of third control point \b P2 to \b p.
Shinya Kitaoka 120a6e
  void setP2(const TPointD &p) { m_p2 = p; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator==(const TQuadratic &c) const {
Shinya Kitaoka 120a6e
    return m_p0 == c.m_p0 && m_p1 == c.m_p1 && m_p2 == c.m_p2;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator!=(const TQuadratic &c) const { return !operator==(c); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return a parameter that correspond to the point \b p in the quadratic.
Shinya Kitaoka 120a6e
  double getT(const TPointD &p) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int getX(double y, double &x0, double &x1) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  int getY(double x, double &y0, double &y1) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
N.B. if t==0 o t==1 return a quadratic with all points equal
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  void split(double t, TQuadratic &first, TQuadratic &second) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return rect that contains the quadratic.
Shinya Kitaoka 120a6e
  TRectD getBBox() const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
Return length of an arc between parameters t0 t1.
Shinya Kitaoka 120a6e
N.B. Length returned is always positive.
Shinya Kitaoka 120a6e
\note t0 and t1 are clamped to [0,1] interval
Shinya Kitaoka 120a6e
\note if t0>=t1 returns 0
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  double getLength(double t0, double t1) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double getLength(double t1 = 1) const { return getLength(0, t1); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  double getApproximateLength(double t0, double t1, double error) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void reverse() {
Shinya Kitaoka 120a6e
    TPointD app;
Shinya Kitaoka 120a6e
    app  = m_p0;
Shinya Kitaoka 120a6e
    m_p0 = m_p2;
Shinya Kitaoka 120a6e
    m_p2 = app;
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!\relates TAffine, TQuadratic
Shinya Kitaoka 120a6e
inline TQuadratic operator*(const TAffine &aff, const TQuadratic &curve) {
Shinya Kitaoka 120a6e
  TQuadratic quad;
Shinya Kitaoka 120a6e
  quad.setP0(aff * curve.getP0());
Shinya Kitaoka 120a6e
  quad.setP1(aff * curve.getP1());
Shinya Kitaoka 120a6e
  quad.setP2(aff * curve.getP2());
Shinya Kitaoka 120a6e
  return quad;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
DVAPI std::ostream &operator<<(std::ostream &out, const TQuadratic &curve);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline std::ostream &operator<<(std::ostream &out, const TQuadratic *curve) {
Shinya Kitaoka 120a6e
  assert(curve);
Shinya Kitaoka 120a6e
  return out << *curve;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
   TCubic class to manage a cubic
Toshihiro Shimizu 890ddd
 */
Shinya Kitaoka 120a6e
class DVAPI TCubic {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  TPointD m_p0, m_p1, m_p2, m_p3;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TCubic() : m_p0(), m_p1(), m_p2(), m_p3() {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! p0,p1,p2,p3 are the four control points
Shinya Kitaoka 120a6e
  TCubic(const TPointD &p0, const TPointD &p1, const TPointD &p2,
Shinya Kitaoka 120a6e
         const TPointD &p3)
Shinya Kitaoka 120a6e
      : m_p0(p0), m_p1(p1), m_p2(p2), m_p3(p3) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TCubic(const TCubic &src)
Shinya Kitaoka 120a6e
      : m_p0(src.m_p0), m_p1(src.m_p1), m_p2(src.m_p2), m_p3(src.m_p3) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TCubic &operator=(const TCubic &src) {
Shinya Kitaoka 120a6e
    m_p0 = src.m_p0;
Shinya Kitaoka 120a6e
    m_p1 = src.m_p1;
Shinya Kitaoka 120a6e
    m_p2 = src.m_p2;
Shinya Kitaoka 120a6e
    m_p3 = src.m_p3;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return first control point \b P0.
Shinya Kitaoka 120a6e
  TPointD getP0() const { return m_p0; }
Shinya Kitaoka 120a6e
  //! Return second control point \b P1.
Shinya Kitaoka 120a6e
  TPointD getP1() const { return m_p1; }
Shinya Kitaoka 120a6e
  //! Return third control point \b P2.
Shinya Kitaoka 120a6e
  TPointD getP2() const { return m_p2; }
Shinya Kitaoka 120a6e
  //! Return fourth control point \b P3.
Shinya Kitaoka 120a6e
  TPointD getP3() const { return m_p3; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Set the value of first control point \b P0 to \b p.
Shinya Kitaoka 120a6e
  void setP0(const TPointD &p0) { m_p0 = p0; }
Shinya Kitaoka 120a6e
  //! Set the value of second control point \b P1 to \b p.
Shinya Kitaoka 120a6e
  void setP1(const TPointD &p1) { m_p1 = p1; }
Shinya Kitaoka 120a6e
  //! Set the value of third control point \b P2 to \b p.
Shinya Kitaoka 120a6e
  void setP2(const TPointD &p2) { m_p2 = p2; }
Shinya Kitaoka 120a6e
  //! Set the value of fourth control point \b P3 to \b p.
Shinya Kitaoka 120a6e
  void setP3(const TPointD &p3) { m_p3 = p3; }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator==(const TCubic &c) const {
Shinya Kitaoka 120a6e
    return m_p0 == c.m_p0 && m_p1 == c.m_p1 && m_p2 == c.m_p2 && m_p3 == c.m_p3;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  bool operator!=(const TCubic &c) const { return !operator==(c); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return rect that contains the cubic.
Shinya Kitaoka 120a6e
  TRectD getBBox() const {
Shinya Kitaoka 120a6e
    return TRectD(std::min({m_p0.x, m_p1.x, m_p2.x, m_p3.x}),
Shinya Kitaoka 120a6e
                  std::min({m_p0.y, m_p1.y, m_p2.y, m_p3.y}),
Shinya Kitaoka 120a6e
                  std::max({m_p0.x, m_p1.x, m_p2.x, m_p3.x}),
Shinya Kitaoka 120a6e
                  std::max({m_p0.y, m_p1.y, m_p2.y, m_p3.y}));
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return the point of cubic at parameter \b t.
Shinya Kitaoka 120a6e
  TPointD getPoint(double t) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return speed of cubic at parameter \b t.
Shinya Kitaoka 120a6e
  TPointD getSpeed(double t) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return acceleration of cubic at parameter \b t.
Shinya Kitaoka 120a6e
  TPointD getAcceleration(double t) const {
Shinya Kitaoka 120a6e
    return 6.0 *
Shinya Kitaoka 120a6e
           ((m_p2 - 2 * m_p1 + m_p0) * (1 - t) + (m_p3 - 2 * m_p2 + m_p1) * t);
Shinya Kitaoka 120a6e
  };
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
Return length of an arc between parameters t0 t1.
Shinya Kitaoka 120a6e
N.B. Length returned is always positive.
Shinya Kitaoka 120a6e
\note t0 and t1 are clamped to [0,1] interval
Shinya Kitaoka 120a6e
\note if t0>=t1 returns 0
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  double getLength(double t0, double t1) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  inline double getLength(double t1 = 1.0) const { return getLength(0.0, t1); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  /*!
Shinya Kitaoka 120a6e
N.B. if t==0 o t==1 return a quadratic with all points equal
Shinya Kitaoka 120a6e
*/
Shinya Kitaoka 120a6e
  void split(double t, TCubic &first, TCubic &second) const;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//!\relates TAffine, TCubic
Shinya Kitaoka 120a6e
inline TCubic operator*(const TAffine &aff, const TCubic &curve) {
Shinya Kitaoka 120a6e
  TCubic out;
Shinya Kitaoka 120a6e
  out.setP0(aff * curve.getP0());
Shinya Kitaoka 120a6e
  out.setP1(aff * curve.getP1());
Shinya Kitaoka 120a6e
  out.setP2(aff * curve.getP2());
Shinya Kitaoka 120a6e
  out.setP3(aff * curve.getP3());
Shinya Kitaoka 120a6e
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
DVAPI std::ostream &operator<<(std::ostream &out, const TCubic &curve);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline std::ostream &operator<<(std::ostream &out, const TCubic *curve) {
Shinya Kitaoka 120a6e
  assert(curve);
Shinya Kitaoka 120a6e
  return out << *curve;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  TSegment Class to manage a segment with thickness
Toshihiro Shimizu 890ddd
  \!relates TSegment
Toshihiro Shimizu 890ddd
 */
Shinya Kitaoka d1f6c4
class DVAPI TThickSegment final : public TSegment {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  double m_thickP0;
Shinya Kitaoka 120a6e
  double m_thickP1;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  //! m_thickP0, m_thickP1 are thickness of segment control points
Shinya Kitaoka 120a6e
  TThickSegment() : TSegment(), m_thickP0(0), m_thickP1(0) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickSegment(const TThickSegment &thickSegment)
Shinya Kitaoka 120a6e
      : TSegment(thickSegment)
Shinya Kitaoka 120a6e
      , m_thickP0(thickSegment.m_thickP0)
Shinya Kitaoka 120a6e
      , m_thickP1(thickSegment.m_thickP1) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickSegment(const TSegment &seg)
Shinya Kitaoka 120a6e
      : TSegment(seg), m_thickP0(0), m_thickP1(0) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickSegment(const TPointD &p0, double thickP0, const TPointD &p1,
Shinya Kitaoka 120a6e
                double thickP1)
Shinya Kitaoka 120a6e
      : TSegment(p0, p1), m_thickP0(thickP0), m_thickP1(thickP1) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickSegment(const TThickPoint &thickP0, const TThickPoint &thickP1)
Shinya Kitaoka 120a6e
      : TSegment(thickP0, thickP1)
Shinya Kitaoka 120a6e
      , m_thickP0(thickP0.thick)
Shinya Kitaoka 120a6e
      , m_thickP1(thickP1.thick) {}
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickSegment &operator=(const TThickSegment &other) {
Shinya Kitaoka 120a6e
    m_c0.x    = other.m_c0.x;
Shinya Kitaoka 120a6e
    m_c1.x    = other.m_c1.x;
Shinya Kitaoka 120a6e
    m_c0.y    = other.m_c0.y;
Shinya Kitaoka 120a6e
    m_c1.y    = other.m_c1.y;
Shinya Kitaoka 120a6e
    m_thickP0 = other.m_thickP0;
Shinya Kitaoka 120a6e
    m_thickP1 = other.m_thickP1;
Shinya Kitaoka 120a6e
    return *this;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Set the value of first control point \b P0 to \b TThickPoint \b p0.
Shinya Kitaoka 120a6e
  void setThickP0(const TThickPoint &p0) {
Shinya Kitaoka 120a6e
    m_c0.x    = p0.x;
Shinya Kitaoka 120a6e
    m_c0.y    = p0.y;
Shinya Kitaoka 120a6e
    m_thickP0 = p0.thick;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
  //! Set the value of second control point \b P1 to \b TThickPoint \b p1.
Shinya Kitaoka 120a6e
  void setThickP1(const TThickPoint &p1) {
Shinya Kitaoka 120a6e
    m_c1.x    = p1.x - m_c0.x;
Shinya Kitaoka 120a6e
    m_c1.y    = p1.y - m_c0.y;
Shinya Kitaoka 120a6e
    m_thickP1 = p1.thick;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return first control point \b P0.
Shinya Kitaoka 120a6e
  TThickPoint getThickP0() const { return TThickPoint(m_c0, m_thickP0); }
Shinya Kitaoka 120a6e
  //! Return second control point \b P1.
Shinya Kitaoka 120a6e
  TThickPoint getThickP1() const { return TThickPoint(m_c0 + m_c1, m_thickP1); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return the \b TThickPoint of segment at parameter \b t.
Shinya Kitaoka 120a6e
  TThickPoint getThickPoint(double t) const {
Shinya Kitaoka 120a6e
    return TThickPoint(m_c0 + t * m_c1, (1 - t) * m_thickP0 + t * m_thickP1);
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline TThickSegment operator*(const TAffine &aff, const TThickSegment &ts) {
Shinya Kitaoka 120a6e
  TThickSegment out(ts);
Shinya Kitaoka 120a6e
  out.setP0(aff * ts.getP0());
Shinya Kitaoka 120a6e
  out.setP1(aff * ts.getP1());
Shinya Kitaoka 120a6e
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
DVAPI std::ostream &operator<<(std::ostream &out, const TThickSegment &segment);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline std::ostream &operator<<(std::ostream &out,
Shinya Kitaoka 120a6e
                                const TThickSegment *segment) {
Shinya Kitaoka 120a6e
  assert(segment);
Shinya Kitaoka 120a6e
  return out << *segment;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  Class TThickQuadratic: manage a curve with thick
Toshihiro Shimizu 890ddd
  \!relates TQuadratic
Toshihiro Shimizu 890ddd
 */
Shinya Kitaoka d1f6c4
class DVAPI TThickQuadratic final : public TQuadratic {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  double m_thickP0;
Shinya Kitaoka 120a6e
  double m_thickP1;
Shinya Kitaoka 120a6e
  double m_thickP2;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TThickQuadratic();
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //! thickP0, thickP1, thickP2 are thickness of quadratic control points
Shinya Kitaoka 120a6e
  TThickQuadratic(const TPointD &p0, double thickP0, const TPointD &p1,
Shinya Kitaoka 120a6e
                  double thickP1, const TPointD &p2, double thickP2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThickQuadratic(const TThickPoint &p0, const TThickPoint &p1,
Shinya Kitaoka 120a6e
                  const TThickPoint &p2);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThickQuadratic(const TThickQuadratic &thickQuadratic);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThickQuadratic(const TQuadratic &quadratic);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //! Set the value of first control point \b P0 to \b TThickPoint \b p.
Shinya Kitaoka 120a6e
  void setThickP0(const TThickPoint &p);
Shinya Kitaoka 120a6e
  //! Set the value of second control point \b P1 to \b TThickPoint \b p.
Shinya Kitaoka 120a6e
  void setThickP1(const TThickPoint &p);
Shinya Kitaoka 120a6e
  //! Set the value of third control point \b P2 to \b TThickPoint \b p.
Shinya Kitaoka 120a6e
  void setThickP2(const TThickPoint &p);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //! Return the \b TThickPoint of quadratic at parameter \b t.
Shinya Kitaoka 120a6e
  TThickPoint getThickPoint(double t) const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  //! Return first control point \b P0.
Shinya Kitaoka 120a6e
  TThickPoint getThickP0() const { return TThickPoint(m_p0, m_thickP0); }
Shinya Kitaoka 120a6e
  //! Return second control point \b P1.
Shinya Kitaoka 120a6e
  TThickPoint getThickP1() const { return TThickPoint(m_p1, m_thickP1); }
Shinya Kitaoka 120a6e
  //! Return third control point \b P2.
Shinya Kitaoka 120a6e
  TThickPoint getThickP2() const { return TThickPoint(m_p2, m_thickP2); }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  void split(double t, TThickQuadratic &first, TThickQuadratic &second) const;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TRectD getBBox() const;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline TThickQuadratic operator*(const TAffine &aff,
Shinya Kitaoka 120a6e
                                 const TThickQuadratic &tq) {
Shinya Kitaoka 120a6e
  TThickQuadratic out(tq);
Shinya Kitaoka 120a6e
  out.setP0(aff * tq.getP0());
Shinya Kitaoka 120a6e
  out.setP1(aff * tq.getP1());
Shinya Kitaoka 120a6e
  out.setP2(aff * tq.getP2());
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline TThickQuadratic transformQuad(const TAffine &aff,
Shinya Kitaoka 120a6e
                                     const TThickQuadratic &tq,
Shinya Kitaoka 120a6e
                                     bool doChangeThickness = false) {
Shinya Kitaoka 120a6e
  if (!doChangeThickness) return aff * tq;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  TThickQuadratic out(tq);
Shinya Kitaoka 120a6e
  double det = aff.det();
Shinya Kitaoka 120a6e
  det        = (det < 0) ? sqrt(-det) : sqrt(det);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  out.setThickP0(TThickPoint(aff * tq.getP0(), tq.getThickP0().thick * det));
Shinya Kitaoka 120a6e
  out.setThickP1(TThickPoint(aff * tq.getP1(), tq.getThickP1().thick * det));
Shinya Kitaoka 120a6e
  out.setThickP2(TThickPoint(aff * tq.getP2(), tq.getThickP2().thick * det));
Shinya Kitaoka 120a6e
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
DVAPI std::ostream &operator<<(std::ostream &out, const TThickQuadratic &tq);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline std::ostream &operator<<(std::ostream &out, const TThickQuadratic *tq) {
Shinya Kitaoka 120a6e
  assert(tq);
Shinya Kitaoka 120a6e
  return out << *tq;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=============================================================================
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  Class TThickCubic: manage a cubic with thick
Toshihiro Shimizu 890ddd
  \!relates TCubic
Toshihiro Shimizu 890ddd
 */
Shinya Kitaoka d1f6c4
class DVAPI TThickCubic final : public TCubic {
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  double m_thickP0;
Shinya Kitaoka 120a6e
  double m_thickP1;
Shinya Kitaoka 120a6e
  double m_thickP2;
Shinya Kitaoka 120a6e
  double m_thickP3;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  TThickCubic();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! thickP0, thickP1, thickP2, thickP3 are thickness of cubic control points
Shinya Kitaoka 120a6e
  TThickCubic(const TPointD &p0, double thickP0, const TPointD &p1,
Shinya Kitaoka 120a6e
              double thickP1, const TPointD &p2, double thickP2,
Shinya Kitaoka 120a6e
              const TPointD &p3, double thickP3);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickCubic(const TThickPoint &p0, const TThickPoint &p1,
Shinya Kitaoka 120a6e
              const TThickPoint &p2, const TThickPoint &p3);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //  tonino ***************************************************************
Shinya Kitaoka 120a6e
  TThickCubic(const T3DPointD &p0, const T3DPointD &p1, const T3DPointD &p2,
Shinya Kitaoka 120a6e
              const T3DPointD &p3);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //  tonino ***************************************************************
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickCubic(const TThickCubic &thickCubic);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  TThickCubic(const TCubic &cubic);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Set the value of first control point \b P0 to \b TThickPoint \b p.
Shinya Kitaoka 120a6e
  void setThickP0(const TThickPoint &p);
Shinya Kitaoka 120a6e
  //! Set the value of second control point \b P1 to \b TThickPoint \b p.
Shinya Kitaoka 120a6e
  void setThickP1(const TThickPoint &p);
Shinya Kitaoka 120a6e
  //! Set the value of third control point \b P2 to \b TThickPoint \b p.
Shinya Kitaoka 120a6e
  void setThickP2(const TThickPoint &p);
Shinya Kitaoka 120a6e
  //! Set the value of fourth control point \b P3 to \b TThickPoint \b p.
Shinya Kitaoka 120a6e
  void setThickP3(const TThickPoint &p);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return the \b TThickPoint of cubic at parameter \b t.
Shinya Kitaoka 120a6e
  TThickPoint getThickPoint(double t) const;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  //! Return first control point \b P0.
Shinya Kitaoka 120a6e
  TThickPoint getThickP0() const { return TThickPoint(m_p0, m_thickP0); }
Shinya Kitaoka 120a6e
  //! Return second control point \b P1.
Shinya Kitaoka 120a6e
  TThickPoint getThickP1() const { return TThickPoint(m_p1, m_thickP1); }
Shinya Kitaoka 120a6e
  //! Return third control point \b P2.
Shinya Kitaoka 120a6e
  TThickPoint getThickP2() const { return TThickPoint(m_p2, m_thickP2); }
Shinya Kitaoka 120a6e
  //! Return fourth control point \b P3.
Shinya Kitaoka 120a6e
  TThickPoint getThickP3() const { return TThickPoint(m_p3, m_thickP3); }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  void split(double t, TThickCubic &first, TThickCubic &second) const;
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline TThickCubic operator*(const TAffine &aff, const TThickCubic &tc) {
Shinya Kitaoka 120a6e
  TThickCubic out(tc);
Shinya Kitaoka 120a6e
  out.setP0(aff * tc.getP0());
Shinya Kitaoka 120a6e
  out.setP1(aff * tc.getP1());
Shinya Kitaoka 120a6e
  out.setP2(aff * tc.getP2());
Shinya Kitaoka 120a6e
  out.setP3(aff * tc.getP3());
Shinya Kitaoka 120a6e
  return out;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 3bfa54
DVAPI std::ostream &operator<<(std::ostream &out, const TThickCubic &tc);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//---------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
inline std::ostream &operator<<(std::ostream &out, const TThickCubic *tc) {
Shinya Kitaoka 120a6e
  assert(tc);
Shinya Kitaoka 120a6e
  return out << *tc;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//=====================================================================
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  //__T_CURVES_INCLUDED
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
//  End Of File
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------