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-.../Compute_Geometry.h

1297 lines
29 KiB
C

// Copyright (C) Common Computational Geometry Algorithms e.U, ZutterHao
//
// This file is implementation of Common Common Computational Geometry Algorithms.
//
// Please please pay attention to input according to the specified data type.
//
// Author: ZutterHao .Nanjing University ,VISG
// Github: https://github.com/fanghao6666
// <20><><EFBFBD><EFBFBD>ʵ<EFBFBD>ֵ<EFBFBD>һЩ<D2BB><D0A9><EFBFBD><EFBFBD><E3BCB8><EFBFBD>г<EFBFBD><D0B3><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E3B7A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߣ<EFBFBD><DFA3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>㷨ֻ<E3B7A8><D6BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD>C++<2B><>׼<EFBFBD><EFBFBD><E2A3AC><EFBFBD>ð<EFBFBD><C3B0><EFBFBD><EFBFBD>κ<EFBFBD><CEBA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// ʹ<><CAB9>ʱ<EFBFBD><CAB1>ע<EFBFBD><EFBFBD>չ涨<D5B9><E6B6A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͽ<EFBFBD><CDBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// Ŀǰֻʹ<D6BB><CAB9>C++<2B><>ʵ<EFBFBD><CAB5><EFBFBD><EFBFBD><E3B7A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>㷨ԭ<E3B7A8><D4AD><EFBFBD><EFBFBD>½<EFBFBD><C2BD><EFBFBD><EFBFBD>Github<75>ϸ<EFBFBD><CFB8><EFBFBD>
// Github: https://github.com/fanghao6666
/*** <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͷ<EFBFBD>ļ<EFBFBD> ***/
#include <iostream>
#include <vector>
#include <map>
#include <stack>
#include <algorithm>
#include <random>
#include <ctime>
using namespace std;
namespace Compute_Geometry{
/*** <20><><EFBFBD>ó<EFBFBD><C3B3><EFBFBD> ***/
const double PI = 3.14159265;
/******************************* <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> *******************************/
// <20><>,<2C><>ά<EFBFBD><CEAC><EFBFBD><EFBFBD>ά,ͬʱ<CDAC><CAB1>Ҳ<EFBFBD><D2B2><EFBFBD>Ա<EFBFBD>ʾһ<CABE><D2BB>ʸ<EFBFBD><CAB8>
struct Point
{
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>
Point(double a = 0, double b = 0, double c = 0) { x = a; y = b; z = c; } // <20><><EFBFBD><EFBFBD><ECBAAF>
};
// <20><><EFBFBD>ļӷ<C4BC>
Point add(const Point& lhs, const Point& rhs)
{
Point 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>
Point sub(const Point& lhs, const Point& rhs)
{
Point 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>
Point mul(const Point& p, double ratio)
{
Point 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>
Point div(const Point& p, double ratio)
{
Point 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 Point& lhs, const Point& rhs)
{
return(lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z);
}
// <20><>,<2C><><EFBFBD><EFBFBD><EFBFBD>߶κ<DFB6>ֱ<EFBFBD><D6B1>
struct Line
{
Point s; // <20><><EFBFBD><EFBFBD>
Point e; // <20>յ<EFBFBD>
bool is_seg; // <20>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>߶<EFBFBD>
Line() {}; // Ĭ<>Ϲ<EFBFBD><CFB9><EFBFBD><ECBAAF>
Line(Point a, Point b, bool _is_seg = true) { s = a; e = b; is_seg = _is_seg; } // <20><><EFBFBD><EFBFBD><ECBAAF><><C4AC><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>)
};
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD>
struct Triangle
{
Point v0;
Point v1;
Point v2;
bool is_plane;
Triangle() {}; // Ĭ<>Ϲ<EFBFBD><CFB9><EFBFBD><ECBAAF>
Triangle(Point a, Point b, Point c, bool _is_plane = false) { v0 = a; v1 = b; v2 = c; is_plane = _is_plane; }// <20><><EFBFBD><EFBFBD><ECBAAF><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Σ<EFBFBD>
};
/******************************* <20><><EFBFBD><EFBFBD><E3BCB8><EFBFBD>㷨Ŀ¼ *******************************/
// һ<><D2BB><EFBFBD><EFBFBD>
// 1.1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD>
double distance(const Point& p1, const Point& p2);
// 1.2<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double length(const Point& vec);
// 1.3<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>׼<EFBFBD><EFBFBD>
Point normalize(const Point& vec);
// 1.4<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double dotMultiply(const Point& op, const Point& p1, const Point& p2);
double dotMultiply(const Point& vec1, const Point& vec2);
// 1.5<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Point multiply(const Point& op, const Point& p1, const Point& p2);
Point multiply(const Point& vec1, const Point& vec2);
// 1.6<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵľ<EFBFBD><EFBFBD><EFBFBD>
double ptolDistance(const Point& p, const Line& l);
// 1.7<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ͶӰ<EFBFBD><EFBFBD>
Point ptolProjection(const Point& p, const Line& l);
// 1.8<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵĶԳƵ<EFBFBD>
Point ptolSymmetry(const Point& p, const Line& l);
// 1.9<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool isponl(const Point& p, const Line& l);
// 1.10<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double Sin(const Point& op, const Point& p1, const Point& p2);
double Sin(const Point& vec1, const Point& vec2);
// 1.11<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double Cos(const Point& op, const Point& p1, const Point& p2);
double Cos(const Point& vec1, const Point& vec2);
// 1.12<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double Tan(const Point& op, const Point& p1, const Point& p2);
double Tan(const Point& vec1, const Point& vec2);
// 1.13<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>нǽǶ<EFBFBD>
double Angle(const Point& op, const Point& p1, const Point& p2, bool is_radian = true);
double Angle(const Point& vec1, const Point& vec, bool is_radian = true);
// 1.14<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool isPointsCollinear(const Point& p1, const Point& p2, const Point& p3);
// 1.15<EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>-1<><31>-1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>n<EFBFBD><6E><EFBFBD><EFBFBD>
vector<Point> randomGenPoints(int num);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 2.1<EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>
bool isSegIntersect(const Line& l1, const Line& l2, Point& inter_p);
// 2.2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>ߵļн<EFBFBD>
double angleOfLines(const Line& l1, const Line& l2, bool is_radian = true);
// 2.3<EFBFBD><EFBFBD>һ<EFBFBD>ױ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߲<EFBFBD>ֵ
vector<Point> firstOrderBezier(const Point& s, const Point& e, int inter_num);
// 2.4<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ױ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߲<EFBFBD>ֵ
vector<Point> secondOrderBezier(const Point& s, const Point& e, const Point& p, int inter_num);
// 2.5<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ױ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߲<EFBFBD>ֵ
vector<Point> thirdOrderBezier(const Point& s, const Point& e, const Point& p1, const Point& p2, int inter_num);
// 2.6<EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>-1<><31>-1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>n<EFBFBD><6E><EFBFBD><EFBFBD>
vector<Line> randomGenLines(int num);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 3.1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool isTriangle(const Triangle& t);
// 3.2<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>
bool isPointInTriangle(const Triangle& t, const Point& p, double& u, double& v);
// 3.3<EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͶӰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ㣩
Point ptotProjection(const Triangle& t, const Point& p);
// 3.4<EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD>
double ptotDistance(const Triangle& t, const Point& p);
// 3.5<EFBFBD><EFBFBD><EFBFBD>߶κ<EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD>
Point ltotInterPoint(const Triangle& t, const Line& l);
// 3.6<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Point getUnitNormal(const Triangle& t);
// 3.7<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double areaOfTriangle(const Triangle& t);
// <20>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 4.1<EFBFBD><EFBFBD><EFBFBD>ж϶<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ζ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD>͹<EFBFBD><EFBFBD>
void checkConvex(const vector<Point>& polygon, vector<bool>& flags);
// 4.2<EFBFBD><EFBFBD><EFBFBD>ж϶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ϊ͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool isConvex(const vector<Point>& polygon);
// 4.3<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD>ɵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
double areaOfPolygon(const vector<Point>& polygon);
// 4.4<EFBFBD><EFBFBD><EFBFBD>ж϶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool isConterClock(const vector<Point>& polygon);
// 4.5<EFBFBD><EFBFBD><EFBFBD>жϵ<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>
bool isPointInPolygon(const vector<Point>& polygon, const Point& p);
// 4.6<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD>߶<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>
bool isSegInPolygon(const vector<Point>& polygon, const Line& l);
// 4.7<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>Բ<EFBFBD>Ƿ<EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>
bool isCircleInPolygon(const vector<Point>& polygon, const Point& p, double radius);
// 4.8<EFBFBD><EFBFBD>Ѱ<EFBFBD>ҵ㼯͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>graham<EFBFBD><EFBFBD><EFBFBD>
vector<Point> findConvexGraham(const vector<Point>& points);
// 4.9<EFBFBD><EFBFBD>Ѱ<EFBFBD>ҵ㼯͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>Ӷ<EFBFBD>O(nlogn)
vector<Point> findConvex(const vector<Point>& points);
// 4.10<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򵥶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Point centerOfPolygon(const vector<Point>& polygon);
// 4.11<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Point pointInPolygon(const vector<Point>& polygon);
// 4.12<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>εķ<EFBFBD>Χ
void boxOfPolygon(const vector<Point>& polygon, Point& down_left, Point& up_right);
// <20>塢Բ
// 5.1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD>Ĺ<EFBFBD>ϵ
int pointToCircle(const Point& c, double radius, const Point& p);
// 5.2<EFBFBD><EFBFBD>ֱ<EFBFBD>ߺ<EFBFBD>Բ<EFBFBD>Ĺ<EFBFBD>ϵ
int lineToCircle(const Point& c, double radius, const Line& l);
// 5.3<EFBFBD><EFBFBD><EFBFBD>߶κ<EFBFBD>Բ<EFBFBD>Ĺ<EFBFBD>ϵ
int segToCircle(const Point& c, double radius, const Line& l);
// 5.4<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ֮<EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD>ϵ
int circleToCircle(const Point& c1, double raduis1, const Point& c2, double radius2);
/******************************* <20><><EFBFBD><EFBFBD><E3BCB8><EFBFBD>㷨ʵ<E3B7A8><CAB5> *******************************/
//һ<><D2BB><EFBFBD><EFBFBD>
// 1.1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>֮<EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p1 : <20><>һ<EFBFBD><D2BB><EFBFBD><EFBFBD> p2: <20>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD>
//
double distance(const Point& p1, const Point& p2)
{
return(sqrt(pow(p1.x - p2.x, 2) + pow(p1.y - p2.y, 2) + pow(p1.z - p2.z, 2)));
}
// 1.2<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>ij<EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vec ʸ<><CAB8>
//
double length(const Point& vec)
{
return (sqrt(pow(vec.x, 2) + pow(vec.y, 2) + pow(vec.z, 2)));
}
// 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>
//
Point normalize(const Point& vec)
{
Point res;
res = div(vec, length(vec));
return res;
}
// 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 Point& op, const Point& p1, const Point& 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 Point& vec1, const Point& 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
//
Point multiply(const Point& op, const Point& p1, const Point& p2)
{
Point 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
//
Point multiply(const Point& vec1, const Point& vec2)
{
Point 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;
}
// 1.6<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵľ<EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p : <20><> l<><6C>ֱ<EFBFBD><D6B1>
//
double ptolDistance(const Point& p, const Line& l)
{
Point line_vec = sub(l.e, l.s);
Point point_vec = sub(p, l.s);
// <20><><EFBFBD>ȼ<EFBFBD><C8BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD>ͶӰ<CDB6><D3B0><EFBFBD><EFBFBD>
double project_len = dotMultiply(line_vec, point_vec) / length(line_vec);
// <20><><EFBFBD>ݹ<EFBFBD><DDB9>ɶ<EFBFBD><C9B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><C4BE><EFBFBD>
double distance = sqrt(pow(length(line_vec), 2) - pow(project_len, 2));
return distance;
}
// 1.7<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD>ͶӰ<EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>p : <20><> l : <20><>
//
Point ptolProjection(const Point& p, const Line& l)
{
Point line_vec = sub(l.e, l.s);
Point point_vec = sub(p, l.s);
Point unit_line_vec = normalize(line_vec);
// <20><><EFBFBD><EFBFBD>ͶӰ<CDB6><D3B0><EFBFBD><EFBFBD>
double project_len = dotMultiply(point_vec, unit_line_vec);
// ͶӰ<CDB6><D3B0>
Point project_p = add(l.s, mul(unit_line_vec, project_len));
return project_p;
}
// 1.8<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ߵĶԳƵ<EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p : <20><> l : <20>Գ<EFBFBD><D4B3><EFBFBD>
//
Point ptolSymmetry(const Point& p, const Line& l)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD>ϵ<EFBFBD>ͶӰ<CDB6><D3B0>
Point project_p = ptolProjection(p, l);
// <20>㵽ͶӰ<CDB6><D3B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
Point project_vec = sub(project_p, p);
// <20>ԳƵ<D4B3>
Point symmetry_p = add(p, mul(project_vec, 2));
return symmetry_p;
}
// 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 Point& p, const Line& l)
{
Point line_vec = sub(l.e, l.s);
Point point_vec1 = sub(p, l.s);
Point point_vec2 = sub(p, l.e);
Point 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.s) || equal(p, l.e))
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.10<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> op : ʸ<><CAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p1 : ʸ<><CAB8>1<EFBFBD>˵<EFBFBD> p2 : ʸ<><CAB8>2<EFBFBD>˵<EFBFBD>
//
double Sin(const Point& op, const Point& p1, const Point& p2)
{
Point vec1 = sub(p1, op);
Point vec2 = sub(p2, op);
return Sin(vec1, vec2);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vec1 ʸ<><CAB8>1 vec2 ʸ<><CAB8>2
//
double Sin(const Point& vec1, const Point& vec2)
{
return sqrt(1.0 - pow(Cos(vec1, vec2), 2));
}
// 1.11<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> op : ʸ<><CAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p1 : ʸ<><CAB8>1<EFBFBD>˵<EFBFBD> p2 : ʸ<><CAB8>2<EFBFBD>˵<EFBFBD>
//
double Cos(const Point& op, const Point& p1, const Point& p2)
{
Point vec1 = sub(p1, op);
Point vec2 = sub(p2, op);
return Cos(vec1, vec2);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vec1 ʸ<><CAB8>1 vec2 ʸ<><CAB8>2
//
double Cos(const Point& vec1, const Point& vec2)
{
Point unit_vec1 = normalize(vec1);
Point unit_vec2 = normalize(vec2);
return dotMultiply(unit_vec1, unit_vec2);
}
// 1.12<EFBFBD><EFBFBD>ʸ<EFBFBD><EFBFBD><EFBFBD>н<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> op : ʸ<><CAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p1 : ʸ<><CAB8>1<EFBFBD>˵<EFBFBD> p2 : ʸ<><CAB8>2<EFBFBD>˵<EFBFBD>
//
double Tan(const Point& op, const Point& p1, const Point& p2)
{
Point vec1 = sub(p1, op);
Point vec2 = sub(p2, op);
return Tan(vec1, vec2);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vec1 ʸ<><CAB8>1 vec2 ʸ<><CAB8>2
//
double Tan(const Point& vec1, const Point& vec2)
{
double cos = Cos(vec1, vec2);
double sin = Sin(vec1, vec2);
// <20><>ĸ<EFBFBD><C4B8>Ϊ<EFBFBD><CEAA>
if (0.0 == cos)
return -1;
else
return (sin / cos);
}
// 1.13<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ļнǽǶ<EFBFBD>
// <20><><EFBFBD><EFBFBD>: op : ʸ<><CAB8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p1 : ʸ<><CAB8>1<EFBFBD>˵<EFBFBD> p2 : ʸ<><CAB8>2<EFBFBD>˵<EFBFBD> is_radian : Ĭ<><C4AC>Ϊ<EFBFBD><CEAA><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
double Angle(const Point& op, const Point& p1, const Point& p2, bool is_radian)
{
double cos_value = Cos(op, p1, p2);
if (is_radian)
{
return acos(cos_value);
}
else
{
return (acos(cos_value) / PI * 180.0);
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> vec1 : ʸ<><CAB8>1 vec2 : ʸ<><CAB8>2
//
double Angle(const Point& vec1, const Point& vec2, bool is_radian)
{
double cos_value = Cos(vec1, vec2);
if (is_radian)
{
return acos(cos_value);
}
else
{
return (acos(cos_value) / PI * 180.0);
}
}
// 1.14<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
bool isPointsCollinear(const Point& p1, const Point& p2, const Point& p3)
{
Line line(p1, p2, false);
// <20>жϵ<D0B6><CFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD>
return isponl(p3, line);
}
// 1.15<EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>-1<><31>-1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>n<EFBFBD><6E><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> down_left : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>½<EFBFBD> up_right: <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ͻ<EFBFBD> num : <20><><EFBFBD>ɵ<EFBFBD><C9B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
vector<Point> randomGenPoints(int num)
{
vector<Point> result;
std::uniform_real_distribution<double> dist(-0.9, 0.9);
std::mt19937 rng;
rng.seed(std::random_device{}());
for (int i = 0; i < num; ++i)
{
double rand_x = dist(rng);
double rand_y = dist(rng);
result.push_back(Point(rand_x, rand_y));
}
return result;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 2.1<EFBFBD><EFBFBD><EFBFBD>߶<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߶εĶ˵<C4B6><CBB5>غϻ<D8BA><CFBB><EFBFBD>ij<EFBFBD><C4B3><EFBFBD>߶ζ˵<CEB6><CBB5><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>߶<EFBFBD><DFB6><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD>
// <20>߶<EFBFBD><DFB6>ж<EFBFBD><D0B6>Ƿ<EFBFBD><C7B7><EFBFBD><E0BDBB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD><D6B1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0B5B1><EFBFBD>ж<EFBFBD><D0B6>Ƿ<EFBFBD>ƽ<EFBFBD><C6BD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> l1 : <20>߶<EFBFBD>1 l2 : <20>߶<EFBFBD>2 inter_p : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0BDBB><EFBFBD>ؽ<EFBFBD><D8BD><EFBFBD>
//
bool isSegIntersect(const Line& l1, const Line& l2, Point& inter_p)
{
Point line1 = sub(l1.e, l1.s);
Point line2 = sub(l2.e, l2.s);
Point norm1 = normalize(line1);
Point norm2 = normalize(line2);
// <20>߶<EFBFBD><DFB6>
if (l1.is_seg)
{
// <20>˵<EFBFBD><CBB5><EFBFBD><EFBFBD>߶<EFBFBD><DFB6><EFBFBD>
if (isponl(l1.s, l2))
{
inter_p = l1.s;
return true;
}
if (isponl(l1.e, l2))
{
inter_p = l1.e;
return true;
}
if (isponl(l2.s, l1))
{
inter_p = l2.s;
return true;
}
if (isponl(l2.e, l1))
{
inter_p = l2.e;
return true;
}
// <20>ж<EFBFBD><D0B6>߶<EFBFBD><DFB6>Ƿ<EFBFBD><C7B7><EFBFBD><E0BBA5><EFBFBD><EFBFBD>
double dot1 = dotMultiply(multiply(sub(l2.s, l1.s), line1), multiply(sub(l2.e, l1.s), line1));
double dot2 = dotMultiply(multiply(sub(l1.s, l2.s), line2), multiply(sub(l1.e, l2.s), line2));
if (dot1 < 0.0 && dot2 < 0.0)
{
double t1 = length(multiply(sub(l1.s, l2.s), norm2)) / length(multiply(norm2, norm1));
double t2 = length(multiply(sub(l2.s, l1.s), norm1)) / length(multiply(norm1, norm2));
inter_p = add(l1.s, mul(norm1, t1));
return true;
}
else
{
return false;
}
}
// ֱ<><D6B1><EFBFBD>
else
{
if (Cos(line1, line2) == 1.0)
return false;
double t1 = length(multiply(sub(l1.s, l2.s), norm2)) / length(multiply(norm2, norm1));
double t2 = length(multiply(sub(l2.s, l1.s), norm1)) / length(multiply(norm1, norm2));
inter_p = add(l1.s, mul(norm1, t1));
return true;
}
}
// 2.2<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֱ<EFBFBD>ߵļн<EFBFBD>
//
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> l1 : <20>߶<EFBFBD>1 l2 : <20>߶<EFBFBD>2
//
double angleOfLines(const Line& l1, const Line& l2, bool is_radian)
{
Point line1 = sub(l1.e, l1.s);
Point line2 = sub(l2.e, l2.s);
return Angle(line1, line2, is_radian);
}
// 2.3<EFBFBD><EFBFBD>һ<EFBFBD>ױ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߲<EFBFBD>ֵ
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> s<><73> <20><><EFBFBD><EFBFBD> e : <20>յ<EFBFBD> inter_num<75><6D><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD>
// <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
//
vector<Point> firstOrderBezier(const Point& s, const Point& e, int inter_num)
{
vector<Point> res;
res.push_back(s);
for (int i = 1; i <= inter_num; ++i)
{
double a1 = double(i) / double(inter_num + 1);
double a2 = 1.0 - a1;
res.push_back(add(mul(s, a2), mul(e, a1)));
}
res.push_back(e);
return res;
}
// 2.4<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ױ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߲<EFBFBD>ֵ
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> s<><73> <20><><EFBFBD><EFBFBD> e : <20>յ<EFBFBD> p : <20><><EFBFBD>Ƶ<EFBFBD> inter_num<75><6D><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD>
// <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
//
vector<Point> secondOrderBezier(const Point& s, const Point& e, const Point& p, int inter_num)
{
vector<Point> res;
res.push_back(s);
for (int i = 1; i <= inter_num; ++i)
{
double a = double(i) / double(inter_num + 1);
double a1 = pow(a, 2);
double a2 = 2 * a * (1.0 - a);
double a3 = pow(1.0 - a, 2);
res.push_back(add(add(mul(s, a3), mul(p, a2)), mul(e, a1)));
}
res.push_back(e);
return res;
}
// 2.5<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ױ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>߲<EFBFBD>ֵ
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> s<><73> <20><><EFBFBD><EFBFBD> e : <20>յ<EFBFBD> p1<70><31>p2 : <20><><EFBFBD>Ƶ<EFBFBD> inter_num<75><6D><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD>
// <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC>
//
vector<Point> thirdOrderBezier(const Point& s, const Point& e, const Point& p1, const Point& p2, int inter_num)
{
vector<Point> res;
res.push_back(s);
for (int i = 1; i <= inter_num; ++i)
{
double a = double(i) / double(inter_num + 1);
double a1 = pow(a, 3);
double a2 = 3 * pow(a, 2) * (1.0 - a);
double a3 = 3 * pow(1.0 - a, 2) * a;
double a4 = pow(1.0 - a, 3);
res.push_back(add(add(add(mul(s, a4), mul(p1, a3)), mul(p2, a2)), mul(e, a1)));
}
res.push_back(e);
return res;
}
// 2.6<EFBFBD><EFBFBD><EFBFBD>ڣ<EFBFBD>-1<><31>-1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD>1<EFBFBD><31>1<EFBFBD><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>n<EFBFBD><6E><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD> num : <20><>Ҫ<EFBFBD><D2AA><EFBFBD>ɵ<EFBFBD><C9B5>߶ε<DFB6><CEB5><EFBFBD><EFBFBD><EFBFBD>
//
vector<Line> randomGenLines(int num)
{
vector<Line> result;
std::uniform_real_distribution<double> dist(-0.9, 0.9);
std::mt19937 rng;
rng.seed(std::random_device{}());
for (int i = 0; i < num; ++i)
{
double rand_sx = dist(rng);
double rand_sy = dist(rng);
Point p1(rand_sx, rand_sy);
double rand_ex = dist(rng);
double rand_ey = dist(rng);
Point p2(rand_ex, rand_ey);
result.push_back(Line(p1,p2,true));
}
return result;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// 3.1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ܹ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD>ߵ<EFBFBD><DFB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> t : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
bool isTriangle(const Triangle& t)
{
return isPointsCollinear(t.v0, t.v1, t.v2);
}
// 3.2<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ķ<EFBFBD><EFBFBD><EFBFBD>
// <20><EFBFBD><E3B7A8><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD> https://www.cnblogs.com/graphics/archive/2010/08/05/1793393.html
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> t : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p : <20><>Ҫ<EFBFBD>жϵĵ<CFB5> u,v<>ֱ<EFBFBD>Ϊ<EFBFBD><CEAA><EFBFBD>ڱ<EFBFBD>ʾ<EFBFBD><CABE><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͶӰϵ<D3B0><CFB5>
//
bool isPointInTriangle(const Triangle& t, const Point& p, double& u, double& v)
{
Point vec1 = sub(t.v1, t.v0);
Point vec2 = sub(t.v2, t.v0);
Point vec_p = sub(p, t.v0);
double dot00 = dotMultiply(vec1, vec1);
double dot01 = dotMultiply(vec1, vec2);
double dot02 = dotMultiply(vec1, vec_p);
double dot11 = dotMultiply(vec2, vec2);
double dot12 = dotMultiply(vec2, vec_p);
double inverDeno = 1 / (dot00 * dot11 - dot01 * dot01);
u = (dot11 * dot02 - dot01 * dot12) * inverDeno;
v = (dot00 * dot12 - dot01 * dot02) * inverDeno;
if (u < 0 || u > 1) return false;
if (v < 0 || v > 1) return false;
if (u + v < 1)return true;
else return false;
}
// 3.3<EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ĵ㣬<EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͶӰ
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>t : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p : <20><>
//
Point ptotProjection(const Triangle& t, const Point& p)
{
Point vec_p = sub(p, t.v0);
Point unit_normal = getUnitNormal(t);
double ratio = dotMultiply(vec_p, unit_normal);
return sub(p, mul(unit_normal, ratio));
}
// 3.4<EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD>ľ<EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> t : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڵ<EFBFBD>ƽ<EFBFBD><C6BD> p : <20><>Ҫ<EFBFBD>жϵĵ<CFB5>
//
double ptotDistance(const Triangle& t, const Point& p)
{
Point project_p = ptotProjection(t, p);
return distance(p, project_p);
}
// 3.5<EFBFBD><EFBFBD><EFBFBD>߶κ<EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> t : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD> l : ֱ<><D6B1>
//
Point ltotInterPoint(const Triangle& t, const Line& l)
{
Point line_vec = sub(l.e, l.s);
Point point_vec = sub(t.v0, l.s);
Point unit_plane_normal = getUnitNormal(t);
double ratio = dotMultiply(point_vec, unit_plane_normal) / dotMultiply(unit_plane_normal, line_vec);
return add(l.s, mul(line_vec, ratio));
}
// 3.6<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><EFBFBD><EFBFBD>ĵ<EFBFBD>λ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> t : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD>
//
Point getUnitNormal(const Triangle& t)
{
Point vec1 = sub(t.v1, t.v0);
Point vec2 = sub(t.v2, t.v0);
return normalize(multiply(vec1, vec2));
}
// 3.7<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> t : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ƽ<EFBFBD><C6BD>
//
double areaOfTriangle(const Triangle& t)
{
return (0.5 * length(multiply(sub(t.v1, t.v0), sub(t.v2, t.v0))));
}
// <20>ġ<EFBFBD><C4A1><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>û<EFBFBD><C3BB><EFBFBD>ر<EFBFBD>˵<EFBFBD><CBB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ĭ<EFBFBD><C4AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ζ<EFBFBD><CEB6><EFBFBD><E3B0B4><EFBFBD><EFBFBD>ʱ<EFBFBD><CAB1><EFBFBD><EFBFBD><EFBFBD>У<EFBFBD><D0A3><EFBFBD>Ϊ<EFBFBD><CEAA>ά<EFBFBD>㼴z=0
// 4.1<EFBFBD><EFBFBD><EFBFBD>ж϶<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ζ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD>͹<EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> polygon : <20><><EFBFBD><EFBFBD><EFBFBD>ε㼯<CEB5><E3BCAF> flags : <20><>־ÿ<D6BE><C3BF><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><C7B7><EFBFBD>͹<EFBFBD><CDB9>
//
void checkConvex(const vector<Point>& polygon, vector<bool>& flags)
{
flags.resize(polygon.size());
// <20>ҵ<EFBFBD><D2B5><EFBFBD>һ<EFBFBD><D2BB>͹<EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD>
int index = 0;
for (int i = 1; i < polygon.size(); ++i)
{
if (polygon[i].y < polygon[index].y ||
(polygon[i].y == polygon[index].y && polygon[i].x < polygon[index].x))
{
index = i;
}
}
/* <20>ж<EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD>͹<EFBFBD><CDB9>
* ͨ<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>ǰ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>
*/
int size = polygon.size() - 1;
flags[index] = true;
while (size)
{
if (multiply(polygon[index], polygon[(index + 1) % size], polygon[(index + 2) % size]).z >= 0)
{
flags[(index + 1) % size] = true;
}
else
{
flags[(index + 1) % size] = false;
}
index++;
size--;
}
}
// 4.2<EFBFBD><EFBFBD><EFBFBD>ж϶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>Ϊ͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD> <20><> polygon : <20><><EFBFBD><EFBFBD><EFBFBD>Ķ<EFBFBD><C4B6><EFBFBD><EFBFBD>ζ<EFBFBD><CEB6><EFBFBD>
//
bool isConvex(const vector<Point>& polygon)
{
vector<bool> flags;
// <20>ж<EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>İ<EFBFBD>͹<EFBFBD><CDB9>
checkConvex(polygon, flags);
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD><EFBFBD><E3B2BB>͹<EFBFBD>ģ<EFBFBD><C4A3><EFBFBD><EFBFBD>˶<EFBFBD><CBB6><EFBFBD><EFBFBD><EFBFBD>Ϊ<EFBFBD><CEAA>͹
for (auto c : flags)
if (!c)
return false;
return true;
}
// 4.3<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Χ<EFBFBD>ɵ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> polygon : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
double areaOfPolygon(const vector<Point>& polygon)
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD><CEB5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD>
int size = polygon.size();
if (size < 3) return 0;
double area(0.0);
for (int i = 0; i < size; ++i)
{
area += polygon[i].y * (polygon[(i - 1 + size) % size].x - polygon[(i + 1) % size].x);
}
return (area / 2);
}
// 4.4<EFBFBD><EFBFBD><EFBFBD>ж϶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> polygon : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
bool isConterClock(const vector<Point>& polygon)
{
return areaOfPolygon(polygon) > 0;
}
// 4.5<EFBFBD><EFBFBD><EFBFBD>жϵ<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>
// <20>жϴӵ<CFB4><D3B5><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>߶<EFBFBD><DFB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>εĽ<CEB5><C4BD><EFBFBD><EFBFBD>ĸ<EFBFBD><C4B8><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E0BDBB>ż<EFBFBD><C5BC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> polygon : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> p : <20><>Ҫ<EFBFBD>жϵĵ<CFB5>
//
bool isPointInPolygon(const vector<Point>& polygon, const Point& p)
{
Point down_left, up_right;
boxOfPolygon(polygon, down_left, up_right);
// λ<>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ⲿһ<E2B2BF><D2BB>
Point out_p = sub(down_left, Point(10.0, 0.0));
int cnt(0);
Line p_line(p, out_p, true);
for (int i = 0; i < polygon.size(); ++i)
{
Point s = polygon[i];
Point e = polygon[(i + 1) % polygon.size()];
Line seg(s, e, true);
Point inter_p;
if (isSegIntersect(p_line, seg, inter_p))
{
cnt++;
}
}
return (cnt % 2 == 1);
}
// 4.6<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><EFBFBD>߶<EFBFBD><EFBFBD>Ƿ<EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>
// <20>߶<EFBFBD><DFB6>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>˵㶼<CBB5>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ҳ<EFBFBD><D2B2><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> polygon : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> l <20><> <20>߶<EFBFBD>
bool isSegInPolygon(const vector<Point>& polygon, const Line& l)
{
// <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6>߶ζ˵<CEB6><CBB5>Ƿ<EFBFBD><C7B7><EFBFBD><EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>
bool is_s_in = isPointInPolygon(polygon, l.s);
bool is_e_in = isPointInPolygon(polygon, l.e);
// Ȼ<><C8BB><EFBFBD>ж<EFBFBD><D0B6>߶<EFBFBD><DFB6>Ƿ<EFBFBD><C7B7>
if (is_s_in && is_e_in)
{
for (int i = 0; i < polygon.size(); ++i)
{
Point s = polygon[i];
Point e = polygon[(i + 1) % polygon.size()];
Line seg(s, e, true);
Point inter_p;
if (isSegIntersect(l, seg, inter_p))
{
return false;
}
}
return true;
}
else
{
return false;
}
}
// 4.7<EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD>Բ<EFBFBD>Ƿ<EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>
// ֻ<>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>еı߶<C4B1><DFB6><EFBFBD>Բ<EFBFBD><D4B2><EFBFBD>ⲿ<EFBFBD><E2B2BF>Բ<EFBFBD>Ŵ<EFBFBD><C5B4>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD>
//
// <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> polygon : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> c : Բ<><D4B2> radius <20><> <20>
//
bool isCircleInPolygon(const vector<Point>& polygon, const Point& c, double radius)
{
for (int i = 0; i < polygon.size(); ++i)
{
const Point& p1 = polygon[i];
const Point& p2 = polygon[(i + 1) % polygon.size()];
Line line(p1, p2, true);
if (segToCircle(c, radius, line) != 2)
return false;
}
return true;
}
// 4.8<EFBFBD><EFBFBD>Ѱ<EFBFBD>ҵ㼯͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>graham<EFBFBD><EFBFBD><EFBFBD>
// <20><EFBFBD><E3B7A8><EFBFBD>ӣ<EFBFBD>https://blog.csdn.net/acm_zl/article/details/9342631
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> points <20><> ƽ<><C6BD><EFBFBD>
//Ŀǰʵ<C7B0>ֵİ汾<C4B0><E6B1BE><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
vector<Point> findConvexGraham(const vector<Point>& points)
{
vector<Point> result;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (points.size() < 3)
return result;
// Ѱ<><D1B0><EFBFBD><EFBFBD><EFBFBD>ײ<EFBFBD><D7B2>ĵ<EFBFBD>
int index = 0;
for (int i = 0; i < points.size(); ++i)
{
if (points[i].y < points[index].y)
{
index = i;
}
}
Point convex_p = points[index];
// <20><><EFBFBD><EFBFBD>ÿ<EFBFBD><C3BF><EFBFBD><EFBFBD><EFBFBD>ļ<EFBFBD><C4BC><EFBFBD>
map<double, int> cos_map;
Point x_vec(1.0, 0.0);
for (int i = 0; i < points.size(); ++i)
{
if (i != index)
{
double cos_value = Cos(sub(points[i], convex_p), x_vec);
// <20><><EFBFBD><EFBFBD><EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ͬ<EFBFBD>ļ<EFBFBD><C4BC>ǣ<EFBFBD><C7A3><EFBFBD>ȡ<EFBFBD><C8A1>Զ<EFBFBD>ĵ<EFBFBD>
if (cos_map.count(-cos_value) != 0)
{
if (length(points[i]) > length(points[cos_map[-cos_value]]))
cos_map[-cos_value] = i;
}
else
cos_map[-cos_value] = i;
}
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ջ
stack<int> result_stack;
// <20><><EFBFBD>ʼ<EBBFAA><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
result_stack.push(index);
result_stack.push(cos_map.begin()->second);
for (auto iter = (++cos_map.begin()); iter != cos_map.end(); ++iter)
{
int first = result_stack.top();
result_stack.pop();
int second = result_stack.top();
Point vec1 = sub(points[first], points[second]);
Point vec2 = sub(points[iter->second], points[first]);
if (multiply(vec1, vec2).z >= 0)
result_stack.push(first);
result_stack.push(iter->second);
}
// <20><><EFBFBD><EFBFBD><EFBFBD>ݴ<EFBFBD>ջ<EFBFBD>ж<EFBFBD>ȡ
while (!result_stack.empty())
{
result.push_back(points[result_stack.top()]);
result_stack.pop();
}
std::reverse(result.begin(), result.end());
return result;
}
//// 4.9<EFBFBD><EFBFBD>Ѱ<EFBFBD>ҵ㼯͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͹<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʱ<EFBFBD><EFBFBD>Ӷ<EFBFBD>O(nlogn)
////
//// <09><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> points : ƽ<><C6BD><EFBFBD>
////
//// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD>ıȽϺ<C8BD><CFBA><EFBFBD>
//bool cmp(Point a, Point b)
//{
// if (a.x == b.x)
// return a.y < b.y;
// return a.x < b.x;
//}
//vector<Point> findConvex(const vector<Point>& points)
//{
// vector<Point> result;
// if (points.size() < 3)
// return result;
//
// vector<Point> tmp_points = points;
// // <20><><EFBFBD>Ƚ<EFBFBD><C8BD><EFBFBD><EFBFBD>е<D0B5><E3B0B4><EFBFBD>ֵ<EFBFBD><D6B5><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// sort(tmp_points.begin(), tmp_points.end(), cmp);
//
// // <20><>͹<EFBFBD><CDB9>
// vector<Point> upper_hull;
// // <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>͵ڶ<CDB5><DAB6><EFBFBD><EFBFBD><EFBFBD>
// upper_hull.push_back(tmp_points[0]);
// upper_hull.push_back(tmp_points[1]);
// for (int i = 2; i < tmp_points.size(); ++i)
// {
// upper_hull.push_back(tmp_points[i]);
// while (upper_hull.size() > 2 && multiply(sub(upper_hull[upper_hull.size() - 2], upper_hull[upper_hull.size() - 3]), sub(upper_hull[upper_hull.size() - 1], upper_hull[upper_hull.size() - 3])).z >= 0)
// {
// upper_hull.erase(upper_hull.end() - 2);
// }
// }
// // <20><>͹<EFBFBD><CDB9>
// vector<Point> lower_hull;
// // <20><><EFBFBD><EFBFBD><EBB5B9><EFBFBD><EFBFBD>һ<EFBFBD>ڶ<EFBFBD><DAB6><EFBFBD><EFBFBD><EFBFBD>
// lower_hull.push_back(tmp_points[tmp_points.size() - 1]);
// lower_hull.push_back(tmp_points[tmp_points.size() - 2]);
// for (int i = tmp_points.size() - 3; i >= 0; --i)
// {
// lower_hull.push_back(tmp_points[i]);
// while (lower_hull.size() > 2 && multiply(sub(lower_hull[lower_hull.size() - 2], lower_hull[lower_hull.size() - 3]), sub(lower_hull[lower_hull.size() - 1], lower_hull[lower_hull.size() - 3])).z >= 0)
// {
// lower_hull.erase(lower_hull.end() - 1);
// }
// }
// // ɾ<><C9BE><EFBFBD>ظ<EFBFBD><D8B8><EFBFBD>
// lower_hull.erase(lower_hull.begin());
// lower_hull.erase(lower_hull.end() - 1);
//
// // <20>ϲ<EFBFBD><CFB2><EFBFBD><EFBFBD><EFBFBD>͹<EFBFBD><CDB9>
// upper_hull.insert(upper_hull.end(), lower_hull.begin(), lower_hull.end());
//
// result = upper_hull;
//
// return result;
//}
// 4.10<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>򵥶<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20>㷨ԭ<E3B7A8><D4AD><EFBFBD><EFBFBD><EFBFBD>ӣ<EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> polygon <20><> <20>򵥶<EFBFBD><F2B5A5B6><EFBFBD><EFBFBD><EFBFBD>
//
Point centerOfPolygon(const vector<Point>& polygon)
{
double polygon_area(0.0);
Point center;
Point origin;
for (int i = 0; i < polygon.size(); ++i)
{
Point curr_p = polygon[i];
Point next_p = polygon[(i + 1) % polygon.size()];
Triangle t(origin, curr_p, next_p);
double curr_area = areaOfTriangle(t);
polygon_area += curr_area;
center = add(center, mul(div(add(curr_p, next_p), 3), curr_area));
}
center = div(center, polygon_area);
return center;
}
// 4.11<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>϶<EFBFBD><EFBFBD>ڶ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>1: ÿ<><C3BF><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB>͹<EFBFBD><CDB9><EFBFBD>
// x<><78><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>ĵ<EFBFBD><C4B5>϶<EFBFBD><CFB6><EFBFBD>͹<EFBFBD><CDB9><EFBFBD>㣬y<E3A3AC><79><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С<EFBFBD>ĵ<EFBFBD><C4B5>϶<EFBFBD><CFB6><EFBFBD>͹<EFBFBD><CDB9><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD>2<EFBFBD><32><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>>= 4<>ļ򵥶<C4BC><F2B5A5B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>һ<EFBFBD><D2BB><EFBFBD>Խ<EFBFBD><D4BD><EFBFBD>
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> polygon <20><> <20>򵥶<EFBFBD><F2B5A5B6><EFBFBD><EFBFBD><EFBFBD>
//
Point pointInPolygon(const vector<Point>& polygon)
{
// ͹<><CDB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
int index = 0;
Point convex_p = polygon[0];
// Ѱ<><D1B0>һ<EFBFBD><D2BB>͹<EFBFBD><CDB9><EFBFBD><EFBFBD>
for (int i = 0; i < polygon.size(); ++i)
{
if (polygon[i].y < convex_p.y)
{
index = i;
convex_p = polygon[i];
}
}
// <20><>ȡ͹<C8A1><CDB9><EFBFBD><EFBFBD>ǰ<EFBFBD><C7B0>һ<EFBFBD><D2BB><EFBFBD><EFBFBD>
int size = polygon.size();
Point pre_p = polygon[(index - 1 + size) % size];
Point next_p = polygon[(index + 1) % size];
Triangle t(convex_p, pre_p, next_p);
double min_d = double(INT_MAX);
bool flag = false;
Point min_p;
for (int i = 0; i < polygon.size(); ++i)
{
if (i == index || i == ((index - 1 + size) % size) || i == ((index + 1) % size))
continue;
flag = true;
if (distance(convex_p, polygon[i]) < min_d)
{
min_p = polygon[i];
min_d = distance(convex_p, polygon[i]);
}
}
// <20><><EFBFBD><EFBFBD>û<EFBFBD>ж<EFBFBD><D0B6><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ڲ<EFBFBD><DAB2><EFBFBD><EFBFBD>򷵻<EFBFBD>ǰ<EFBFBD><C7B0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>
if (!flag)
{
return div(add(pre_p, next_p), 2);
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>͹<EFBFBD><CDB9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>е<EFBFBD>
return div(add(convex_p, min_p), 2);
}
// 4.12<EFBFBD><EFBFBD><EFBFBD><EFBFBD>ȡ<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>εİ<EFBFBD>Χ<EFBFBD><EFBFBD><EFBFBD><EFBFBD>
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ε<EFBFBD><CEB5><EFBFBD>С<EFBFBD><D0A1>Χ<EFBFBD>У<EFBFBD><D0A3><EFBFBD><EFBFBD><EFBFBD><EFBFBD>º<EFBFBD><C2BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʾ
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> polygon : <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> down_left : <20><><EFBFBD>µ<EFBFBD> up_right : <20><><EFBFBD>ϵ<EFBFBD>
//
void boxOfPolygon(const vector<Point>& polygon, Point& down_left, Point& up_right)
{
double max_x = double(INT_MIN), min_x = double(INT_MAX);
double max_y = double(INT_MIN), min_y = double(INT_MAX);
for (auto c : polygon)
{
max_x = (c.x > max_x) ? c.x : max_x;
min_x = (c.x < min_x) ? c.x : min_x;
max_y = (c.y > max_y) ? c.y : max_y;
min_y = (c.y < min_y) ? c.y : min_y;
}
down_left = Point(min_x, min_y);
up_right = Point(max_x, max_y);
}
// <20>塢Բ
// 5.1<EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ<EFBFBD>Ĺ<EFBFBD>ϵ
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> c: Բ<><D4B2> radiuns <20><> Բ<>İ뾶 p : <20>жϵĵ<CFB5>
// <20><><EFBFBD><EFBFBD>ֵ <20><> 0 <20><> Բ<><D4B2> 1 <20><> Բ<><D4B2> 2<><32> Բ<><D4B2>
//
int pointToCircle(const Point& c, double radius, const Point& p)
{
double ptoc_d = distance(c, p);
if (ptoc_d < radius)
return 0;
else if (ptoc_d == radius)
return 1;
else
return 2;
}
// 5.2<EFBFBD><EFBFBD>ֱ<EFBFBD>ߺ<EFBFBD>Բ<EFBFBD>Ĺ<EFBFBD>ϵ
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> c: Բ<><D4B2> radiuns <20><> Բ<>İ뾶 l : <20>жϵ<D0B6>ֱ<EFBFBD><D6B1>
// <20><><EFBFBD><EFBFBD>ֵ <20><> 0 <20><> <20>ཻ 1 <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<><32> <20><><EFBFBD><EFBFBD>
//
int lineToCircle(const Point& c, double radius, const Line& l)
{
double ctol_d = ptolDistance(c, l);
if (ctol_d < radius)
return 0;
else if (ctol_d == radius)
return 1;
else
return 2;
}
// 5.3<EFBFBD><EFBFBD><EFBFBD>߶κ<EFBFBD>Բ<EFBFBD>Ĺ<EFBFBD>ϵ
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> c: Բ<><D4B2> radiuns <20><> Բ<>İ뾶 l : <20>жϵ<D0B6><CFB5>߶<EFBFBD>
// <20><><EFBFBD><EFBFBD>ֵ <20><> 0 <20><> Բ<><D4B2> 1 <20><> <20><>Բ<EFBFBD>ཻ 2<><32> Բ<><D4B2>
//
int segToCircle(const Point& c, double radius, const Line& l)
{
double ctol_d = ptolDistance(c, l);
if (ctol_d > radius)
return 2;
else if (ctol_d == radius)
return 1;
else
{
Point project_p = ptolProjection(c, l);
if (isponl(project_p, l))
return 1;
else
return 2;
}
}
// 5.4<EFBFBD><EFBFBD><EFBFBD><EFBFBD>Բ֮<EFBFBD><EFBFBD><EFBFBD>Ĺ<EFBFBD>ϵ
//
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD> c1 : Բ1Բ<31>ģ<EFBFBD>r1 Բ1<D4B2>뾶 c2 : Բ2Բ<32>ģ<EFBFBD>r2 Բ2<D4B2>
// <20><><EFBFBD><EFBFBD>ֵ<EFBFBD><D6B5>0 <20><><EFBFBD>ں<EFBFBD> 1<><31><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 2<><32><EFBFBD>ཻ 3<><33><EFBFBD><EFBFBD><EFBFBD><EFBFBD> 4<><34><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
//
int circleToCircle(const Point& c1, double r1, const Point& c2, double r2)
{
double ctoc_d = distance(c1, c2);
if (ctoc_d < abs(r1 - r2))
return 0;
else if (ctoc_d == abs(r1 - r2))
return 1;
else if (ctoc_d > abs(r1 - r2) && ctoc_d < (r1 + r2))
return 2;
else if (ctoc_d == (r1 + r2))
return 3;
else if (ctoc_d >(r1 + r2))
return 4;
}
}