【C++代码 简单好用的 计算几何学 模板】一些点 线 圆的基本操作

之前学了一下下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;
}
/**

*/

的基本运算 1. 平面上两之间距离 1 2. 判断两是否重合 1 3. 矢量叉乘 1 4. 矢量乘 2 5. 判断是否在线段上 2 6. 求一饶某旋转后的坐标 2 7. 求矢量夹角 2 ㈡ 线段及直线的基本运算 1. 线段的关系 3 2. 求线段所在直线线的垂足 4 3. 线段的最近 4 4. 线段所在直线的距离 4 5. 到折线集的最近距离 4 6. 判断是否在多边形内 5 7. 求矢量夹角余弦 5 8. 求线段之间的夹角 5 9. 判断线段是否相交 6 10.判断线段是否相交但不交在端处 6 11.求线段所在直线的方程 6 12.求直线的斜率 7 13.求直线的倾斜角 7 14.求关于某直线的对称 7 15.判断两条直线是否相交及求直线 7 16.判断线段是否相交,如果相交返回交 7 ㈢ 多边形常用算法模块 1. 判断多边形是否简单多边形 8 2. 检查多边形顶的凸凹性 9 3. 判断多边形是否凸多边形 9 4. 求多边形面积 9 5. 判断多边形顶的排列方向,方法一 10 6. 判断多边形顶的排列方向,方法二 10 7. 射线法判断是否在多边形内 10 8. 判断是否在凸多边形内 11 9. 寻找集的graham算法 12 10.寻找集凸包的卷包裹法 13 11.判断线段是否在多边形内 14 12.求简单多边形的重心 15 13.求凸多边形的重心 17 14.求肯定在给定多边形内的一个 17 15.求从多边形外一出发到该多边形的切线 18 16.判断多边形的核是否存在 19 ㈣ 的基本运算 1 .是否在内 20 2 .求不共线的三所确定的 21 ㈤ 矩形的基本运算 1.已知矩形三坐标,求第4坐标 22 ㈥ 常用算法的描述 22 ㈦ 补充 1.两关系: 24 2.判断是否在矩形内: 24 3.到平面的距离: 25 4.是否在直线同侧: 25 5.镜面反射线: 25 6.矩形包含: 26 7.两: 27 8.两公共面积: 28 9. 和直线关系: 29 10. 内切: 30 11. 求切: 31 12. 线段的左右旋: 31
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值