• hdu 2857 求点关于线段的对称点


    本来很简单的一个题,但是有个大坑:

    因为模板中Tline用到了直线的一般方程ax+by+c=0,所以有种很坑的情况需要特判:

    斜率不存在啊喂

    老子坑了一下午2333

      1 #include <math.h>
      2 #include <stdio.h>
      3 
      4    #define eps 1e-6
      5    #define PI acos(-1.0)//3.14159265358979323846
      6    //判断一个数是否为0,是则返回true,否则返回false
      7    #define zero(x)(((x)>0?(x):-(x))<eps)
      8    //返回一个数的符号,正数返回1,负数返回2,否则返回0
      9    #define _sign(x)((x)>eps?1:((x)<-eps?2:0))
     10 
     11   struct point
     12   {
     13       double x,y;
     14       point(){}
     15       point(double xx,double yy):x(xx),y(yy)
     16       {}
     17   };
     18   struct line
     19   {
     20       point a,b;
     21       line(){}      //默认构造函数
     22       line(point ax,point bx):a(ax),b(bx)
     23       {}
     24   };//直线通过的两个点,而不是一般式的三个系数
     25   struct TLine
     26   {
     27       double a,b,c;
     28       TLine(){}
     29       TLine(double _a,double _b,double _c):a(_a),b(_b),c(_c)
     30       {}
     31   };//直线一般式的三个系数ax+by+c=0
     32   struct TPoint
     33   {
     34       double x,y;
     35       TPoint(){}
     36       TPoint(double _x,double _y):x(_x),y(_y)
     37       {}
     38       TPoint operator-(TPoint&a)
     39       {
     40           TPoint p1;
     41           p1.x=x-a.x;
     42           p1.y=y-a.y;
     43           return p1;
     44       }
     45   };
     46 
     47    //求矢量[p0,p1],[p0,p2]的叉积
     48    //p0是顶点
     49    //若结果等于0,则这三点共线
     50    //若结果大于0,则p0p2在p0p1的逆时针方向
     51    //若结果小于0,则p0p2在p0p1的顺时针方向
     52    double xmult(point p1,point p2,point p0)
     53    {
     54        return(p1.x-p0.x)*(p2.y-p0.y)-(p2.x-p0.x)*(p1.y-p0.y);
     55    }
     56    //计算dotproduct(P1-P0).(P2-P0)
     57    double dmult(point p1,point p2,point p0)
     58    {
     59        return(p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
     60    }
     61    //两点距离
     62    double distance(point p1,point p2)
     63    {
     64        return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
     65    }
     66    //判三点共线
     67    int dots_inline(point p1,point p2,point p3)
     68    {
     69        return zero(xmult(p1,p2,p3));
     70    }
     71    //判点是否在线段上,包括端点
     72    int dot_online_in(point p,line l)
     73    {
     74        return zero(xmult(p,l.a,l.b))&&(l.a.x-p.x)*(l.b.x-p.x)<eps&&(l.a.y-p.y)*(l.b.y-p.y)<eps;
     75    }
     76    //判点是否在线段上,不包括端点
     77    int dot_online_ex(point p,line l)
     78    {
     79        return dot_online_in(p,l)&&(!zero(p.x-l.a.x)||!zero(p.y-l.a.y))&&(!zero(p.x-l.b.x)||!zero(p.y-l.b.y));
     80    }
     81    //判两点在线段同侧,点在线段上返回0
     82    int same_side(point p1,point p2,line l)
     83    {
     84        return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;
     85    }
     86    //判两点在线段异侧,点在线段上返回0
     87    int opposite_side(point p1,point p2,line l)
     88    {
     89        return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;
     90    }
     91    //判两直线平行
     92    int parallel(line u,line v)
     93    {
     94        return zero((u.a.x-u.b.x)*(v.a.y-v.b.y)-(v.a.x-v.b.x)*(u.a.y-u.b.y));
     95    }
     96    //判两直线垂直
     97    int perpendicular(line u,line v)
     98    {
     99        return zero((u.a.x-u.b.x)*(v.a.x-v.b.x)+(u.a.y-u.b.y)*(v.a.y-v.b.y));
    100    }
    101    //判两线段相交,包括端点和部分重合
    102    int intersect_in(line u,line v)
    103    {
    104        if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))
    105            return!same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);
    106        return dot_online_in(u.a,v)||dot_online_in(u.b,v)||dot_online_in(v.a,u)||dot_online_in(v.b,u);
    107    }
    108    //判两线段相交,不包括端点和部分重合
    109    int intersect_ex(line u,line v)
    110    {
    111        return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);
    112    }
    113    //计算两直线交点,注意事先判断直线是否平行!
    114    //线段交点请另外判线段相交(同时还是要判断是否平行!)
    115    point intersection(line u,line v)
    116    {
    117        point ret=u.a;
    118        double t=((u.a.x-v.a.x)*(v.a.y-v.b.y)-(u.a.y-v.a.y)*(v.a.x-v.b.x))/((u.a.x-u.b.x)*(v.a.y-v.b.y)-(u.a.y-u.b.y)*(v.a.x-v.b.x));
    119        ret.x+=(u.b.x-u.a.x)*t;
    120        ret.y+=(u.b.y-u.a.y)*t;
    121        return ret;
    122    }
    123    /*
    124    //点到直线上的最近点
    125    point ptoline(point p,line l)
    126    {
    127        point t=p;
    128        t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
    129        return intersection(p,t,l.a,l.b);
    130   }
    131   //点到直线距离
    132   double disptoline(point p,line l)
    133   {
    134       return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);
    135   }
    136   //点到线段上的最近点
    137   point ptoseg(point p,line l)
    138   {
    139       point t=p;
    140       t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
    141       if(xmult(l.a,t,p)*xmult(l.b,t,p)>eps)
    142           return distance(p,l.a)<distance(p,l.b)?l.a:l.b;
    143       return intersection(p,t,l.a,l.b);
    144   }
    145   //点到线段距离
    146   double disptoseg(point p,line l)
    147   {
    148       point t=p;
    149       t.x+=l.a.y-l.b.y,t.y+=l.b.x-l.a.x;
    150       if(xmult(l.a,t,p)*xmult(l.b,t,p)>eps)
    151           return distance(p,l.a)<distance(p,l.b)?distance(p,l.a):distance(p,l.b);
    152       return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);
    153   }
    154   */
    155   //求p1关于p2的对称点
    156   TPoint symmetricalPoint(TPoint p1,TPoint p2)
    157   {
    158       TPoint p3;
    159       p3.x=2*p2.x-p1.x;
    160       p3.y=2*p2.y-p1.y;
    161       return p3;
    162   }
    163   //p点关于直线L的对称点
    164   TPoint symmetricalPointofLine(TPoint p,TLine L)
    165   {
    166       TPoint p2;
    167       double d;
    168       d=L.a*L.a+L.b*L.b;
    169       p2.x=(L.b*L.b*p.x-L.a*L.a*p.x-2*L.a*L.b*p.y-2*L.a*L.c)/d;
    170       p2.y=(L.a*L.a*p.y-L.b*L.b*p.y-2*L.a*L.b*p.x-2*L.b*L.c)/d;
    171       return p2;
    172   }
    173 
    174 int main()
    175 {
    176     int T;
    177     double X1,Y1,X2,Y2,Xs,Ys,Xe,Ye;
    178     scanf("%d",&T);
    179     while (T--)
    180     {
    181         scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2,&Xs,&Ys,&Xe,&Ye);
    182         double ta=(Y2-Y1)/(X2-X1),tc=Y2-ta*X2;
    183         point A,B;
    184         if (zero(X2-X1))
    185         {
    186             A=point(Xs,Ys);
    187             if (Xe-X1>=0)    B=point(X1-fabs(Xe-X1),Ye);
    188             else if (Xe-X1<0)    B=point(X1+fabs(Xe-X1),Ye);
    189         }
    190         else
    191         {
    192             TLine tl=TLine(ta,-1,tc);
    193             TPoint pt=TPoint(Xe,Ye);
    194             TPoint tp=symmetricalPointofLine(pt,tl);
    195 
    196             A=point(tp.x,tp.y);
    197             B=point(Xs,Ys);
    198         }
    199         line L1=line(A,B);
    200         line L2=line(point(X1,Y1),point(X2,Y2));
    201         point ans=intersection(L1,L2);
    202         if (zero(ans.x)) ans.x=0;
    203         if (zero(ans.y)) ans.y=0;
    204         printf("%.3lf %.3lf
    ",ans.x,ans.y);
    205     }
    206 
    207     return 0;
    208 }
  • 相关阅读:
    [恢]hdu 2002
    [恢]hdu 2001
    [恢]hdu 2003
    [恢]hdu 1000
    ActionButton的处理流程 天龙packet
    ogre visibleflag
    Scaleform Gfx的Demo
    cegui 自定义控件
    PixWin
    在Ogre中加载自己的资源包
  • 原文地址:https://www.cnblogs.com/pdev/p/4160490.html
Copyright © 2020-2023  润新知