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 ...
随机推荐
- CSS文本溢出处理方式
1. 单行文本溢出省略号效果 .ellipsis { overflow:hidden; white-space:nowrap; text-overflow:ellipsis; } <div cl ...
- kali 2018.1安装教程
00x01 摘要 Kali-linux系统,渗透测试人员的利器,其官网自称 OurMost Advanced Penetration Testing Distribution, Ever. 永远是最 ...
- 2018年美国大学生数学建模竞赛(MCM/ICM) 比赛心得
话不多说,题目先上: 这是我们这次选择的题目,说说建模的那些事! 美赛的时间和国赛挑战杯时间略有不同,貌似多的一天是为了让我们对文章进行一个翻译吧QAQ 建议参加美赛的同学可以参照此计划进行 Day0 ...
- idou老师教你学Istio:如何用 Istio 实现速率限制
使用 Istio 可以很方便地实现速率限制.本文介绍了速率限制的使用场景,使用 memquota\redisquota adapter 实现速率限制的方法,通过配置 rule 实现有条件的速率限制,以 ...
- Java将List<T>集合组装成树(Tree)树结构组装
把列表转换为树结构 /** * 把列表转换为树结构 * * @param originalList 原始list数据 * @param keyName 作为唯一标示的字段名称 * @return 组装 ...
- React——event
1.绑定在React元素上的事件与绑定在DOM元素上的事件非常相似,但是也有一个不同的地方 React事件使用驼峰命名法命名 //在HTML中 <button onclick='handle() ...
- SpringBoot文件上传异常之提示The temporary upload location xxx is not valid
原文: 一灰灰Blog之Spring系列教程文件上传异常原理分析 SpringBoot搭建的应用,一直工作得好好的,突然发现上传文件失败,提示org.springframework.web.multi ...
- STM平台增加性能测试/稳定性测试部分【二】
[一]方案 基本上测试针对产品的各项方案大体是如下的: 如上所示,针对产品的性能测试主要步骤如下: 1.造数据,在产品业务流上,产生所需的数据,数据量以(稳定性或者压测指标确定) 2.根据步骤1,设定 ...
- 自动化运维工具saltstack05 -- 之salt-ssh模式
salt-ssh模式 1.说明: salt-ssh即通过ssh得方式进行管理,不需要安装salt-minion, salt-ssh 用的是sshpass进行密码交互的. 2.salt-ssh得局限性 ...
- UnityEditor扩展-Shader浏览器
1. 用途 用于浏览项目所有Shader被使用的情况 2. 界面说明 Ignore Directory:添加不搜索的文件夹,不添加默认搜索全部 Find按钮:开始搜索 Used Shaders:已被使 ...