hdu3712 Detector Placement
题意:给一束激光,一个三棱柱,三棱柱会折射光,问这束激光最终是否会和y = 0相交;
分析:模拟题,为了方便处理折射角,事先求出每条边的向内和向外的法向量;
findpoint : 找第一交点
step1: 判断激光是否和三角形有规范相交;
step2: 第一次折射;
step3:第二次折射,可能无法折射;
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<vector>
using namespace std;
const int N = +;
const double eps = 1e-;
const double pi = acos(-1.0);
inline int dcmp(double x) {
return x < -eps ? - : x > eps;
}
inline double sqr(double x) {
return x * x;
} struct Point{
double x,y;
Point(){}
Point(double _x,double _y):x(_x),y(_y){}
bool operator == (const Point &p) const{
return dcmp(x - p.x) == && dcmp(y - p.y) == ;
}
Point operator + (const Point &p) const{
return Point(x + p.x, y + p.y);
}
Point operator - (const Point &p) const{
return Point (x - p.x, y - p.y);
}
Point operator * (const double &k) const{
return Point (x * k, y * k);
}
Point operator / (const double &k) const{
return Point (x / k, y / k);
}
double operator * (const Point &p) const{
return x * p.y - y * p.x;
}
double operator / (const Point &p) const{
return x * p.x + y * p.y;
}
double len2() {
return x * x + y * y;
}
double len() {
return sqrt(len2());
}
Point scale(const double &k) {
return dcmp( len() ) ? (*this) * (k / len()) : (*this);
}
Point turnLeft() {
return Point(-y,x);
}
Point turnRight(){
return Point(y,-x);
}
double Distance(const Point &p) {
return sqrt(sqr(x - p.x) + sqr(y - p.y));
}
Point rotate(const Point &p,double angle, double k = ) {
Point vec = (*this) - p;
double c = cos(angle * k) , s =sin(angle * k) ;
return p + Point(vec.x * c - vec.y * s, vec.x * s + vec.y * c);
}
void input(){
scanf("%lf%lf",&x,&y);
}
void ot() {
printf("%.3lf %.3lf\n",x,y);
}
};
double Angle(Point a,Point b) {
return (a/b) / a.len() / b.len();
}
struct Line{
Point a,b;
Line(){}
Line(Point a,Point b):a(a),b(b){}
double operator * (const Point &p) const{
return (b - a) * (p - a);
}
double operator / (const Point &p) const{
return (p - a) / (p - b);
}
bool IsPointOnSeg(const Point &p) {
return dcmp( (a - p) * (b - p) ) == && dcmp( (p - a) / (p - b) ) <= ;
}
int LineCrossSeg(const Line &v) {//2jiao, 1 dian ,0 wu
int d1 = dcmp( (*this) * v.a), d2 = dcmp((*this) * v.b);
if ((d1 ^ d2) == -) return ;
return (d1 == || d2 == );
}
Point CrossPoint(const Line &v) {
double s1 = v * a, s2 = v * b;
return ( a * s2 - b * s1 ) / (s2 - s1);
}
};
Line li[];
int d[];
Point a[],b[],c[];
Point st,en; double u;
int check(int i) {
if (dcmp( (li[i].b - li[i].a) * (a[d[i]] - li[i].a) ) > ) {
return ;
}
return ;
}
void init(){
for (int i = ; i < ; i++) {
if (check(i)) {
b[i] = (li[i].b - li[i].a).turnLeft();
c[i] = (li[i].b - li[i].a).turnRight();
}else {
b[i] = (li[i].b - li[i].a).turnRight();
c[i] = (li[i].b - li[i].a).turnLeft();
}
}
}
int ond(Point a,Point b,Point p) {
if (dcmp((p - a) / (b - a)) >= ) return ;
return ;
}
int step1() {
int fg = ;
Line line = Line(st,en);
for (int i = ; i < ; i++) {
if (line.LineCrossSeg(li[i]) == ) {
Point p = line.CrossPoint(li[i]);
if (ond(st,en,p)) fg = ;
}
}
if (fg == ) { Point p = line.CrossPoint(Line(Point(,),Point(,)));
if (ond(st,en,p)) printf("%.3lf\n",p.x+eps);
else printf("Error\n");
return ;
}
return ; }
void findPoint(Point &p,int &id) {
Line line = Line(st,en);
double dis = 1e50;
for (int i = ; i < ; i++) {
if (line.LineCrossSeg(li[i])) {
Point tp = line.CrossPoint(li[i]);
if (!ond(st,en,tp)) continue;
double tdis = tp.Distance(st);
if (tdis < dis && dcmp(tdis) != ) {
dis = tdis;
p = tp;
id = i;
}
}
}
}
void step2() {
Point p;
int id = -;
findPoint(p,id);
Point vec = en - st;
double cs = Angle(vec,b[id]);
double sn1 = sqrt( - cs * cs);
double sn2 = sn1 / u;
double ag = asin(sn1) - asin(sn2);
if (dcmp(vec * b[id]) <= ) {
vec = (p + vec).rotate(p,-ag);
}else vec = (p + vec).rotate(p,ag);
st = p; en = vec;
}
void step3() {
Point p;
int id = -;
findPoint(p,id);
Point vec = en - st;
double cs = Angle(vec,c[id]);
double sn1 = sqrt( - cs * cs);
double sn2 = sn1 * u;
if (sn2 > ) {
if (dcmp(p.y) == ) printf("%.3lf\n",p.x+eps);
else printf("Error\n");
return;
}
double ag = asin(sn2) - asin(sn1);
if (dcmp(vec * c[id]) >= ) {
vec = (p + vec).rotate(p,-ag);
}else vec = (p + vec).rotate(p,ag);
st = p; en = vec;
Point an = Line(st,en).CrossPoint(Line(Point(,),Point(,)));
if (ond(st,en,an)) {
printf("%.3lf\n",an.x+eps);
}else printf("Error\n");
}
void solve(){
init();
if (!step1()) return;
step2();
step3();
}
int main(){
// cout<<Line(Point(0,0),Point(1,0)).LineCrossSeg(Line(Point(0,0),Point(1,0)))<<endl;
int T; scanf("%d",&T);
while (T--) {
st.input(); en.input();
for (int i = ; i < ; i++) a[i].input();
li[] = Line(a[],a[]); d[] = ;
li[] = Line(a[],a[]); d[] = ;
li[] = Line(a[],a[]); d[] = ;
scanf("%lf",&u);
solve();
}
return ;
}
/*
3
0 10
0 20
-1 3 1 2 -1 1
1.325
0 10
0 0
-1 3 1 2 -1 1
1.325 0 10 0 9
0 0 0 1 1 0
1.0
*/
hdu3712 Detector Placement的更多相关文章
- LA 5007 Detector Placement 模拟
题意: 给出一束光线(射线),和一块三角形的棱镜 以及 棱镜的折射率,问光线能否射到X轴上,射到X轴上的坐标是多少. 分析: 其实直接模拟就好了,注意到题目中说不会发生全反射,所以如果射到棱镜中的话就 ...
- A Cross-Platform Memory Leak Detector
Memory leakage has been a permanent annoyance for C/C++ programmers. Under MSVC, one useful feature ...
- 使用Visual Leak Detector for Visual C++ 捕捉内存泄露
什么是内存泄漏? 内存泄漏(memory leak),指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况.内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段 ...
- 写了placement new就要写placement delete
"placement new"通常是专指指定了位置的new(std::size_t size, void *mem),用于vector申请capacity剩余的可用内存. 但广义的 ...
- XiangBai——【AAAI2017】TextBoxes_A Fast Text Detector with a Single Deep Neural Network
XiangBai--[AAAI2017]TextBoxes:A Fast Text Detector with a Single Deep Neural Network 目录 作者和相关链接 方法概括 ...
- Canny Edge Detector
Canny边缘检测算法有自己的理论和经验性的推导, 没仔细看/没看明白. 它的步骤如下: 对原图的灰度图进行高斯滤波 求一阶导数, 得到每个像素点的梯度强度和方向. 非最大抑制. 对每个edge ca ...
- Effective C++ -----条款52:写了placement new 也要写 placement delete
当你写一个placement operator new ,请确定也写出了对应的placement operator delete.如果没有这样做,你的程序可能会发生隐微而时断时续的内存泄漏. 当你声明 ...
- 浅谈new operator、operator new和placement new 分类: C/C++ 2015-05-05 00:19 41人阅读 评论(0) 收藏
浅谈new operator.operator new和placement new C++中使用new来产生一个存在于heap(堆)上对象时,实际上是调用了operator new函数和placeme ...
- SSD(Single Shot MultiBox Detector)的安装配置和运行
下文图文介绍转自watersink的博文SSD(Single Shot MultiBox Detector)不得不说的那些事. 该方法出自2016年的一篇ECCV的oral paper,SSD: Si ...
随机推荐
- python基础开发环境Pycharm的详细使用方法
PyCharm是由JetBrains打造的一款Python IDE(集成开发环境) 1. 创建Python文件 2. pycharm的操作界面 3. PyCharm修改字体大小的方式 4. pycha ...
- virtualBox linux操作系统centos 挂载光盘
virtualBox虚拟机linux centos 挂载光盘 第一步: 放入光盘 第二步: 挂载光驱 (/dev/cdrom) 1) 创建挂载点 mkdir /mnt/media 2) 挂载 moun ...
- tomcat7时遇到启动报错问题 SEVERE: ContainerBase.addChild: start:
个人说明:错误日志确实是我的,方法都是从其他地儿借鉴过来的,但肯定是能解决错误的方法,亲身体验,安全保障!!! 还有遇到这种问题,多启动几遍可能就行了. 错误日志: SEVERE: Container ...
- MD5加密--项目案例
在项目中最尝使用MD5这种非对称加密的就是用户信息登录了.下面我就以一个简单的登录案例来说明MD5的用法 首先来看几张图: 用户登录页:需要选择要登录的系统,同时输入用户的用户名和密码,验证码才能进入 ...
- 基于神念TGAM的脑波小车(2)
将数据处理移植到STM32上,采用串口的DMA接收模式,注意的是DMA_MODE采用Circular,DMA_BufferSize>(8*512+36=4132)(小包8个字节,每秒512个,完 ...
- 实践lnmpde 的安装
1.先安装apache, yum install httpd 2.安装MySQL rpm -qa | grep mysql // 这个命令就会查看该操作系统上是否已经安装了mysql数据库 ...
- No.101_第二次团队会议
时间的敲定 在这一次的会议中,明确了任务目标,将任务进行合理分配,并且规划了整个任务的时间节点,这对团队来说非常重要. 一.最终项目 在上一节课的时候,我们最终没有拿到学霸开发项目,最后爬虫也被选走了 ...
- C++:new&delete
一.new的浅析 在C++中,new主要由三种形式:new operator.operator new和placement new • new operator new operator即一些C++书 ...
- 福大软工1816 · 评分结果 · beta冲刺总评
作业地址:beta答辩总结.beta冲刺7.beta冲刺6.beta冲刺5.beta冲刺4.beta冲刺3.beta冲刺2.beta冲刺1.beta冲刺前准备 作业提交准则 按时交 - 有分 晚交 - ...
- Mutual and feedback(互评与反馈)
互评与反馈: 注:我在收集各小组对我小组的评价了,发现有几个没有收集到,不知道是我看不到还是贵小组不小心遗漏了对我小组的评价,如果看到,请给我留意,谢谢! 组名 对我 ...