|
|
|
|
#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<><78><EFBFBD><EFBFBD>
|
|
|
|
|
double y; // y<><79><EFBFBD><EFBFBD>
|
|
|
|
|
double z; // z<><7A><EFBFBD>꣨Ĭ<EAA3A8><C4AC>Ϊ0<CEAA><30><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҫ<EFBFBD><D2AA>ά<EFBFBD><CEAC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>z<EFBFBD><7A>ֵ<EFBFBD><D6B5>
|
|
|
|
|
|
|
|
|
|
Point2D(double a = 0, double b = 0, double c = 0) { x = a; y = b; z = c; } // <20><><EFBFBD>캯<EFBFBD><ECBAAF>
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
struct Line2D {
|
|
|
|
|
//Point2D p1, p2;
|
|
|
|
|
Point2D p1; // <20><><EFBFBD><EFBFBD>
|
|
|
|
|
Point2D p2; // <20>յ<EFBFBD>
|
|
|
|
|
bool is_seg; // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>߶<EFBFBD>
|
|
|
|
|
|
|
|
|
|
Line2D() {}; // Ĭ<>Ϲ<EFBFBD><CFB9>캯<EFBFBD><ECBAAF>
|
|
|
|
|
Line2D(Point2D a, Point2D b, bool _is_seg = true) { p1 = a; p2 = b; is_seg = _is_seg; } // <20><><EFBFBD>캯<EFBFBD><ECBAAF>(Ĭ<><C4AC><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>)
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
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);
|
|
|
|
|
|
|
|
|
|
// <20>жϵ<D0B6><CFB5>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
int isPointInPolyLine(double* point, vector<double>& lineX,vector<double>& lineY,float tolerance=0.001);
|
|
|
|
|
bool isPointInLine(CPoint1 point, CPoint1 startPoint, CPoint1 endPoint);
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߹<EFBFBD><DFB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>ߵĽ<DFB5><C4BD><EFBFBD>
|
|
|
|
|
bool GetPointToLineVerticalCross(double* linePt1,double* linePt2,double* pt,double* crossPt);
|
|
|
|
|
|
|
|
|
|
//<2F>жϵ<D0B6><CFB5>Ƿ<EFBFBD><C7B7>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD><DAA3><EFBFBD><EFBFBD>㷨
|
|
|
|
|
bool isPointInPolygon(CPoint1 point, vector<CPoint1> polygon);
|
|
|
|
|
|
|
|
|
|
//<2F>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>߶<EFBFBD><DFB6>Ƿ<EFBFBD><C7B7>ཻ
|
|
|
|
|
bool isLineIntersect(CPoint1 line1Start, CPoint1 line1End, CPoint1 line2Start, CPoint1 line2End);
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ŷʽ<C5B7><CABD><EFBFBD><EFBFBD>, δʵ<CEB4><CAB5>
|
|
|
|
|
double getDistance(CPoint1 point1, CPoint1 point2);
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>CPoint1<74><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>X
|
|
|
|
|
double getMaxX(vector<CPoint1> points);
|
|
|
|
|
|
|
|
|
|
//<2F><>ȡ<EFBFBD><C8A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
bool GetBoundingBoxVertices(const vector<double>& polygonX,const vector<double>& polygonY,vector<double>& rectangleX,vector<double>& rectangleY);
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>εĽ<CEB5><C4BD><EFBFBD>
|
|
|
|
|
int linePolygonIntersections(const Point2D& linePt1,const Point2D& linePt2,const vector<double>& polygonX,const std::vector<double>& polygonY,std::vector<Point2D>& result);
|
|
|
|
|
|
|
|
|
|
/** <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD><D0A1><EFBFBD>ȶ<EFBFBD>Ӧ<EFBFBD>ı<EFBFBD>
|
|
|
|
|
* param: polygonX,polygonY,<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ζ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(<EFBFBD><EFBFBD>β<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ)
|
|
|
|
|
* return: <EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><EFBFBD>ID<EFBFBD><EFBFBD>
|
|
|
|
|
*/
|
|
|
|
|
int getLineWithPolygonMinWidth(const vector<double>& polygonX,const vector<double>& polygonY);
|
|
|
|
|
|
|
|
|
|
//<2F>жϵ<D0B6><CFB5><EFBFBD>ֱ<EFBFBD>ߵ<EFBFBD>λ<EFBFBD>ù<EFBFBD>ϵ
|
|
|
|
|
int pointPosition(const Point2D& pt,const Line2D& line);
|
|
|
|
|
|
|
|
|
|
// <20>жϵ<D0B6>P<EFBFBD>Ƿ<EFBFBD><C7B7>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD>polygon<6F><6E>
|
|
|
|
|
bool isPointInPolygon(const Point2D& P, vector<double>& regionLons,vector<double>& regionLats);
|
|
|
|
|
private:
|
|
|
|
|
// <20>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD><DFB6>Ƿ<EFBFBD><C7B7>ཻ
|
|
|
|
|
int isLineIntersecting(const Line2D& l1, const Line2D& l2, Point2D& intersection);
|
|
|
|
|
|
|
|
|
|
//<2F><>ѧ<EFBFBD><D1A7><EFBFBD><EFBFBD>
|
|
|
|
|
private:
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣨<EFBFBD><E3A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD><C4B5><EFBFBD>
|
|
|
|
|
double dotProduct(const Point2D& p1, const Point2D& p2) {
|
|
|
|
|
return p1.x * p2.x + p1.y * p2.y;
|
|
|
|
|
}
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㣨<EFBFBD><E3A3A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
Point2D subtract(const Point2D& p1, const Point2D& p2) {
|
|
|
|
|
Point2D point;
|
|
|
|
|
point.x = p1.x - p2.x;
|
|
|
|
|
point.y = p1.y - p2.y;
|
|
|
|
|
return point;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//<2F><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
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:
|
|
|
|
|
// <20><><EFBFBD>ļӷ<C4BC>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
// <20><><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ij˷<C4B3>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><C4B3><EFBFBD>
|
|
|
|
|
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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
bool equal(const Point2D& lhs, const Point2D& rhs)
|
|
|
|
|
{
|
|
|
|
|
return(lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 1.3<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD>ȹ<EFBFBD>Լ<EFBFBD><EFBFBD>1<EFBFBD><EFBFBD>
|
|
|
|
|
//
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vec <20><> ʸ<><CAB8>
|
|
|
|
|
//
|
|
|
|
|
Point2D normalize(const Point2D& vec)
|
|
|
|
|
{
|
|
|
|
|
Point2D res;
|
|
|
|
|
|
|
|
|
|
res = div(vec, length(vec));
|
|
|
|
|
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 1.9<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
// <20>߷<EFBFBD>Ϊֱ<CEAA>ߺ<EFBFBD><DFBA>߶Σ<DFB6>ֱ<EFBFBD>߱<EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>Ƿ<C7B7><F1BEADB9><EFBFBD>
|
|
|
|
|
//
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p : <20><> l : <20>߶λ<DFB6><CEBB><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//
|
|
|
|
|
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);
|
|
|
|
|
// <20><><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD>
|
|
|
|
|
if (l.is_seg)
|
|
|
|
|
{
|
|
|
|
|
if (equal(p, l.p1) || equal(p, l.p2))
|
|
|
|
|
return true;
|
|
|
|
|
return (0.0 == length(mul_vec) && dot < 0.0);
|
|
|
|
|
|
|
|
|
|
}
|
|
|
|
|
// <20><><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD>
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
return (0.0 == length(mul_vec));
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 1.4<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(p1-op)Ϊʸ<CEAA><CAB8>1<EFBFBD><31><EFBFBD><EFBFBD>p2-op<6F><70>Ϊʸ<CEAA><CAB8>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));
|
|
|
|
|
}
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>vec1Ϊʸ<CEAA><CAB8>1<EFBFBD><31>vec2Ϊʸ<CEAA><CAB8>2
|
|
|
|
|
//
|
|
|
|
|
double dotMultiply(const Point2D& vec1, const Point2D& vec2)
|
|
|
|
|
{
|
|
|
|
|
return(vec1.x * vec2.x + vec1.y * vec2.y + vec1.z * vec2.z);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 1.5<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>(p1-op)Ϊʸ<CEAA><CAB8>1<EFBFBD><31><EFBFBD><EFBFBD>p2-op<6F><70>Ϊʸ<CEAA><CAB8>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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vec1Ϊʸ<CEAA><CAB8>1<EFBFBD><31>vec2Ϊʸ<CEAA><CAB8>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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vec1 ʸ<><CAB8>1 vec2 ʸ<><CAB8>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<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
//
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vec ʸ<><CAB8>
|
|
|
|
|
//
|
|
|
|
|
double length(const Point2D& vec)
|
|
|
|
|
{
|
|
|
|
|
return (sqrt(pow(vec.x, 2) + pow(vec.y, 2) + pow(vec.z, 2)));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
Point2D mathVector(const Point2D& p1, const Point2D& p2) {
|
|
|
|
|
Point2D pt;
|
|
|
|
|
pt.x = p2.x - p1.x;
|
|
|
|
|
pt.y = p2.y - p1.y;
|
|
|
|
|
return pt;
|
|
|
|
|
}
|
|
|
|
|
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><D6AE><EFBFBD>IJ<EFBFBD><C4B2><EFBFBD>
|
|
|
|
|
double crossProduct(const Point2D& p1, const Point2D& p2) {
|
|
|
|
|
return p1.x * p2.y - p1.y * p2.x;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
//ֱ<><D6B1><EFBFBD><EFBFBD><EFBFBD>߶εĽ<CEB5><C4BD><EFBFBD>
|
|
|
|
|
bool findIntersection(double x1, double y1, double x2, double y2, // ֱ<><D6B1>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
|
|
|
|
|
double x3, double y3, double x4, double y4,Point2D& intersection);
|
|
|
|
|
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|