|
|
|
|
// 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;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|