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>
Toshihiro Shimizu 890ddd
RasterEdgeEvaluator<ranit>::RasterEdgeEvaluator(</ranit>
Toshihiro Shimizu 890ddd
	const iterator_type &begin, const iterator_type &end,
Toshihiro Shimizu 890ddd
	double tolerance, double maxLength)
Toshihiro Shimizu 890ddd
	: tcg::polyline_ops::StandardDeviationEvaluator<ranit>(begin, end), m_tolerance(tolerance), m_maxLength(maxLength)</ranit>
Toshihiro Shimizu 890ddd
{
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>::penalty_type</ranit>
Toshihiro Shimizu 890ddd
RasterEdgeEvaluator<ranit>::penalty(const iterator_type &a, const iterator_type &b)</ranit>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	return tcg::point_ops::norm(*b - *a) * 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>
Toshihiro Shimizu 890ddd
RasterEdgeEvaluator<ranit>::furthestFrom(const iterator_type &start)</ranit>
Toshihiro Shimizu 890ddd
{
Toshihiro Shimizu 890ddd
	//Build the furthest possible forward difference for every vertex between begin and end.
Toshihiro Shimizu 890ddd
	point_type displace, oldDisplace;
Toshihiro Shimizu 890ddd
	point_type leftConstraint, rightConstraint;
Toshihiro Shimizu 890ddd
	point_type newLeftConstraint, newRightConstraint;
Toshihiro Shimizu 890ddd
	point_type leftDirConstr, rightDirConstr, dir, oldDir;
Toshihiro Shimizu 890ddd
	iterator_type it = start, jt;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	const double sqMaxLength = sq(m_maxLength);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	//Initialize search
Toshihiro Shimizu 890ddd
	leftConstraint = rightConstraint = point_type();
Toshihiro Shimizu 890ddd
	leftDirConstr = rightDirConstr = point_type();
Toshihiro Shimizu 890ddd
	oldDir = oldDisplace = point_type();
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (it != this->m_begin)
Toshihiro Shimizu 890ddd
		--it; //Chop left
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	jt = it;
Toshihiro Shimizu 890ddd
	for (++jt; jt != this->m_end; ++jt) {
Toshihiro Shimizu 890ddd
		//Retrieve displacement from *it
Toshihiro Shimizu 890ddd
		displace = point_type(jt->x - it->x, jt->y - it->y);
Toshihiro Shimizu 890ddd
		dir = point_type(displace.x - oldDisplace.x, displace.y - oldDisplace.y);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Max length
Toshihiro Shimizu 890ddd
		if (oldDir.x != 0 || oldDir.y != 0) {
Toshihiro Shimizu 890ddd
			if (sq(displace.x) + sq(displace.y) > sqMaxLength)
Toshihiro Shimizu 890ddd
				break;
Toshihiro Shimizu 890ddd
		} else
Toshihiro Shimizu 890ddd
			leftDirConstr = rightDirConstr = dir;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Test displacement against the oldDisplacement. If it's reversing the
Toshihiro Shimizu 890ddd
		//direction, make it invalid.
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (cross(oldDir, dir) > 0)
Toshihiro Shimizu 890ddd
			leftDirConstr = dir;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (cross(oldDir, dir) < 0)
Toshihiro Shimizu 890ddd
			rightDirConstr = dir;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		//Test constraints
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		/*if(cross(rightDirConstr, leftDirConstr) <= 0 &&
Toshihiro Shimizu 890ddd
       leftDirConstr * rightDirConstr < 0)
Toshihiro Shimizu 890ddd
      break;*/
Toshihiro Shimizu 890ddd
		if (cross(rightDirConstr, leftDirConstr) < 0)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (cross(displace, leftConstraint) < 0)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
		if (cross(displace, rightConstraint) > 0)
Toshihiro Shimizu 890ddd
			break;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		if (tmax(displace.x, -displace.x, displace.y, -displace.y) > m_tolerance) {
Toshihiro Shimizu 890ddd
			//Update m_tolerance constraints
Toshihiro Shimizu 890ddd
			newLeftConstraint.x = displace.x +
Toshihiro Shimizu 890ddd
								  (displace.y < 0 || (displace.y == 0 && displace.x < 0) ? m_tolerance : -m_tolerance);
Toshihiro Shimizu 890ddd
			newLeftConstraint.y = displace.y +
Toshihiro Shimizu 890ddd
								  (displace.x > 0 || (displace.x == 0 && displace.y < 0) ? m_tolerance : -m_tolerance);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (cross(newLeftConstraint, leftConstraint) >= 0)
Toshihiro Shimizu 890ddd
				leftConstraint = newLeftConstraint;
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			newRightConstraint.x = displace.x +
Toshihiro Shimizu 890ddd
								   (displace.y > 0 || (displace.y == 0 && displace.x < 0) ? m_tolerance : -m_tolerance);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			newRightConstraint.y = displace.y +
Toshihiro Shimizu 890ddd
								   (displace.x < 0 || (displace.x == 0 && displace.y < 0) ? m_tolerance : -m_tolerance);
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
			if (cross(newRightConstraint, rightConstraint) <= 0)
Toshihiro Shimizu 890ddd
				rightConstraint = newRightConstraint;
Toshihiro Shimizu 890ddd
		}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
		oldDisplace = displace;
Toshihiro Shimizu 890ddd
		oldDir = dir;
Toshihiro Shimizu 890ddd
	}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	if (jt != this->m_end)
Toshihiro Shimizu 890ddd
		--jt; //Chop Right
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
	return start + tmax((int)tmin(jt - start - 1, this->m_end - this->m_begin - 2), 1);
Toshihiro Shimizu 890ddd
}
Toshihiro Shimizu 890ddd
Toshihiro Shimizu 890ddd
#endif // RASTER_EDGE_EVALUATOR_HPP