首页 > 代码库 > hdu 2857 求点关于线段的对称点
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 else191 {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\n",ans.x,ans.y);205 }206 207 return 0;208 }
hdu 2857 求点关于线段的对称点
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。