ScanlineFilling.h
#include
#include
class ScanlineFilling
{
public:
class Edge {
public:
int x1, y1, x2, y2, dx, dy;
Edge(int x1, int y1, int x2, int y2);
};
private:
std::vector<Edge> edgeTable;
int getYmin();
int getYmax();
bool isActive(Edge edge, int currentY);
void updateActiveEdges(std::vector<Edge>& activeEdges, int y);
void findIntersections(std::vector<int>& intersections, std::vector <Edge> activeEdges, int currentY);
public:
void fill(int** matrix, int x, int y, int** position, int len, int fillValue);
};
ScanlineFilling.cpp
#include "ScanlineFilling.h"
#include
#include
#include
using namespace std;
ScanlineFilling::Edge::Edge(int x1, int y1, int x2, int y2) {
this->x1 = x1;
this->y1 = y1;
this->x2 = x2;
this->y2 = y2;
this->dx = x2 - x1;
this->dy = y2 - y1;
}
int ScanlineFilling::getYmin() {
int yMin = edgeTable.front().y1;
for (Edge edge : edgeTable) {
if (edge.y1 < yMin)
yMin = edge.y1;
}
return yMin;
}
int ScanlineFilling::getYmax() {
int yMax = edgeTable.front().y1;
for (Edge edge : edgeTable) {
if (edge.y1 > yMax)
yMax = edge.y1;
}
return yMax;
}
bool ScanlineFilling::isActive(Edge edge, int currentY) {
return edge.y1 < currentY && currentY <= edge.y2 || edge.y1 >= currentY && currentY > edge.y2;
}
void ScanlineFilling::updateActiveEdges(std::vector<Edge>& activeEdges, int y) {
for (Edge edge : edgeTable) {
if (isActive(edge, y)) {
activeEdges.push_back(edge);
}
}
}
void ScanlineFilling::findIntersections(std::vector<int>& intersections, std::vector<Edge> activeEdges, int currentY) {
for (Edge edge : activeEdges) {
int x = edge.x1 + ((currentY - edge.y1) * (edge.dx)) / (edge.dy);
intersections.push_back(x);
}
}
void ScanlineFilling::fill(int** matrix, int x, int y, int** position, int len,int fillValue) {
vector<Edge> activeEdges;
vector<int> intersections;
int firstX, firstY;
edgeTable.clear();
for (int i = 0; i < len; i++) {
if (i == 0) {
firstX = position[i][0];
firstY = position[i][1];
continue;
}
edgeTable.push_back(*(new Edge(firstX, firstY, position[i][0], position[i][1])));
firstX = position[i][0];
firstY = position[i][1];
}
int yMin = getYmin();
int yMax = getYmax();
for (int y = yMin; y < yMax; y++) {
activeEdges.clear();
intersections.clear();
updateActiveEdges(activeEdges, y);
findIntersections(intersections, activeEdges, y);
sort(intersections.begin(),intersections.end());
for (int i = 0; i < intersections.size(); i += 2) {
int x1 = intersections[i];
if ((i + 1) >= intersections.size()) {
break;
}
int x2 = intersections[i + 1];
for (int k = x1; k < x2; k++) {
matrix[k][y] = fillValue;
}
}
}
}
二维矩阵填充测试:
int main() {
int** matrix = new int* [10];
for (int i = 0; i < 10; i++) {
matrix[i] = new int[10];
for (int j = 0; j < 10; j++) {
matrix[i][j] = 0;
}
}
int** position = new int* [4];
position[0] = new int[2];
position[1] = new int[2];
position[2] = new int[2];
position[3] = new int[2];
position[0][0] = 2;
position[0][1] = 2;
position[1][0] = 2;
position[1][1] = 8;
position[2][0] = 8;
position[2][1] = 7;
position[3][0] = 2;
position[3][1] = 2;
ScanlineFilling* sc = new ScanlineFilling();
sc->fill(matrix, 10, 10, position, 4, 1);
for (int i = 0; i < 10; i++) {
for (int j = 0; j < 10; j++) {
cout << matrix[i][j] << " ";
}
cout << endl;
}
return 0;
}
![c++ 扫描线填充算法实现,对 DEM 数据进行置平_第1张图片](http://img.e-com-net.com/image/info8/f621493fb75e4138a414cb061edc1ce7.jpg)
对 DEM 数据进行置平
ScanlineFilling* sc = new ScanlineFilling();
sc->fill(greyValue, X, Y, position, pointCount, minGreyValue);
填充结果:
![c++ 扫描线填充算法实现,对 DEM 数据进行置平_第2张图片](http://img.e-com-net.com/image/info8/838a484af7e74b698f199a60d365e9e1.jpg)
![c++ 扫描线填充算法实现,对 DEM 数据进行置平_第3张图片](http://img.e-com-net.com/image/info8/f503356d5e094b2ba55732c7d57f35eb.jpg)
![c++ 扫描线填充算法实现,对 DEM 数据进行置平_第4张图片](http://img.e-com-net.com/image/info8/438cf09c92374befa4a2c06bb4d88d96.jpg)
![c++ 扫描线填充算法实现,对 DEM 数据进行置平_第5张图片](http://img.e-com-net.com/image/info8/194467411b204672a9b361cdd55b27e4.jpg)