#pragma once #include #include "point.h" #include #include #include #include "geocompute.h" #include using namespace std; struct Point2D { //double x, y; double x; // x坐标 double y; // y坐标 double z; // z坐标(默认为0,如果需要三维点则给z赋值) Point2D(double a = 0, double b = 0, double c = 0) { x = a; y = b; z = c; } // 构造函数 }; struct Line2D { //Point2D p1, p2; Point2D p1; // 起点 Point2D p2; // 终点 bool is_seg; // 是否是线段 Line2D() {}; // 默认构造函数 Line2D(Point2D a, Point2D b, bool _is_seg = true) { p1 = a; p2 = b; is_seg = _is_seg; } // 构造函数(默认是线段) }; struct Rectangle2D { Point2D vertices[4]; double area() const { double width = std::sqrt(std::pow(vertices[1].x - vertices[0].x, 2) + std::pow(vertices[1].y - vertices[0].y, 2)); double height = std::sqrt(std::pow(vertices[2].x - vertices[1].x, 2) + std::pow(vertices[2].y - vertices[1].y, 2)); return width * height; } }; class TopologicalAnalysis { public: TopologicalAnalysis(void); ~TopologicalAnalysis(void); bool isPointInLine(double* point, double* startPoint, double* endPoint,float tolerance=0.001); // 判断点是否在线上 int isPointInPolyLine(double* point, vector& lineX,vector& lineY,float tolerance=0.001); bool isPointInLine(CPoint1 point, CPoint1 startPoint, CPoint1 endPoint); //根据两点求出垂线过第三点的直线的交点 bool GetPointToLineVerticalCross(double* linePt1,double* linePt2,double* pt,double* crossPt); //判断点是否在多边形内,交点法 bool isPointInPolygon(CPoint1 point, vector polygon); //判断两条直线段是否相交 bool isLineIntersect(CPoint1 line1Start, CPoint1 line1End, CPoint1 line2Start, CPoint1 line2End); // 计算两点的欧式距离, 未实现 double getDistance(CPoint1 point1, CPoint1 point2); //计算一组CPoint1的最大X double getMaxX(vector points); //获取多边形外包矩形 bool GetBoundingBoxVertices(const vector& polygonX,const vector& polygonY,vector& rectangleX,vector& rectangleY); //计算直线与多边形的交点 int linePolygonIntersections(const Point2D& linePt1,const Point2D& linePt2,const vector& polygonX,const std::vector& polygonY,std::vector& result); /** 计算多边形最小宽度对应的边 * param: polygonX,polygonY,多边形顶点坐标(首尾坐标相同) * return: 返回线段起始点ID号 */ int getLineWithPolygonMinWidth(const vector& polygonX,const vector& polygonY); //判断点与直线的位置关系 int pointPosition(const Point2D& pt,const Line2D& line); // 判断点P是否在多边形polygon内 bool isPointInPolygon(const Point2D& P, vector& regionLons,vector& regionLats); private: // 判断两条线段是否相交 int isLineIntersecting(const Line2D& l1, const Line2D& l2, Point2D& intersection); //数学计算 private: //计算两点(向量)的点积 double dotProduct(const Point2D& p1, const Point2D& p2) { return p1.x * p2.x + p1.y * p2.y; } //计算两个点(向量)之间的差向量 Point2D subtract(const Point2D& p1, const Point2D& p2) { Point2D point; point.x = p1.x - p2.x; point.y = p1.y - p2.y; return point; } //计算向量叉积 double crossProduct(const Point2D& A, const Point2D& B, const Point2D& P) { return (B.x - A.x) * (P.y - A.y) - (B.y - A.y) * (P.x - A.x); } /* double length(const Point2D& p) { return std::sqrt(p.x * p.x + p.y * p.y); }*/ /* Point2D normalize(const Point2D& p) { double len = length(p); Point2D pt; pt.x = p.x / len; pt.y = p.y / len; return pt; }*/ private: // 点的加法 Point2D add(const Point2D& lhs, const Point2D& rhs) { Point2D res; res.x = lhs.x + rhs.x; res.y = lhs.y + rhs.y; res.z = lhs.z + rhs.z; return res; } // 点的减法 Point2D sub(const Point2D& lhs, const Point2D& rhs) { Point2D res; res.x = lhs.x - rhs.x; res.y = lhs.y - rhs.y; res.z = lhs.z - rhs.z; return res; } // 向量的乘法 Point2D mul(const Point2D& p, double ratio) { Point2D res; res.x = p.x * ratio; res.y = p.y * ratio; res.z = p.z * ratio; return res; } // 向量的除法 Point2D div(const Point2D& p, double ratio) { Point2D res; res.x = p.x / ratio; res.y = p.y / ratio; res.z = p.z / ratio; return res; } // 点判断相等 bool equal(const Point2D& lhs, const Point2D& rhs) { return(lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z); } // 1.3、矢量标准化(矢量的长度规约到1) // // 参数: vec : 矢量 // Point2D normalize(const Point2D& vec) { Point2D res; res = div(vec, length(vec)); return res; } // 1.9、点是否在线上 // 线分为直线和线段,直线表示的是直线是否经过点 // // 参数:p : 点 l : 线段或者线 // bool isponl(const Point2D& p, const Line2D& l) { Point2D line_vec = sub(l.p2, l.p1); Point2D point_vec1 = sub(p, l.p1); Point2D point_vec2 = sub(p, l.p2); Point2D mul_vec = multiply(line_vec, point_vec1); double dot = dotMultiply(point_vec1, point_vec2); // 点是否在线段上 if (l.is_seg) { if (equal(p, l.p1) || equal(p, l.p2)) return true; return (0.0 == length(mul_vec) && dot < 0.0); } // 点是否在直线上 else { return (0.0 == length(mul_vec)); } } // 1.4、矢量点乘 // // 参数:(p1-op)为矢量1,(p2-op)为矢量2 // double dotMultiply(const Point2D& op, const Point2D& p1, const Point2D& p2) { return ((p1.x - op.x) * (p2.x - op.x) + (p1.y - op.y) * (p2.y - op.y) + (p1.z - op.z) * (p2.z - op.z)); } // 参数:vec1为矢量1,vec2为矢量2 // double dotMultiply(const Point2D& vec1, const Point2D& vec2) { return(vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z); } // 1.5、矢量叉乘 // // 参数:(p1-op)为矢量1,(p2-op)为矢量2 // Point2D multiply(const Point2D& op, const Point2D& p1, const Point2D& p2) { Point2D result; result.x = (p1.y - op.y) * (p2.z - op.z) - (p2.y - op.y) * (p1.z - op.z); result.y = (p1.z - op.z) * (p2.x - op.x) - (p2.z - op.z) * (p1.x - op.x); result.z = (p1.x - op.x) * (p2.y - op.y) - (p2.x - op.x) * (p1.y - op.y); return result; } // 参数: vec1为矢量1,vec2为矢量2 // Point2D multiply(const Point2D& vec1, const Point2D& vec2) { Point2D result; result.x = vec1.y * vec2.z - vec2.y * vec1.z; result.y = vec1.z * vec2.x - vec2.z * vec1.x; result.z = vec1.x * vec2.y - vec2.x * vec1.y; return result; } // 参数: vec1 矢量1 vec2 矢量2 // double Cos(const Point2D& vec1, const Point2D& vec2) { Point2D unit_vec1 = normalize(vec1); Point2D unit_vec2 = normalize(vec2); return dotMultiply(unit_vec1, unit_vec2); } // 1.2、矢量的长度 // // 参数: vec 矢量 // double length(const Point2D& vec) { return (sqrt(pow(vec.x, 2) + pow(vec.y, 2) + pow(vec.z, 2))); } // 计算两点之间的向量 Point2D mathVector(const Point2D& p1, const Point2D& p2) { Point2D pt; pt.x = p2.x - p1.x; pt.y = p2.y - p1.y; return pt; } // 计算两点之间的叉积 double crossProduct(const Point2D& p1, const Point2D& p2) { return p1.x * p2.y - p1.y * p2.x; } //直线与线段的交点 bool findIntersection(double x1, double y1, double x2, double y2, // 直线1的两个点 double x3, double y3, double x4, double y4,Point2D& intersection); };