计算几何基础

constexpr long double EPS = 1E-10;
const long double PI = acos(-1.0);
using T = long double;

点, 向量 都用point来表示

struct Point {
    T x = 0, y = 0;
    Point operator+(const Point &o) const {return {x + o.x, y + o.y};}
    Point operator-(const Point &o) const {return {x - o.x, y - o.y};}
    Point operator-() const {return {-x, -y};}
    Point operator*(T fac) const {return {x * fac, y * fac};}
    Point operator/(T fac) const {return {x / fac, y / fac};}
    bool operator<(const Point &o) const {
        return std::tie(x, y) < std::tie(o.x, o.y);
    }
    friend std::istream &operator>>(std::istream &is, Point &p) {
        return is >> p.x >> p.y;
    }
    friend std::ostream &operator<<(std::ostream &os, Point p) {
        return os << "(" << p.x << ", " << p.y << ")";
    }
};

向量点积 a\cdot b = \left | a \right |\left | b \right |\cos\theta = a.x * b.x + a.y * b.y

T dot(const Point &a, const Point &b) { // 计算点积
    return a.x * b.x + a.y * b.y;
}
T angle(const Point &a, const Point &b) { // 求夹角 (弧度制)
    return acosl(dot(a, b) / len(a) / len(b));
}

向量叉积 a\times b = \left | a \right |\left | b \right |\sin\theta = a.x * b.y - a.y * b.x

几何意义: 两向量所张成的平行四边形的有向面积, b在a逆时针为正, 顺时针为负

T cross(const Point &a, const Point &b) { // 两向量叉积
    return a.x * b.y - a.y * b.x;
}
T cross(const Point &a, const Point &b, const Point &c) { 
    return cross(b - a, c - a);                          
    // ab向量与ac向量的叉积
 // c在直线ab左侧 > 0, 右侧 < 0, 共线 = 0 
}

向量模长

T len(const Point &a) { // 求模长
    return sqrtl(a.x * a.x + a.y * a.y);
}

两点距离

T dis2(const Point &a, const Point &b) { // 距离的平方
    return (a.x - b.x) * (a.x - b.x) + (a.y - b.y) * (a.y - b.y);
}
T dis(const Point &a, const Point &b) { // 距离
    return sqrtl(dis2(a, b));
}

向量夹角

T angle(const Point &a, const Point &b) { // 求夹角 
    return acosl(dot(a, b) / len(a) / len(b)); //(弧度制) [0, π]
    return acosl(dot(a, b) / len(a) / len(b)) * (180 / PI); // 转化为角度制 [0, 180]
}

点在向量的哪边

T cross(const Point &a, const Point &b, const Point &c) { // ab向量与ac向量的叉积
    return cross(b - a, c - a);                           // c在直线ab左侧 > 0,
                                                          // 右侧 < 0, 共线 = 0 
}

逆转角

Point rotate(const Point &a, const Point &b, T theta) {  // 逆转角, ab向量逆时针
                                                         //旋转theta度,ac为转后向量
                                                        // c为返回值
    return {
        (b.x - a.x) * cosl(theta) - (b.y - a.y) * sinl(theta) + a.x,
        (b.x - a.x) * sinl(theta) + (b.y - a.y) * cosl(theta) + a.y
    };
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值