zoukankan      html  css  js  c++  java
  • 计算几何模板

    #include<iostream>
    #include<cstdio>
    #include<cmath>
    using namespace std;
    #define EPS 1e-8
    
    struct Point{
        double x,y;
        Point(){}
        Point(double xx, double yy):x(xx), y(yy){}
    };
    
    struct Line{
        Point a,b;
    };
    
    /*
        向量p0p1与p0p2的叉积
        =0说明三点共线
        >0则p0p2在p0p1的逆时针方向
        <0则p0p2在p0p1的顺时针方向
    */
    double xmult(Point p1, Point p2, Point p0)
    {
        return (p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
    }
    
    //两点距离
    double dis(Point p1, Point p2)
    {
        double x = p1.x-p2.x;
        double y = p1.y-p2.y;
        return sqrt(x*x+y*y);
    }
    
    //p点到直线ab的距离
    double disptoline(Point p, Point a, Point b)
    {
        //fabs(xmult(p,a,b))是以pa,pb为邻边的平行四边形面积
        return fabs(xmult(p,a,b))/dis(a,b);
    }
    //两条直线的交点,注意判断直线是否平行或重合
    Point intersection(Point A, Point B, Point C, Point D)
    {
        //a1*x+b1*y=c1;a2*x+b2*y=c2;
        //得到直线的3个系数
        double a1 = A.y-B.y;
        double b1 = B.x-A.x;
        double c1 = A.x*B.y-B.x*A.y;
        double a2 = C.y-D.y;
        double b2 = D.x-C.x;
        double c2 = C.x*D.y-D.x*C.y;
        double x = (b1*c2-b2*c1)/(a1*b2-a2*b1);
        double y = (a2*c1-a1*c2)/(a1*b2-a2*b1);
        return Point(x,y);
    }
    
    //点到直线上的最近点
    Point ptoline(Point p,Line l)
    {
        Point t=p;
        t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
        return intersection(p,t,l.a,l.b);
    }
    //点是否在线段l上
    bool pisonline(Line l,Point p)
    {
        return( (xmult(l.a,l.b,p)==0) &&( ( (p.x-l.a.x)*(p.x-l.b.x)<=0 )&&( (p.y-l.a.y)*(p.y-l.b.y)<=0 ) ) );
    }
    //点到线段上的最近点
    Point ptoseg(Point p,Line l)
    {
         Point t=p;
         t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
         if(xmult(l.a,t,p)*xmult(l.b,t,p)>EPS)
             return dis(p,l.a)<dis(p,l.b)?l.a:l.b;
         return intersection(p,t,l.a,l.b);
    }
    //点到线段距离
    double disptoseg(Point p,Line l)
    {
         Point t=p;
         t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
         if(xmult(l.a,t,p)*xmult(l.b,t,p)>EPS)
             return dis(p,l.a)<dis(p,l.b)?dis(p,l.a):dis(p,l.b);
        return fabs(xmult(p,l.a,l.b))/dis(l.a,l.b);
     }
    
    
    //判断直线是否重合
    bool isSame(Point A,Point B,Point C,Point D)
    {
        if(fabs(xmult(A,B,C))<=EPS&&fabs(xmult(A,B,D))<=EPS)
            return true;
        return false;
    }
    //判断直线是否平行,判断平行之前先判断是否重合
    bool isParallel(Point A,Point B,Point C,Point D)
    {
        if((A.y-B.y)*(D.x-C.x)==(B.x-A.x)*(C.y-D.y))
            return true;
        return false;
    }
    //根据圆周上的三点,求出圆心
    Point getCir(Point a,Point b,Point c)
    {
        Line u,v;
        u.a.x = (a.x+b.x)/2;
        u.a.y = (a.y+b.y)/2;
        u.b.x = u.a.x-a.y+b.y;
        u.b.y = u.a.y+a.x-b.x;
        v.a.x = (a.x+c.x)/2;
        v.a.y = (a.y+c.y)/2;
        v.b.x = v.a.x-a.y+c.y;
        v.b.y = v.a.y+a.x-c.x;
        return intersection(u.a, u.b, v.a, v.b);
    }
    
    //判断线段ab与线段cd是否相交
    bool SegIntersection(Point a, Point b, Point c, Point d)  //判断线段相交
    {
    	if (min(a.x, b.x) <= max(c.x, d.x) &&
    		min(a.y, b.y) <= max(c.y, d.y) &&
    		min(c.x, d.x) <= max(a.x, b.x) &&
    		min(c.y, d.y) <= max(a.y, b.y) &&
    		xmult(a, b, c) * xmult(a, b, d) <= EPS &&
    		xmult(c, d, a) * xmult(c, d, b) <= EPS)
    		return true;
    	return false;
    }
    
  • 相关阅读:
    mybatis设置添加新对象数据的时候id使用uuid类型自动写入数据库
    mysql大小写敏感配置
    linux中iproute2工具介绍
    openwrt中补丁命名规则
    Java: ThreadLocal 用法详解和原理(转)
    Git: tag 标签操作
    android: 详解 Android 中的 HandlerThread(转)
    android: drawable中同时设置state_enabled和和state_pressed不起作用的问题
    C语言:记录32bit数据的一些常用位操作
    android: 分享一个带多行选择功能的RadioGroup
  • 原文地址:https://www.cnblogs.com/wt20/p/5802882.html
Copyright © 2011-2022 走看看