#include "stdafx.h" #include "topologicalanalysis.h" TopologicalAnalysis::TopologicalAnalysis(void) { } TopologicalAnalysis::~TopologicalAnalysis(void) { } bool TopologicalAnalysis::isPointInLine(double* point, double* startPoint, double* endPoint,float tolerance) { double AX = startPoint[0]; double AY = startPoint[1]; double BX = endPoint[0]; double BY = endPoint[1]; double PX = point[0]; double PY = point[1]; double dx_AB = AX - BX; double dy_AB = AY - BY; double dx_PA = PX - AX; double dy_PA = PY - AY; double dx_PB = PX - BX; double dy_PB = PY - BY; double AB = sqrt(dx_AB*dx_AB + dy_AB*dy_AB); double PA = sqrt(dx_PA*dx_PA + dy_PA*dy_PA); double PB = sqrt(dx_PB*dx_PB + dy_PB*dy_PB); double rate = abs(PA + PB - AB) / AB; if (rate < tolerance) { return true; } else { return false; } } //判断线是否在折线上 int TopologicalAnalysis::isPointInPolyLine(double* point, vector& lineX,vector& lineY,float tolerance) { int lineNum = lineX.size(); double startPoint[2],endPoint[2]; for (int i=0;i polygon){ if (polygon.size()<=3) return false; // 一个有效多边形顶点数应大于3 int LineNum = polygon.size(); CPoint1 leftP = point; CPoint1 rightP; rightP.SetX(getMaxX(polygon) + 1); rightP.SetY(point.GetY()); int count = 0, yPrev = polygon[LineNum - 2].GetY(); CPoint1 v1, v2; v1 = polygon[LineNum - 1]; for (int i = 0; i < LineNum; i++) { v2 = polygon[i]; if (isPointInLine(leftP, v1, v2)) return true; if (v1.GetY() != v2.GetY()) { if (isLineIntersect(v1, v2, leftP, rightP)) { if (isPointInLine(v1, leftP, rightP)) { if (v1.GetY()yPrev) count++; } else { if (v1.GetY() < yPrev) count++; } } else if (!isPointInLine(v2, leftP, rightP)) { count++; } } } yPrev = v1.GetY(); v1 = v2; } return (count % 2 == 1); } double TopologicalAnalysis::getMaxX(vector points){ if (points.size()==0) return -1; else if(points.size()==1) return points[0].GetX(); else{ double maxx = points[0].GetX(); for (unsigned i=1; imaxx){ maxx = points[i].GetX(); } } return maxx; } } bool TopologicalAnalysis::isPointInLine(CPoint1 point, CPoint1 startPoint, CPoint1 endPoint) { long AX = startPoint.GetX(); long AY = startPoint.GetY(); long BX = endPoint.GetX(); long BY = endPoint.GetY(); long PX = point.GetX(); long PY = point.GetY(); double dx_AB = AX - BX; double dy_AB = AY - BY; double dx_PA = PX - AX; double dy_PA = PY - AY; double dx_PB = PX - BX; double dy_PB = PY - BY; double AB = sqrt(dx_AB*dx_AB + dy_AB*dy_AB); double PA = sqrt(dx_PA*dx_PA + dy_PA*dy_PA); double PB = sqrt(dx_PB*dx_PB + dy_PB*dy_PB); double rate = abs(PA + PB - AB) / AB; if (rate < 0.001) { return true; } else { return false; } } // 叉积 double mult(CPoint1 a, CPoint1 b, CPoint1 c) { return (a.GetX()-c.GetX())*(b.GetY()-c.GetY())-(b.GetX()-c.GetX())*(a.GetY()-c.GetY()); } //判断两条直线段是否相交 bool TopologicalAnalysis::isLineIntersect(CPoint1 line1Start, CPoint1 line1End, CPoint1 line2Start, CPoint1 line2End){ double l1sx = line1Start.GetX(); double l1sy = line1Start.GetY(); double l1ex = line1End.GetX(); double l1ey = line1End.GetY(); double l2sx = line2Start.GetX(); double l2sy = line2Start.GetY(); double l2ex = line2End.GetX(); double l2ey = line2End.GetY(); if ( max(l1sx, l1ex)& polygonX,const vector& polygonY,vector& rectangleX,vector& rectangleY) { if (polygonX.size()<3 || polygonY.size()<3) return false; //计算最大最小x和y double minX = polygonX[0]; double minY = polygonY[0]; double maxX = polygonX[0]; double maxY = polygonY[0]; for (int i=0;i maxX) maxX = polygonX[i]; if (polygonY[i] > maxY) maxY = polygonY[i]; } rectangleX.push_back(minX); rectangleX.push_back(maxX); rectangleX.push_back(maxX); rectangleX.push_back(minX); rectangleY.push_back(maxY); rectangleY.push_back(maxY); rectangleY.push_back(minY); rectangleY.push_back(minY); } //计算直线与多边形的交点 void TopologicalAnalysis::linePolygonIntersections(const Point2D& linePt1,const Point2D& linePt2,const vector& polygonX,const vector& polygonY, vector& result) { Line2D line1; line1.p1 = linePt1; line1.p2 = linePt2; Point2D intersectionPt; vector resPoints; for (int i=0;i0) { //获取最左或者最右的两个点,忽略凹多边形中间交点 double minX = resPoints[0].x; double maxX = resPoints[0].x; int minIndex = 0; int maxIndex = 0; for (int i=0;i maxX) maxIndex = i; } result.push_back(resPoints[minIndex]); result.push_back(resPoints[maxIndex]); } } // 判断两条线段是否相交 int TopologicalAnalysis::isLineIntersecting(const Line2D& l1, const Line2D& l2, Point2D& intersection) { float numera = (l2.p2.x-l2.p1.x) * (l1.p1.y-l2.p1.y) - (l2.p2.y-l2.p1.y) * (l1.p1.x-l2.p1.x); float numerb = (l1.p2.x-l1.p1.x) * (l1.p1.y-l2.p1.y) - (l1.p2.y-l1.p1.y) * (l1.p1.x-l2.p1.x); float denom = (l2.p2.y-l2.p1.y) * (l1.p2.x-l1.p1.x) - (l2.p2.x-l2.p1.x) * (l1.p2.y-l1.p1.y); if(denom == 0.0f) { if(numera == 0.0f && numerb == 0.0f) { intersection.x = l2.p2.x; intersection.y = l2.p2.y; return 2; //重合 } return 3; //平行 } float ua = numera / denom; float ub = numerb / denom; if(ua >= 0.0f && ua <= 1.0f && ub >= 0.0f && ub <= 1.0f) { intersection.x = l1.p1.x + ua*(l1.p2.x - l1.p1.x); intersection.y = l1.p1.y + ua*(l1.p2.y - l1.p1.y); return 1; //相交 } return 0; //不相交 }