• 计算几何 模板


    (更新中。。。。。。。)

    点 结构

    struct point
    {
        double x;//或为double
        double y;
    }

    浮点处理:

    1 int dbcmp(double x)
    2 {
    3     if(fabs(x) < eps) return 0;
    4 
    5     if(x < 0 ) return -1;
    6     else  return  1;
    7 }

    点乘:

    int betweencmp(point c,point a,point b)// c 是否在a ,b 间
     {
         return dbcmp(dot(c,a,b)) ;
     }

    double dotdet(double x1,double y1,double x2,double y2)
     {
          return x1*x2+y1*y2 ;
     }
     double dot(point a,point b,point c)
     {
        return  dotdet(b.x - a.x,b.y - a.y,c.x - a.x,c.y - a.y);
     }

    叉积:

    1 double  det(double x1,double y1,double x2,double y2)
    2  {
    3      return x1*y2 - x2*y1;
    4  }
    5  double  cross(point a,point b,point c)
    6  {
    7      return det(b.x - a.x,b.y - a.y,c.x - a.x,c.y - a.y);
    8  }

     多边形的面积:

     1 double area(point p[])
     2 {
        注意 p[]中的点按 顺时针或逆时针 排 ,一般按 逆时针

        double s = 0;
     4     p[n].x = p[0].x;//以 (0,0) 为 跟点 ,也可以多边形边点为 跟点(利用 有向面积 的和)
     5     p[n].y = p[0].y ;
     6     for(int i = 0; i<n;i++)
     7     {
     8         s+=det(p[i].x,p[i].y,p[i+1].x,p[i+1].y);
     9 
    10     }
    11 
    12     return fabs(s*0.5);
    13 }

     

    线段和线段的交点

    point get (point a,point b,point c,point d)
     {
         point q;
         double s1, s2,s3,s4;
         int d1,d2,d3,d4;



         d1 = dbcmp(s1 = cross(a,b,c));
         d2 = dbcmp(s2 = cross(a,b,d));
         d3 = dbcmp(s3 = cross(c,d,a));
         d4 = dbcmp(s4 = cross(c,d,b));


         if((d1^d2) == -2 &&(d3^d4) == -2)//规范相交
         {

             q.x  = (c.x*s2 - d.x*s1)/(s2 - s1) ;// 求 交点 的 x 坐标
             q.y  = (c.y*s2 - d.y*s1)/(s2 - s1) ;// 求 交点 的 y 坐标

             return q ;
         }

         if(d1 == 0 && betweencmp(c,a,b) <= 0 ||         //非规范相交
            d2 == 0 && betweencmp(d,a,b) <= 0 ||
            d3 == 0 && betweencmp(a,c,d) <= 0 ||
            d4 == 0 && betweencmp(b,c,d) <= 0
            )
            {

                 q.x  = (c.x*s2 - d.x*s1)/(s2 - s1) ;// 求 交点 的 x 坐标
                 q.y  = (c.y*s2 - d.y*s1)/(s2 - s1) ;// 求 交点 的 y 坐标
                 return q ;
            }



     }

    直线和线段的交点 

    1 double getxy(point a,point b,point c,point d)//  a,b 代表直线 ,c,d 代表 线段
    2 {
         
    // 判断是否相交 用 叉积 就可以了

         double s1 = cross(a,b,c);
    4     double s2 = cross(a,b,d);
    5 
    6     x =  (c.x*s2 - d.x*s1)/(s2 - s1) ;// 求 交点 的 x 坐标
    7     y =  (c.y*s2 - d.y*s1)/(s2 - s1) ;// 求 交点 的 y 坐标
    8 }

     凸包 graham法:


    int cmp(point a,point b)
    {
        if(a.y != b.y) return a.y < b.y;
        else return a.x < b.x;
    }
    void graham()
    {

        int  i,len;
        top = 0;
        sort(p,p+n,cmp);

        if(n == 0return ;
        if(n == 1return ;
        stack[top++] = p[0];//stack[] 为 point 栈
        stack[top++] = p[1];
        for(i = 2 ;i<n;i++)//求右链
        {
            while(top > 1&& cross(stack[top - 1],stack[top - 2],p[i]) >= 0) top--;  //  >= 0 这 改为 > 0 可以 不去除  共线点    //注意 top 要 > 1

            stack[top++] = p[i];
        }

         //dblcmp(cross(p[stack[top - 1]],p[stack[top - 2]],p[i])) 可以直接是 cross
        len =  top ;

        for(i = n - 2;i >= 0;i--)//求左链
        {
             while(top > len && cross(stack[top - 1],stack[top - 2],p[i]) >= 0)top--;
             stack[top++] = p[i];

        }
        top--;//第一个点入栈两次 所以 减 1

    }
  • 相关阅读:
    HTML5画的简单时钟
    JS操作网页中的iframe
    JS垂直落体回弹原理
    JS回弹原理高级
    待续...
    JS拖拽面向对象拖拽继承
    JS简单回弹原理
    c++快速排序(从大到小greater/从小到大less)
    搜索素数环
    搜索组合数
  • 原文地址:https://www.cnblogs.com/acSzz/p/2656941.html
Copyright © 2020-2023  润新知