之前学了一下下C++ 的OOP,然后跑过来跟着竞赛书把计算几何学的模板补好了!不得不说代码量是真的大!
利用了类的封装,方法重载,操作符重载等。
这里的范数应该是范2(模长概念?) ,书上的范数是模长的平方
assert()那里,要保证有相交才能保证有交点。
///存储:点 向量 线段 直线 圆
///点操作:內积,外积,equals与== 相等,+操作 -操作
///直线与直线的正交判断dot = 0 平行判断 cross = 0
///点到直线的投影,点与直线的映像点
///三个点的逆时针ccw
///判断俩线段是否相交
///求两个点之间距离Distance,点与直线距离DistancePL,点与线段距离DistancePS,两个线段之间距离Distance
///求两个线段的交点CrossPoint,圆与直线的交点CrossPoints,圆与圆的交点CrossPoints
#include <bits/stdc++.h>
#define show(x) std::cerr << #x << "=" << x << std::endl;
#define IOS ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
typedef long long ll;
const int MAX = 300500;
const int INF = 1e9;
const long long MOD = 998244353;
const double EPS = (1e-10);
class Point{ ///Point
public:
double x,y;
Point(double x=0,double y=0):x(x),y(y){}
Point operator + (Point p){
return Point(x+p.x,y+p.y);
}
Point operator - (Point p){
return Point(x-p.x,y-p.y);
}
Point operator * (double k){
return Point(x*k,y*k);
}
Point operator / (double k){
return Point(x/k,y/k);
}
bool operator == (const Point &p)const{
return fabs(x-p.x)<EPS && fabs(y-p.y)<EPS;
}
double norm(){
return sqrt(x*x+y*y);
}
friend ostream& operator <<(ostream& os,Point p){
os << "p.x = " << p.x << " p.y = " << p.y << endl;
return os;
}
};
double dot(Point a,Point b){ ///orthogonal : dot = 0
return a.x*b.x+a.y*b.y;
}
double cross(Point a,Point b){ ///parallel : cross = 0
return a.x*b.y-a.y*b.x;
}
bool equals(Point a,Point b){
return (((a)-(b)).norm()<EPS);
}
typedef Point Vector; ///Vector
class Segment{
public:
Point p1,p2;
Segment(Point p1 = Point(),Point p2 = Point()):p1(p1),p2(p2){}
};
///struct Segment{Point p1,p2;}; ///Segment
typedef Segment Line; ///Line
Point Project(Point p,Segment s){
Vector base = s.p2-s.p1;
double r = dot(p-s.p1,base)/base.norm()/base.norm();
return (s.p1 + base * r);
}
Point Reflect(Point p,Segment s){
return p + (Project(p,s)-p)*2.0;
}
static const int COUNTER_CLOCKWISE = 1;
static const int CLOCKWISE = -1;
static const int ONLINE_BACK = 2;
static const int ONLINE_FRONT = -2;
static const int ON_SEGMENT = 0;
int ccw(Point p0,Point p1,Point p2){
Vector a = p1 - p0;
Vector b = p2 - p0;
if(cross(a,b)>EPS)return COUNTER_CLOCKWISE;
if(cross(a,b)<-EPS)return CLOCKWISE;
if(dot(a,b)<-EPS)return ONLINE_BACK;
if(a.norm()<b.norm())return ONLINE_FRONT;
return ON_SEGMENT;
}
bool intersect(Point p1,Point p2,Point p3,Point p4){
return (ccw(p1,p2,p3)*ccw(p1,p2,p4)<=0 &&
ccw(p3,p4,p1)*ccw(p3,p4,p2)<=0);
}
bool intersect(Segment s1,Segment s2){
return intersect(s1.p1,s1.p2,s2.p1,s2.p2);
}
double Distance(Point a,Point b){
return (a-b).norm();
}
double DistancePL(Point p,Line l){
return abs(cross(l.p2 - l.p1,p - l.p1) / (l.p2-l.p1).norm());
}
double DistancePS(Point p,Segment s){
if(dot(s.p2 - s.p1 ,p - s.p1) < 0.0)return (p-s.p1).norm();
if(dot(s.p1 - s.p2 ,p - s.p2) < 0.0)return (p-s.p2).norm();
return DistancePL(p,s);
}
double Distance(Segment s1,Segment s2){
if(intersect(s1,s2))return 0.0;
return min(min(DistancePS(s2.p1,s1),DistancePS(s2.p2,s1)),
min(DistancePS(s1.p1,s2),DistancePS(s1.p2,s2)));
}
Point CrossPoint(Segment s1,Segment s2){
Vector base = s2.p2 - s2.p1;
double d1 = abs(cross(base, s1.p1 - s2.p1));
double d2 = abs(cross(base, s1.p2 - s2.p1));
double t = d1/(d1+d2);
return s1.p1 + (s1.p2 - s1.p1)*t;
}
typedef vector<Point>Polygon; ///Polygon
class Circle{ ///Circle
public:
Point c;
double r;
Circle(Point c = Point(),double r=0.0):c(c),r(r){}
friend ostream& operator <<(ostream& os,Circle d){
os << "c.x = " << d.c.x << " c.y = " << d.c.y << " c.r = " << d.r << endl;
return os;
}
};
pair<Point,Point> CrossPoints(Circle c,Line l){
///assert(intersect(c,l));
Vector pr = Project(c.c,l);
Vector e = (l.p2 - l.p1)/ (l.p2-l.p1).norm();
double base = sqrt(c.r * c.r - (pr - c.c).norm() * (pr - c.c).norm());
return make_pair(pr + e*base , pr - e*base);
}
double arg(Vector p){return atan2(p.y,p.x);}
Vector polar(double a,double r){return Point(cos(r)*a,sin(r)*a);}
pair<Point,Point>CrossPoints(Circle c1, Circle c2){
///assert(intersect(c1,c2));
double d = (c1.c-c2.c).norm();
double a = acos((c1.r * c1.r + d * d - c2.r * c2.r)/(2 * c1.r * d));
double t = arg(c2.c - c1.c);
return make_pair(c1.c + polar(c1.r,t+a),c1.c + polar(c1.r,t-a));
}
int main()
{
IOS;
Point P1(1,1),P2(2,3),P3,P4,P5;
P3 = P1 + P2;
P4 = P1 - P2;
P5 = P1*5;
cout << P1 << P2 << P3 << P4 << P5;
show(P1.norm());
show(equals(P1,P2));
show(equals(P1,P1));
if(P1==P2)cout << "1 2 EQ" <<endl;
if(P1==P1)cout << "1 1 EQ" <<endl;
Point P6(2,5);
Segment S1;
S1.p1 = Point(0,0);
S1.p2 = Point(3,4);
show(Distance(P1,P2));
cout << Project(P6,S1);
cout << Reflect(P6,S1);
Vector V1(2,3);
show(V1.x);
show(V1.y);
Circle C1(Point(2,1),1);
Line L1(Point(0,1),Point(4,1));
pair<Point,Point> PP;
PP = CrossPoints(C1,L1);
cout << C1;
show(PP.first.x);
show(PP.first.y);
show(PP.second.x);
show(PP.second.y);
Circle C2(Point(0,0),2);
Circle C3(Point(2,0),2);
pair<Point,Point> PP2;
PP2 = CrossPoints(C2,C3);
show(PP2.first.x);
show(PP2.first.y);
show(PP2.second.x);
show(PP2.second.y);
return 0;
}
/**
*/