Shinya Kitaoka 810553
#pragma once
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#ifndef RASTER_EDGE_EVALUATOR_HPP
Toshihiro Shimizu 890ddd
#define RASTER_EDGE_EVALUATOR_HPP
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#include "raster_edge_evaluator.h"
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//*******************************************************************************
Toshihiro Shimizu 890ddd
//    Raster Edge Evaluator implementation
Toshihiro Shimizu 890ddd
//*******************************************************************************
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename ranit=""></typename>
Shinya Kitaoka 120a6e
RasterEdgeEvaluator<ranit>::RasterEdgeEvaluator(const iterator_type &begin,</ranit>
Shinya Kitaoka 120a6e
                                                const iterator_type &end,
Shinya Kitaoka 120a6e
                                                double tolerance,
Shinya Kitaoka 120a6e
                                                double maxLength)
Shinya Kitaoka 120a6e
    : tcg::polyline_ops::StandardDeviationEvaluator<ranit>(begin, end)</ranit>
Shinya Kitaoka 120a6e
    , m_tolerance(tolerance)
Shinya Kitaoka 120a6e
    , m_maxLength(maxLength) {}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename ranit=""></typename>
Toshihiro Shimizu 890ddd
typename RasterEdgeEvaluator<ranit>::penalty_type</ranit>
Shinya Kitaoka 120a6e
RasterEdgeEvaluator<ranit>::penalty(const iterator_type &a,</ranit>
Shinya Kitaoka 120a6e
                                    const iterator_type &b) {
Shinya Kitaoka 120a6e
  return tcg::point_ops::norm(*b - *a) *
Shinya Kitaoka 120a6e
         tcg::polyline_ops::StandardDeviationEvaluator<ranit>::penalty(a, b);</ranit>
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
//--------------------------------------------------------------------------
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
template <typename ranit=""></typename>
Toshihiro Shimizu 890ddd
typename RasterEdgeEvaluator<ranit>::iterator_type</ranit>
Shinya Kitaoka 120a6e
RasterEdgeEvaluator<ranit>::furthestFrom(const iterator_type &start) {</ranit>
Shinya Kitaoka 120a6e
  // Build the furthest possible forward difference for every vertex between
Shinya Kitaoka 120a6e
  // begin and end.
Shinya Kitaoka 120a6e
  point_type displace, oldDisplace;
Shinya Kitaoka 120a6e
  point_type leftConstraint, rightConstraint;
Shinya Kitaoka 120a6e
  point_type newLeftConstraint, newRightConstraint;
Shinya Kitaoka 120a6e
  point_type leftDirConstr, rightDirConstr, dir, oldDir;
Shinya Kitaoka 120a6e
  iterator_type it = start, jt;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  const double sqMaxLength = sq(m_maxLength);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  // Initialize search
Shinya Kitaoka 120a6e
  leftConstraint = rightConstraint = point_type();
Shinya Kitaoka 120a6e
  leftDirConstr = rightDirConstr = point_type();
Shinya Kitaoka 120a6e
  oldDir = oldDisplace = point_type();
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (it != this->m_begin) --it;  // Chop left
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  jt = it;
Shinya Kitaoka 120a6e
  for (++jt; jt != this->m_end; ++jt) {
Shinya Kitaoka 120a6e
    // Retrieve displacement from *it
Shinya Kitaoka 120a6e
    displace = point_type(jt->x - it->x, jt->y - it->y);
Shinya Kitaoka 120a6e
    dir = point_type(displace.x - oldDisplace.x, displace.y - oldDisplace.y);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Max length
Shinya Kitaoka 120a6e
    if (oldDir.x != 0 || oldDir.y != 0) {
Shinya Kitaoka 120a6e
      if (sq(displace.x) + sq(displace.y) > sqMaxLength) break;
Shinya Kitaoka 120a6e
    } else
Shinya Kitaoka 120a6e
      leftDirConstr = rightDirConstr = dir;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Test displacement against the oldDisplacement. If it's reversing the
Shinya Kitaoka 120a6e
    // direction, make it invalid.
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (cross(oldDir, dir) > 0) leftDirConstr = dir;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (cross(oldDir, dir) < 0) rightDirConstr = dir;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    // Test constraints
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    /*if(cross(rightDirConstr, leftDirConstr) <= 0 &&
Shinya Kitaoka 120a6e
leftDirConstr * rightDirConstr < 0)
Shinya Kitaoka 120a6e
break;*/
Shinya Kitaoka 120a6e
    if (cross(rightDirConstr, leftDirConstr) < 0) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (cross(displace, leftConstraint) < 0) break;
Shinya Kitaoka 120a6e
    if (cross(displace, rightConstraint) > 0) break;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    if (std::max({displace.x, -displace.x, displace.y, -displace.y}) >
Shinya Kitaoka 120a6e
        m_tolerance) {
Shinya Kitaoka 120a6e
      // Update m_tolerance constraints
Shinya Kitaoka 120a6e
      newLeftConstraint.x =
Shinya Kitaoka 120a6e
          displace.x + (displace.y < 0 || (displace.y == 0 && displace.x < 0)
Shinya Kitaoka 120a6e
                            ? m_tolerance
Shinya Kitaoka 120a6e
                            : -m_tolerance);
Shinya Kitaoka 120a6e
      newLeftConstraint.y =
Shinya Kitaoka 120a6e
          displace.y + (displace.x > 0 || (displace.x == 0 && displace.y < 0)
Shinya Kitaoka 120a6e
                            ? m_tolerance
Shinya Kitaoka 120a6e
                            : -m_tolerance);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (cross(newLeftConstraint, leftConstraint) >= 0)
Shinya Kitaoka 120a6e
        leftConstraint = newLeftConstraint;
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      newRightConstraint.x =
Shinya Kitaoka 120a6e
          displace.x + (displace.y > 0 || (displace.y == 0 && displace.x < 0)
Shinya Kitaoka 120a6e
                            ? m_tolerance
Shinya Kitaoka 120a6e
                            : -m_tolerance);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      newRightConstraint.y =
Shinya Kitaoka 120a6e
          displace.y + (displace.x < 0 || (displace.x == 0 && displace.y < 0)
Shinya Kitaoka 120a6e
                            ? m_tolerance
Shinya Kitaoka 120a6e
                            : -m_tolerance);
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
      if (cross(newRightConstraint, rightConstraint) <= 0)
Shinya Kitaoka 120a6e
        rightConstraint = newRightConstraint;
Shinya Kitaoka 120a6e
    }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
    oldDisplace = displace;
Shinya Kitaoka 120a6e
    oldDir      = dir;
Shinya Kitaoka 120a6e
  }
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  if (jt != this->m_end) --jt;  // Chop Right
Shinya Kitaoka 120a6e
Shinya Kitaoka 120a6e
  return start +
Shinya Kitaoka 120a6e
         std::max(
Shinya Kitaoka 120a6e
             (int)std::min(jt - start - 1, this->m_end - this->m_begin - 2), 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Shinya Kitaoka 120a6e
#endif  // RASTER_EDGE_EVALUATOR_HPP