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 edgeTable; int getYmin(); int getYmax(); bool isActive(Edge edge, int currentY); void updateActiveEdges(std::vector & activeEdges, int y); void findIntersections(std::vector & intersections, std::vector activeEdges, int currentY); public: // 多边形填充 // 参数:matrix: 要填充的二维数组, // x,y: 数组的行列, // position: 多边形的坐标[x,y], // len: 多边形坐标的个数(从起点到终点的个数,其中起点==终点), // fillValue: 填充的值 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 & activeEdges, int y) { for (Edge edge : edgeTable) { if (isActive(edge, y)) { activeEdges.push_back(edge); } } } void ScanlineFilling::findIntersections(std::vector & intersections, std::vector activeEdges, int currentY) { for (Edge edge : activeEdges) { int x = edge.x1 + ((currentY - edge.y1) * (edge.dx)) / (edge.dy); intersections.push_back(x); } } // 多边形填充 // 参数:matrix: 要填充的二维数组, // x,y: 数组的行列, // position: 多边形的坐标[x,y], // len: 多边形坐标的个数(从起点到终点的个数,其中起点==终点), // fillValue: 填充的值 void ScanlineFilling::fill(int** matrix, int x, int y, int** position, int len,int fillValue) { vector activeEdges; vector 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;
}
对 DEM 数据进行置平
ScanlineFilling* sc = new ScanlineFilling(); // greyValue: dem 高程值二维矩阵 // X,Y: dem 高程值二维矩阵在 x(lat),y(lon)方向上的像素个数 // position: 要填充的多边形的坐标(第一个点和最后一个点相同), // 用 shp 文件置平,经纬度要转换为 dem 高程值的索引位置 // pointCount: 多边形坐标个数, position.length // minGreyValue: 要填充的高程值 sc->fill(greyValue, X, Y, position, pointCount, minGreyValue);填充结果:



