#include "stdafx.h" #include "simplegrid.h" #include #include using namespace std; CSimpleGrid::CSimpleGrid(void) { m_numx=0; //列数 m_numy=0; //行数 m_x0=0; //起点x0 m_y0=0; //起点y0 m_dx=0; //x步长 m_dy=0; //y步长 } CSimpleGrid::~CSimpleGrid(void) { Clear(); } void CSimpleGrid::Clear(void) { m_numx = 0; //列数 m_numy = 0; //行数 m_x0 = 0; //起点x0 m_y0 = 0; //起点y0 m_dx = 0; //x步长 m_dy = 0; //y步长 m_points.clear(); delete[]m_nodePointsArray; } double CSimpleGrid::X(int i) { return m_x0 + i * m_dx; } double CSimpleGrid::Y(int j) { return m_y0 + j * m_dy; } void CSimpleGrid::Create(double x0, double y0, double dx, double dy, int xnum, int ynum) { Clear(); m_x0 = x0; m_y0 = y0; m_dx = dx; m_dy = dy; m_numx = xnum; m_numy = ynum; m_deltS = pow(std::min(m_dx, m_dy), 2.0); m_nodePointsArray = new vector[m_numx*m_numy]; } void CSimpleGrid::WriteGridLines(CString strout) { FILE* fw = fopen(strout, "w"); double x1, y1, x2, y2; for (int j = 0; j < ynum(); j++) { x1 = m_x0; y1 = Y(j); x2 = X(xnum() - 1); y2 = y1; fprintf(fw, "Pline\n"); fprintf(fw, "%.12g,%.12g\n", x1, y1); fprintf(fw, "%.12g,%.12g\n", x2, y2); fprintf(fw, "\n"); } for (int i = 0; i < xnum(); i++) { x1 = X(i); y1 = m_y0; x2 = x1; y2 = Y(ynum()-1); fprintf(fw, "Pline\n"); fprintf(fw, "%.12g,%.12g\n", x1, y1); fprintf(fw, "%.12g,%.12g\n", x2, y2); fprintf(fw, "\n"); } fclose(fw); } void CSimpleGrid::ReadPoints(const vector& pts) { m_points.assign(pts.begin(),pts.end() ); CPointXYZ pt; int ix = 0; int iy = 0; int NX = xnum(); int NY = ynum(); int idx = -1; for (int i = 0; i < pts.size(); i++) { pt = pts[i]; ix = std::floor((pt.x0 - m_x0) / m_dx + 1e-8); iy = std::floor((pt.y0 - m_y0) / m_dy + 1e-8); if (ix < 0 || iy < 0) continue; if (ix > NX - 2 && ix < NX) ix = NX - 2; if (iy > NY - 2 && iy < NY) iy = NY - 2; idx = GetNodeIndex(ix, iy); m_nodePointsArray[idx].push_back(i); } } int CSimpleGrid::GetNodeIndex(int ix, int iy) { if (ix > xnum() - 1 || iy > ynum() - 1) return -1; return iy*xnum() + ix; } vector& CSimpleGrid::GetNodePointsVec(int ix, int iy) { int idx = GetNodeIndex(ix, iy); if (idx < 0) { static vector tmp; return tmp; } return m_nodePointsArray[idx]; } //每个格子最多保留1-2个点, void CSimpleGrid::SimplifyNodePointsArray() { for (int j = 0; j < ynum() - 1; j++) { for (int i = 0; i < xnum() - 1; i++) { SimplifySeedGrid(i, j); SimplifyNeighborGrid(i, j, i + 1, j); SimplifyNeighborGrid(i, j, i + 1, j+1); SimplifyNeighborGrid(i, j, i, j+1); SimplifyNeighborGrid(i, j, i - 1, j + 1); } } } //查找距离(x0,y0)最近的点,返回序号 int CSimpleGrid::GetNearestPoint(double x0, double y0, vector& pts, double* distance) { int idx = pts[0]; CPointXYZ pt = m_points[idx]; double dist2; double mindist2 = pt.GetDist2(x0, y0); int minidx = idx; for (int i = 1; i < pts.size(); i++) { idx = pts[i]; pt = m_points[idx]; dist2 = pt.GetDist2(x0, y0); if (dist2 < mindist2) { mindist2 = dist2; minidx = idx; } } if(distance) *distance = sqrt(mindist2); return minidx; } //查找距离(x0,y0)最远的点,返回序号,和距离distance int CSimpleGrid::GetFarthestPoint(double x0, double y0, vector& pts, double* distance) { int idx = pts[0]; CPointXYZ pt = m_points[idx]; double dist2; double maxdist2 = pt.GetDist2(x0, y0); int maxidx = idx; for (int i = 1; i < pts.size(); i++) { idx = pts[i]; pt = m_points[idx]; dist2 = pt.GetDist2(x0, y0); if (dist2 > maxdist2) { maxdist2 = dist2; maxidx = idx; } } if (distance) *distance = sqrt(maxdist2); return maxidx; } void CSimpleGrid::SimplifySeedGrid(int ix, int iy) { vector& vec = GetNodePointsVec(ix, iy); if (vec.size() < 2) //少于两个点,返回 return; vector dstIdxes; double x0 = X(ix); double y0 = Y(iy); double distance = 0; int seedPt = GetNearestPoint(x0, y0, vec); dstIdxes.push_back(seedPt); x0 = m_points[seedPt].x0; y0 = m_points[seedPt].y0; //查找距离seedPt最远的点 int second = GetFarthestPoint(x0, y0, vec,&distance); if (distance > min(m_dx, m_dy)) dstIdxes.push_back(second); vec.assign(dstIdxes.begin(), dstIdxes.end()); } void CSimpleGrid::SimplifyNeighborGrid(int seedX, int seedY, int ix, int iy) { vector& seedsVec = GetNodePointsVec(seedX, seedY); if (seedsVec.empty()) return; vector& subjVec = GetNodePointsVec(ix,iy); if (subjVec.empty()) return; double x0, y0; double dist2 = 0; list sublst(subjVec.begin(), subjVec.end()); list::iterator iter; for (int j = 0; j < seedsVec.size(); j++) { if (sublst.empty()) break; x0 = m_points[seedsVec[j]].x0; y0 = m_points[seedsVec[j]].y0; ////begin test //if (int(x0 + 0.000001) == 591091 && int(y0 + 0.000001) == 5134095) //{ // TRACE("\n"); // for (auto p : sublst) // { // TRACE("%.12g,%.12g, dist = %.12g\n", m_points[p].x0 , m_points[p].y0 , // m_points[p].GetDist(x0,y0) ); // } //} ////end test iter = sublst.begin(); while (iter != sublst.end()) { dist2 = m_points[*iter].GetDist2(x0, y0); if (dist2 < m_deltS) sublst.erase(iter++); else iter++; } } subjVec.assign(sublst.begin(), sublst.end()); } void CSimpleGrid::GetAllNodePointIndexes(list& ptIndexes) // 获取所有相关点序号 { int N = xnum() *ynum(); for (int i = 0; i < N; i++) { ptIndexes.insert(ptIndexes.end(), m_nodePointsArray[i].begin(), m_nodePointsArray[i].end() ); } }