|
|
#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)为矢量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);
|
|
|
|
|
|
};
|
|
|
|
|
|
|