#include "stdafx.h"
#include "vectortoraster.h"

VectorToRaster::VectorToRaster(void)
{
}


VectorToRaster::~VectorToRaster(void)
{
}

/* 功能:矢量要素栅格化
*	ptsRow[in]:线段点x坐标集(行号)
*	ptsCol[in]:线段点y坐标集(列号)
*   rowList[out]: 经过的栅格行号
*   colList[out]: 经过的栅格列号
*/
void VectorToRaster::GetRasterLine(vector<int> ptsRow,vector<int> ptsCol,vector<int>& rowList,vector<int>& colList)
{
	int startRow,startCol,endRow,endCol;
	for (int i=0;i<ptsRow.size()-1;i++)
	{
		startRow = ptsRow.at(i);
		startCol = ptsCol.at(i);
		endRow = ptsRow.at(i+1);
		endCol = ptsCol.at(i+1);

		Vector2d O(startRow, startCol);
		Vector2d E(endRow, endCol);
		std::pair<Vector2d, Vector2d> line(O, E);

		vector<Vector2d> linePointList;
		RasterLine(line, linePointList);

		for (size_t i = 0; i < linePointList.size(); i++)
		{
			//cout << linePointList[i].x << ',' << linePointList[i].y << '\t';
			rowList.push_back(linePointList[i].x);
			colList.push_back(linePointList[i].y);
		}
	}
}

set<vector<int> > VectorToRaster::GetRasterLineEx(vector<int> ptsRow,vector<int> ptsCol,int row_max,int col_max,int tolerance)
{
	int startRow,startCol,endRow,endCol;
	//int piexl = tolerance;
	set<vector<int> > resultSet;
	for (int i=0;i<ptsRow.size()-1;i++)
	{
		startRow = ptsRow.at(i);
		startCol = ptsCol.at(i);
		endRow = ptsRow.at(i+1);
		endCol = ptsCol.at(i+1);

		Vector2d O(startRow, startCol);
		Vector2d E(endRow, endCol);
		std::pair<Vector2d, Vector2d> line(O, E);

		vector<Vector2d> linePointList;
		RasterLine(line, linePointList);

		for (size_t i = 0; i < linePointList.size(); i++)
		{
			ExtendGrid(linePointList[i].x,linePointList[i].y,row_max,col_max,tolerance,resultSet);
			
			//rowList.push_back(linePointList[i].x);
			//colList.push_back(linePointList[i].y);
		}
	}
	return resultSet;
}

void VectorToRaster::ExtendGrid(int cx,int cy,int x_max,int y_max,int tolerance,set<vector<int> >& resultSet)
{
	int dx = cx - tolerance;
	int dy = cy - tolerance;
	int startRow,startCol,endRow,endCol;
	if(cx < tolerance) startRow = 0;
	else startRow = cx - tolerance;
	if ((cx+tolerance)>x_max) endRow = x_max;
	else endRow = cx + tolerance;

	if(cy< tolerance) startCol = 0;
	else startCol = cy - tolerance;
	if ((cy+tolerance)>y_max) endCol = y_max;
	else endCol = cy + tolerance;

	for (int i=0;i<=(endRow-startRow);i++)
	{
		for (int j=0;j<=(endCol-startCol);j++)
		{
			vector<int> pt;
			pt.push_back(startRow+i);
			pt.push_back(startCol+j);
			resultSet.insert(pt);
			pt.clear();
		}
	}
}

void VectorToRaster::RasterLine(std::pair<Vector2d, Vector2d> line, std::vector<Vector2d>& linePointList)
{
	Vector2d vecLine = line.second - line.first;
	double lineLength = vecLine.Mod();
	double step = 1.0;

	//根据距离逐步取
	vector<Vector2d> tmpPointList;
	double curLength = 0;
	while (curLength < lineLength)
	{
		curLength = curLength + step;
		Vector2d P = line.first + vecLine.Scalar(curLength / lineLength);
		P.x = (int)(P.x + 0.5);
		P.y = (int)(P.y + 0.5);
		tmpPointList.push_back(P);
	}

	//与最后一个值比较,去重
	linePointList.push_back(line.first);
	for (size_t i = 0; i < tmpPointList.size(); i++)
	{
		//与最后一个值比较,去重
		if (!tmpPointList[i].Equel(linePointList[linePointList.size() - 1]))
		{
			linePointList.push_back(tmpPointList[i]);
		}
	}

	if (!linePointList[linePointList.size() - 1].Equel(line.second))
	{
		linePointList.push_back(line.second);
	}
}