|
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
|