Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef TCG_POLYLINE_OPS
Toshihiro Shimizu 890ddd
#define TCG_POLYLINE_OPS
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
// tcg includes
Toshihiro Shimizu 890ddd
#include "traits.h"
Toshihiro Shimizu 890ddd
#include "containers_reader.h"
Toshihiro Shimizu 890ddd
#include "point.h"
Toshihiro Shimizu 890ddd
#include "point_ops.h"
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
namespace tcg {
Shinya Kitaoka 120a6e
namespace polyline_ops {
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
//    Polyline Basic Operations
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  Computes the length of the polyline between the specified point iterators.
Toshihiro Shimizu 890ddd
  \return   The input polyline's length
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename forit=""></typename>
Shinya Kitaoka 120a6e
double length(ForIt begin, ForIt end) {
Shinya Kitaoka 120a6e
  typedef typename std::iterator_traits<forit>::value_type point_type;</forit>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double result = 0.0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  for (ForIt jt = begin, it = ++jt; jt != end; it = jt, ++jt)
Shinya Kitaoka 120a6e
    result += tcg::point_ops::dist(*it, *jt);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return result;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//-----------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  Computes the area enclosed by the input polyline's \a closure.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \note    The input polyline is implicitly \a connected at the endpoints
Toshihiro Shimizu 890ddd
           with a straight segment. This has obviously makes no difference
Toshihiro Shimizu 890ddd
           if the supplied polyline already had coincident endpoints.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \return  The area enclosed by the polyline's \a closure.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename forit=""></typename>
Shinya Kitaoka 120a6e
double area(ForIt begin, ForIt end) {
Shinya Kitaoka 120a6e
  typedef typename std::iterator_traits<forit>::value_type point_type;</forit>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  double result = 0.0;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  if (begin != end) {
Shinya Kitaoka 120a6e
    ForIt jt = begin, it = jt++;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    for (; jt != end; it = jt++)
Shinya Kitaoka 120a6e
      result += 0.5 * (tcg::point_traits<point_type>::y(*jt) +</point_type>
Shinya Kitaoka 120a6e
                       tcg::point_traits<point_type>::y(*it)) *</point_type>
Shinya Kitaoka 120a6e
                (tcg::point_traits<point_type>::x(*jt) -</point_type>
Shinya Kitaoka 120a6e
                 tcg::point_traits<point_type>::x(*it));</point_type>
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
    result += 0.5 * (tcg::point_traits<point_type>::y(*begin) +</point_type>
Shinya Kitaoka 120a6e
                     tcg::point_traits<point_type>::y(*it)) *</point_type>
Shinya Kitaoka 120a6e
              (tcg::point_traits<point_type>::x(*begin) -</point_type>
Shinya Kitaoka 120a6e
               tcg::point_traits<point_type>::x(*it));</point_type>
Shinya Kitaoka 120a6e
  }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  return result;
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
//    Quadratic Conversions
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Toshihiro Shimizu 890ddd
  Standard direct conversion function used in polyline-to-quadratics conversion.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  Point a has already been inserted in the output; this function must add the
Shinya Kitaoka 120a6e
  remaining part of a sequence of quadratics approximating the triplet (a, *bt,
Shinya Kitaoka 120a6e
  c).
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
// Note: typename iter_type::value_type == point_type
Toshihiro Shimizu 890ddd
template <typename iter_type="" point_type,="" typename=""></typename>
Shinya Kitaoka 120a6e
void tripletToQuadratics(
Shinya Kitaoka 120a6e
    const point_type &a, const iter_type &bt, const point_type &c,
Shinya Kitaoka 120a6e
    tcg::sequential_reader<std::vector<point_type>> &output) {</std::vector<point_type>
Shinya Kitaoka 120a6e
  // Direct conversion
Shinya Kitaoka 120a6e
  output.addElement(*bt);
Shinya Kitaoka 120a6e
  output.addElement(c);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
  Performs a conversion of the specified polyline into a sequence of quadratics,
Shinya Kitaoka 120a6e
then
Toshihiro Shimizu 890ddd
  applies a quadratics sub-sequence optimal merging algorithm.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  A user-made local triplet-to-quadratics conversion can be supplied to
Shinya Kitaoka 120a6e
recognize corners
Toshihiro Shimizu 890ddd
  or supply a tight starting approximation.
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
\warning Passed polylines with equal endpoints are interpreted as closed
Shinya Kitaoka 120a6e
(circular) polylines;
Shinya Kitaoka 120a6e
         in this case, the resulting endpoints of the quadratic sequence will be
Shinya Kitaoka 120a6e
displaced to
Toshihiro Shimizu 890ddd
         the first segment mid-point.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename containers_reader,="" iter_type,="" toquadsfunc="" typename=""></typename>
Shinya Kitaoka 120a6e
void toQuadratics(
Shinya Kitaoka 120a6e
    iter_type begin, iter_type end, containers_reader &output,
Shinya Kitaoka 120a6e
    toQuadsFunc &toQuads =
Shinya Kitaoka 120a6e
        &tripletToQuadratics<typename iter_type="" iter_type::value_type,="">,</typename>
Shinya Kitaoka 120a6e
    double mergeTol = 1.0);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
//    Standard Polyline Evaluators
Toshihiro Shimizu 890ddd
//**************************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
/*!
Shinya Kitaoka 120a6e
  Calculates the (weighted) standard deviation of a polyline's sub-paths with
Shinya Kitaoka 120a6e
  respect
Toshihiro Shimizu 890ddd
  to the segment connecting the endpoints.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
  \warning For efficiency reasons, the returned value is the actual standard
Toshihiro Shimizu 890ddd
  deviation, times the endpoints-segment length.
Toshihiro Shimizu 890ddd
*/
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename ranit=""></typename>
Shinya Kitaoka 120a6e
class StandardDeviationEvaluator {
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  typedef RanIt iterator_type;
Shinya Kitaoka 120a6e
  typedef typename std::iterator_traits<ranit>::difference_type diff_type;</ranit>
Shinya Kitaoka 120a6e
  typedef typename std::iterator_traits<ranit>::value_type point_type;</ranit>
Shinya Kitaoka 120a6e
  typedef typename tcg::point_traits<point_type>::value_type value_type;</point_type>
Shinya Kitaoka 120a6e
  typedef double penalty_type;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
protected:
Shinya Kitaoka 120a6e
  iterator_type m_begin, m_end;
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  std::vector<double> m_sums_x, m_sums_y;  //!< Sums of the points coordinates</double>
Shinya Kitaoka 120a6e
  std::vector<double> m_sums2_x,</double>
Shinya Kitaoka 120a6e
      m_sums2_y;                  //!< Sums of the points coordinates' squares
Shinya Kitaoka 120a6e
  std::vector<double> m_sums_xy;  //!< Sums of the coordinates products</double>
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
public:
Shinya Kitaoka 120a6e
  StandardDeviationEvaluator(const iterator_type &begin,
Shinya Kitaoka 120a6e
                             const iterator_type &end);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  penalty_type penalty(const iterator_type &a, const iterator_type &b);
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const iterator_type &begin() const { return m_begin; }
Shinya Kitaoka 120a6e
  const iterator_type &end() const { return m_end; }
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
  const std::vector<double> &sums_x() const { return m_sums_x; }</double>
Shinya Kitaoka 120a6e
  const std::vector<double> &sums_y() const { return m_sums_y; }</double>
Shinya Kitaoka 120a6e
  const std::vector<double> &sums2_x() const { return m_sums2_x; }</double>
Shinya Kitaoka 120a6e
  const std::vector<double> &sums2_y() const { return m_sums2_y; }</double>
Shinya Kitaoka 120a6e
  const std::vector<double> &sums_xy() const { return m_sums_xy; }</double>
Toshihiro Shimizu 890ddd
};
Toshihiro Shimizu 890ddd
}
Shinya Kitaoka 120a6e
}  // namespace tcg::polyline_ops
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifdef INCLUDE_HPP
Toshihiro Shimizu 890ddd
#include "hpp/polyline_ops.hpp"
Toshihiro Shimizu 890ddd
#endif
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // TCG_POLYLINE_OPS