You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
GCS-GISControlDlg-for-981A-.../TopologicalAnalysis.h

297 lines
7.2 KiB
C++

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

#pragma once
#include <vector>
#include "point.h"
#include <cmath>
#include <algorithm>
#include <limits>
#include "geocompute.h"
#include <cstdint>
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<double>& lineX,vector<double>& 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<CPoint1> polygon);
//判断两条直线段是否相交
bool isLineIntersect(CPoint1 line1Start, CPoint1 line1End, CPoint1 line2Start, CPoint1 line2End);
// 计算两点的欧式距离, 未实现
double getDistance(CPoint1 point1, CPoint1 point2);
//计算一组CPoint1的最大X
double getMaxX(vector<CPoint1> points);
//获取多边形外包矩形
bool GetBoundingBoxVertices(const vector<double>& polygonX,const vector<double>& polygonY,vector<double>& rectangleX,vector<double>& rectangleY);
//计算直线与多边形的交点
int linePolygonIntersections(const Point2D& linePt1,const Point2D& linePt2,const vector<double>& polygonX,const std::vector<double>& polygonY,std::vector<Point2D>& result);
/** 计算多边形最小宽度对应的边
* param: polygonX,polygonY,多边形顶点坐标(首尾坐标相同)
* return: 返回线段起始点ID号
*/
int getLineWithPolygonMinWidth(const vector<double>& polygonX,const vector<double>& polygonY);
//判断点与直线的位置关系
int pointPosition(const Point2D& pt,const Line2D& line);
// 判断点P是否在多边形polygon内
bool isPointInPolygon(const Point2D& P, vector<double>& regionLons,vector<double>& 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)为矢量1p2-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为矢量1vec2为矢量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)为矢量1p2-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为矢量1vec2为矢量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);
};