hdu 2857 求点关于线段的对称点
本来很简单的一个题,但是有个大坑:
因为模板中Tline用到了直线的一般方程ax+by+c=0,所以有种很坑的情况需要特判:
斜率不存在啊喂
老子坑了一下午2333
#include <math.h>
#include <stdio.h> #define eps 1e-6
#define PI acos(-1.0)//3.14159265358979323846
//判断一个数是否为0,是则返回true,否则返回false
#define zero(x)(((x)>0?(x):-(x))<eps)
//返回一个数的符号,正数返回1,负数返回2,否则返回0
#define _sign(x)((x)>eps?1:((x)<-eps?2:0)) struct point
{
double x,y;
point(){}
point(double xx,double yy):x(xx),y(yy)
{}
};
struct line
{
point a,b;
line(){} //默认构造函数
line(point ax,point bx):a(ax),b(bx)
{}
};//直线通过的两个点,而不是一般式的三个系数
struct TLine
{
double a,b,c;
TLine(){}
TLine(double _a,double _b,double _c):a(_a),b(_b),c(_c)
{}
};//直线一般式的三个系数ax+by+c=0
struct TPoint
{
double x,y;
TPoint(){}
TPoint(double _x,double _y):x(_x),y(_y)
{}
TPoint operator-(TPoint&a)
{
TPoint p1;
p1.x=x-a.x;
p1.y=y-a.y;
return p1;
}
}; //求矢量[p0,p1],[p0,p2]的叉积
//p0是顶点
//若结果等于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);
}
//计算dotproduct(P1-P0).(P2-P0)
double dmult(point p1,point p2,point p0)
{
return(p1.x-p0.x)*(p2.x-p0.x)+(p1.y-p0.y)*(p2.y-p0.y);
}
//两点距离
double distance(point p1,point p2)
{
return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y));
}
//判三点共线
int dots_inline(point p1,point p2,point p3)
{
return zero(xmult(p1,p2,p3));
}
//判点是否在线段上,包括端点
int dot_online_in(point p,line l)
{
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;
}
//判点是否在线段上,不包括端点
int dot_online_ex(point p,line l)
{
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));
}
//判两点在线段同侧,点在线段上返回0
int same_side(point p1,point p2,line l)
{
return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)>eps;
}
//判两点在线段异侧,点在线段上返回0
int opposite_side(point p1,point p2,line l)
{
return xmult(l.a,p1,l.b)*xmult(l.a,p2,l.b)<-eps;
}
//判两直线平行
int parallel(line u,line v)
{
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));
}
//判两直线垂直
int perpendicular(line u,line v)
{
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));
}
//判两线段相交,包括端点和部分重合
int intersect_in(line u,line v)
{
if(!dots_inline(u.a,u.b,v.a)||!dots_inline(u.a,u.b,v.b))
return!same_side(u.a,u.b,v)&&!same_side(v.a,v.b,u);
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);
}
//判两线段相交,不包括端点和部分重合
int intersect_ex(line u,line v)
{
return opposite_side(u.a,u.b,v)&&opposite_side(v.a,v.b,u);
}
//计算两直线交点,注意事先判断直线是否平行!
//线段交点请另外判线段相交(同时还是要判断是否平行!)
point intersection(line u,line v)
{
point ret=u.a;
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));
ret.x+=(u.b.x-u.a.x)*t;
ret.y+=(u.b.y-u.a.y)*t;
return ret;
}
/*
//点到直线上的最近点
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);
}
//点到直线距离
double disptoline(point p,line l)
{
return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);
}
//点到线段上的最近点
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 distance(p,l.a)<distance(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 distance(p,l.a)<distance(p,l.b)?distance(p,l.a):distance(p,l.b);
return fabs(xmult(p,l.a,l.b))/distance(l.a,l.b);
}
*/
//求p1关于p2的对称点
TPoint symmetricalPoint(TPoint p1,TPoint p2)
{
TPoint p3;
p3.x=*p2.x-p1.x;
p3.y=*p2.y-p1.y;
return p3;
}
//p点关于直线L的对称点
TPoint symmetricalPointofLine(TPoint p,TLine L)
{
TPoint p2;
double d;
d=L.a*L.a+L.b*L.b;
p2.x=(L.b*L.b*p.x-L.a*L.a*p.x-*L.a*L.b*p.y-*L.a*L.c)/d;
p2.y=(L.a*L.a*p.y-L.b*L.b*p.y-*L.a*L.b*p.x-*L.b*L.c)/d;
return p2;
} int main()
{
int T;
double X1,Y1,X2,Y2,Xs,Ys,Xe,Ye;
scanf("%d",&T);
while (T--)
{
scanf("%lf%lf%lf%lf%lf%lf%lf%lf",&X1,&Y1,&X2,&Y2,&Xs,&Ys,&Xe,&Ye);
double ta=(Y2-Y1)/(X2-X1),tc=Y2-ta*X2;
point A,B;
if (zero(X2-X1))
{
A=point(Xs,Ys);
if (Xe-X1>=) B=point(X1-fabs(Xe-X1),Ye);
else if (Xe-X1<) B=point(X1+fabs(Xe-X1),Ye);
}
else
{
TLine tl=TLine(ta,-,tc);
TPoint pt=TPoint(Xe,Ye);
TPoint tp=symmetricalPointofLine(pt,tl); A=point(tp.x,tp.y);
B=point(Xs,Ys);
}
line L1=line(A,B);
line L2=line(point(X1,Y1),point(X2,Y2));
point ans=intersection(L1,L2);
if (zero(ans.x)) ans.x=;
if (zero(ans.y)) ans.y=;
printf("%.3lf %.3lf\n",ans.x,ans.y);
} return ;
}
hdu 2857 求点关于线段的对称点的更多相关文章
- hdu 2857:Mirror and Light(计算几何,点关于直线的对称点,求两线段交点坐标)
Mirror and Light Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) ...
- HDU.5692 Snacks ( DFS序 线段树维护最大值 )
HDU.5692 Snacks ( DFS序 线段树维护最大值 ) 题意分析 给出一颗树,节点标号为0-n,每个节点有一定权值,并且规定0号为根节点.有两种操作:操作一为询问,给出一个节点x,求从0号 ...
- HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对)
HDU.1394 Minimum Inversion Number (线段树 单点更新 区间求和 逆序对) 题意分析 给出n个数的序列,a1,a2,a3--an,ai∈[0,n-1],求环序列中逆序对 ...
- HDU.1689 Just a Hook (线段树 区间替换 区间总和)
HDU.1689 Just a Hook (线段树 区间替换 区间总和) 题意分析 一开始叶子节点均为1,操作为将[L,R]区间全部替换成C,求总区间[1,N]和 线段树维护区间和 . 建树的时候初始 ...
- R - Weak Pair HDU - 5877 离散化+权值线段树+dfs序 区间种类数
R - Weak Pair HDU - 5877 离散化+权值线段树 这个题目的初步想法,首先用dfs序建一颗树,然后判断对于每一个节点进行遍历,判断他的子节点和他相乘是不是小于等于k, 这么暴力的算 ...
- HDU 3016 Man Down (线段树+dp)
HDU 3016 Man Down (线段树+dp) Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Ja ...
- HDU.1556 Color the ball (线段树 区间更新 单点查询)
HDU.1556 Color the ball (线段树 区间更新 单点查询) 题意分析 注意一下pushdown 和 pushup 模板类的题还真不能自己套啊,手写一遍才行 代码总览 #includ ...
- HDU.1166 敌兵布阵 (线段树 单点更新 区间查询)
HDU.1166 敌兵布阵 (线段树 单点更新 区间查询) 题意分析 加深理解,重写一遍 代码总览 #include <bits/stdc++.h> #define nmax 100000 ...
- HDU 2857 Mirror and Light
/* hdu 2857 Mirror and Light 计算几何 镜面反射 */ #include<stdio.h> #include<string.h> #include& ...
随机推荐
- [LINK]php的三种CLI常量:STDIN,STDOUT,STDERR
FROM : http://www.cnblogs.com/thinksasa/archive/2013/02/27/2935158.html PHP CLI(command line interfa ...
- 阿里云安装LNMP以及更改网站文件和MySQL数据目录
LNMP安装了哪些软件?安装目录在哪LNMP相关软件安装目录Nginx 目录: /usr/local/nginx/MySQL 目录 : /usr/local/mysql/MySQL数据库所在目录:/u ...
- hadoop: hive 1.2.0 在mac机上的安装与配置
环境:mac OS X Yosemite + hadoop 2.6.0 + hive 1.2.0 + jdk 1.7.0_79 前提:hadoop必须先安装,且处于运行状态(伪分式模式或全分布模式均可 ...
- 如何让oracle的select强制走索引
大多数情况下,oracle数据库内置的查询优化策略还是很成功的,但偶尔也有犯2的时候,即使有索引,也会做全表扫描,可以参考以下语句的写法,强制让select语句使用索引 CREATE OR REPLA ...
- opencv2-新特性及Mat
本文参照<opencv_2.4.9tutorial>的core部分完成.因为功力还不足以学习侯捷那种大师一样去深入浅出的解析opencv的源码,也只能先学会怎么用opencv,然后实在觉得 ...
- 【自己给自己题目做】:如何在Canvas上实现魔方效果
最终demo -> 3d魔方 体验方法: 浮动鼠标找到合适的位置,按空格键暂停 选择要翻转的3*3模块,找到相邻两个正方体,鼠标点击第一个正方体,并且一直保持鼠标按下的状态直到移到第二个正方体后 ...
- WebConfig 详解
一.Web.Config继承特性 首先我们就来看看配置文件的继承层次.都知道在ASP.NET中有很多的配置文件,如machine.config,web.config,特别是web.config出现在很 ...
- C#发展历程以及C#6.0新特性
一.C#发展历程 下图是自己整理列出了C#每次重要更新的时间及增加的新特性,对于了解C#这些年的发展历程,对C#的认识更加全面,是有帮助的. 二.C#6.0新特性 1.字符串插值 (String In ...
- IDEA 13 无法进入debug 模式解决方案
1.最近在idea中使用tomcat开发项目,像往常一样打开tomcat进行debug,但奇怪的事情出现了,项目根本不进断点.后查找原因,估计idea的加载参数方式是:先加载tomcat中设置的参数, ...
- C/C++代码覆盖工具gcov与lcov入门
C/C++代码覆盖工具gcov与lcov入门 gcov是一个可用于C/C++的代码覆盖工具,是gcc的内建工具.下面介绍一下如何利用gcov来收集代码覆盖信息.想要用gcov收集代码覆盖信息,需要在g ...