几何板子

板子成长史

const int N=1e6+5;
struct point
{
    double x,y;
};
struct line
{
    point p1,p2;
} s[N];
double height(line a,int x)///计算直线某点y坐标
{
    if(a.p1.x==a.p2.x)
        return a.p1.y;
    double k=(a.p1.y-a.p2.y)*1.0/(a.p1.x-a.p2.x);
    double b=a.p1.y-k*a.p1.x;
    return k*x+b;
}
double Point_distance(point a,point b)///线段距离
{
    return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
}
bool circle(point a,double r,point b)///是否在圆内
{
    return Point_distance(a,b)<=r;
}
double line_sin(point a,point b)///线段长度不能为0
{
    return (a.y-b.y)/Point_distance(a,b);
}
double line_cos(point a,point b)///线段长度不能为0
{
    return (a.x-b.x)/Point_distance(a,b);
}

坐标+向量

const double eps = 1e-7;
const double pi = acos(-1.0);

int dcmp(double x)
{
    if (fabs(x) < eps)
        return 0;
    return (x < 0 ? -1 : 1);
}
inline double sqr(double x)
{
    return x * x;
}

//*************点
struct Point
{
    double x, y;
    Point(double _x = 0, double _y = 0) : x(_x), y(_y) {}
    void input()
    {
        cin>>x>>y;
    }
    void output()
    {
        printf("%.2f %.2f\n", x, y);
    }
    bool operator==(const Point &b) const
    {
        return (dcmp(x - b.x) == 0 && dcmp(y - b.y) == 0);
    }
    bool operator<(const Point &b) const
    {
        return (dcmp(x - b.x) == 0 ? dcmp(y - b.y) < 0 : x < b.x);
    }
    Point operator+(const Point &b) const
    {
        return Point(x + b.x, y + b.y);
    }
    Point operator-(const Point &b) const
    {
        return Point(x - b.x, y - b.y);
    }
    Point operator*(double a)
    {
        return Point(x * a, y * a);
    }
    Point operator/(double a)
    {
        return Point(x / a, y / a);
    }
    double len2()    //返回长度的平方
    {
        return sqr(x) + sqr(y);
    }
    double len()    //返回长度
    {
        return sqrt(len2());
    }
    Point change_len(double r)    //转化为长度为r的向量
    {
        double l = len();
        if (dcmp(l) == 0)
            return *this;  //零向量返回自身
        r /= l;
        return Point(x * r, y * r);
    }
    Point rotate_left()    //顺时针旋转90度
    {
        return Point(-y, x);
    }
    Point rotate_right()    //逆时针旋转90度
    {
        return Point(y, -x);
    }
    Point rotate(Point p, double ang)    //绕点p逆时针旋转ang
    {
        Point v = (*this) - p;
        double c = cos(ang), s = sin(ang);
        return Point(p.x + v.x * c - v.y * s, p.y + v.x * s + v.y * c);
    }
    Point normal()    //单位法向量
    {
        double l = len();
        return Point(-y / l, x / l);
    }
};

double cross(Point a, Point b)    //叉积
{
    return a.x * b.y - a.y * b.x;
}
double dot(Point a, Point b)    //点积
{
    return a.x * b.x + a.y * b.y;
}
double dis(Point a, Point b)    //两个点的距离
{
    Point p = b - a;
    return p.len();
}
double degree_rad(double ang)    //角度转化为弧度
{
    return ang / 180 * pi;
}
double rad_degree(double rad)    //弧度转化为角度
{
    return rad / pi * 180;
}
double rad(Point a, Point b)    //两个向量的夹角
{
    return fabs(atan2(fabs(cross(a, b)), dot(a, b)));
}
bool parallel(Point a, Point b)    //向量平行
{
    double p = rad(a, b);
    return dcmp(p) == 0 || dcmp(p - pi) == 0;
}
Point Circum(Point a,Point b,Point c){ //已知圆上三点求圆心
    double x1=a.x,y1=a.y;
    double x2=b.x,y2=b.y;
    double x3=c.x,y3=c.y;

    double a1=2*(x2-x1);
    double b1=2*(y2-y1);
    double c1=x2*x2+y2*y2-x1*x1-y1*y1;

    double a2=2*(x3-x2);
    double b2=2*(y3-y2);
    double c2=x3*x3+y3*y3-x2*x2-y2*y2;

    double x=(c1*b2-c2*b1)/(a1*b2-a2*b1);
    double y=(a1*c2-a2*c1)/(a1*b2-a2*b1);

    return Point(x,y);
}

直线+线段

//************直线 线段
struct Line
{
    Point s, e;  //直线的两个点
    double k;    //极角 范围[-pi,pi]
    Line() {}
    Line(Point _s, Point _e)
    {
        s = _s, e = _e;
        k = atan2(e.y - s.y, e.x - s.x);
    }
    // ax+by+c = 0
    Line(double a, double b, double c)
    {
        if (dcmp(a) == 0)
        {
            s = Point(0, -c / b);
            e = Point(1, -c / b);
        }
        else if (dcmp(b) == 0)
        {
            s = Point(-c / a, 0);
            e = Point(-c / a, 1);
        }
        else
        {
            s = Point(0, -c / b);
            e = Point(1, (-c - a) / b);
        }
        get_angle();
    }
    //一个点和倾斜角确定直线
    Line(Point p, double ang)
    {
        k = ang;
        s = p;
        if (dcmp(ang - pi / 2) == 0)
        {
            e = s + Point(0, 1);
        }
        else
            e = s + Point(1, tan(ang));
    }
    void input()
    {
        s.input();
        e.input();
    }
    void output()
    {
        printf("%.2f,%.2f %.2f,%.2f\n", s.x, s.y, e.x, e.y);
    }
    void adjust()
    {
        if (e < s)
            swap(e, s);
    }
    double length()    //求线段长度
    {
        return dis(s, e);
    }
    void get_angle()
    {
        k = atan2(e.y - s.y, e.x - s.x);
    }
    double angle()    //直线的倾斜角
    {
        if (dcmp(k) < 0)
            k += pi;
        if (dcmp(k - pi) == 0)
            k -= pi;
        return k;
    }
    Point operator&(const Line &b) const    //直线的交点(保证存在)
    {
        Point res = s;
        double t = (cross(s - b.s, b.s - b.e)) / cross(s - e, b.s - b.e);
        res.x += (e.x - s.x) * t;
        res.y += (e.y - s.y) * t;
        return res;
    }
};

int relation(Point p, Line l)    //点和直线的关系
{
    // 1:在左侧 2:在右侧 3:在直线上
    int c = dcmp(cross(p - l.s, l.e - l.s));
    if (c < 0)
        return 1;
    else if (c > 0)
        return 2;
    else
        return 3;
}

bool point_on_halfline(Point p, Line l)    //判断点在射线上
{
    int id = relation(p, l);
    if (id != 3)
        return 0;
    return dcmp(dot(p - l.s, l.e - l.s)) >= 0;
}

bool point_on_seg(Point p, Line l)    //判断点在线段上
{
    return dcmp(cross(p - l.s, l.e - l.s)) == 0 &&
           dcmp(dot(p - l.s, p - l.e)) <= 0;
    //如果忽略端点交点改成小于号就好了
}

bool parallel(Line a, Line b)    //直线平行
{
    return parallel(a.e - a.s, b.e - b.s);
}

int seg_cross_seg(Line a, Line v)    //线段相交判断
{
    // 2:规范相交 1:不规范相交 0:不相交
    int d1 = dcmp(cross(a.e - a.s, v.s - a.s));
    int d2 = dcmp(cross(a.e - a.s, v.e - a.s));
    int d3 = dcmp(cross(v.e - v.s, a.s - v.s));
    int d4 = dcmp(cross(v.e - v.s, a.e - v.s));
    if ((d1 ^ d2) == -2 && (d3 ^ d4) == -2)
        return 2;
    return (d1 == 0 && dcmp(dot(v.s - a.s, v.s - a.e)) <= 0) ||
           (d2 == 0 && dcmp(dot(v.e - a.s, v.e - a.e)) <= 0) ||
           (d3 == 0 && dcmp(dot(a.s - v.s, a.s - v.e)) <= 0) ||
           (d4 == 0 && dcmp(dot(a.e - v.s, a.e - v.e)) <= 0);
}

int line_cross_seg(Line a, Line v)    //直线和线段相交判断 a直线v线段
{
    // 2:规范相交 1:非规范相交 0:不相交
    int d1 = dcmp(cross(a.e - a.s, v.s - a.s));
    int d2 = dcmp(cross(a.e - a.s, v.e - a.s));
    if ((d1 ^ d2) == -2)
        return 2;
    return (d1 == 0 || d2 == 0);
}

int line_cross_line(Line a, Line v)    //直线相交判断
{
    // 0:平行 1:重合 2:相交
    if (parallel(a, v))
        return relation(a.e, v) == 3;
    return 2;
}

Point line_intersection(Line a, Line v)    //直线交点
{
    //调用前确保有交点
    double a1 = cross(v.e - v.s, a.s - v.s);
    double a2 = cross(v.e - v.s, a.e - v.s);
    return Point((a.s.x * a2 - a.e.x * a1) / (a2 - a1),
                 (a.s.y * a2 - a.e.y * a1) / (a2 - a1));
}

int seg_intersectiong(Line a, Line b, Point &p)    //求线段交点
{
    // 0:没有交点 1:规范相交 2:非规范相交
    //调用前确包只有一个交点
    int rel = seg_cross_seg(a, b);
    if (rel == 0)
        return 0;
    int cnt = 0;
    if (rel == 1)
    {
        if (point_on_seg(a.e, b))
            p = a.e, cnt++;
        if (point_on_seg(a.s, b))
            p = a.s, cnt++;
        if (point_on_seg(b.e, a))
            p = b.e, cnt++;
        if (point_on_seg(b.s, a))
            p = b.s, cnt++;
        return 2;
    }
    p = line_intersection(a, b);
    return 1;
}

double point_to_line(Point p, Line a)    //点到直线的距离
{
    return fabs(cross(p - a.s, a.e - a.s) / a.length());
}

double point_to_seg(Point p, Line a)    //点到线段的距离
{
    if (dcmp(dot(p - a.s, a.e - a.s)) < 0 || dcmp(dot(p - a.e, a.s - a.e)) < 0)
        return min(dis(p, a.e), dis(p, a.s));
    return point_to_line(p, a);
}

Point projection(Point p, Line a)    //点在直线上的投影
{
    return a.s + (((a.e - a.s) * dot(a.e - a.s, p - a.s)) / (a.e - a.s).len2());
}

Point symmetry(Point p, Line a)    //点关于直线的对称点
{
    Point q = projection(p, a);
    return Point(2 * q.x - p.x, 2 * q.y - p.y);
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值