题意:给一束激光,一个三棱柱,三棱柱会折射光,问这束激光最终是否会和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的更多相关文章

  1. LA 5007 Detector Placement 模拟

    题意: 给出一束光线(射线),和一块三角形的棱镜 以及 棱镜的折射率,问光线能否射到X轴上,射到X轴上的坐标是多少. 分析: 其实直接模拟就好了,注意到题目中说不会发生全反射,所以如果射到棱镜中的话就 ...

  2. A Cross-Platform Memory Leak Detector

    Memory leakage has been a permanent annoyance for C/C++ programmers. Under MSVC, one useful feature ...

  3. 使用Visual Leak Detector for Visual C++ 捕捉内存泄露

    什么是内存泄漏? 内存泄漏(memory leak),指由于疏忽或错误造成程序未能释放已经不再使用的内存的情况.内存泄漏并非指内存在物理上的消失,而是应用程序分配某段内存后,由于设计错误,失去了对该段 ...

  4. 写了placement new就要写placement delete

    "placement new"通常是专指指定了位置的new(std::size_t size, void *mem),用于vector申请capacity剩余的可用内存. 但广义的 ...

  5. 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 目录 作者和相关链接 方法概括 ...

  6. Canny Edge Detector

    Canny边缘检测算法有自己的理论和经验性的推导, 没仔细看/没看明白. 它的步骤如下: 对原图的灰度图进行高斯滤波 求一阶导数, 得到每个像素点的梯度强度和方向. 非最大抑制. 对每个edge ca ...

  7. Effective C++ -----条款52:写了placement new 也要写 placement delete

    当你写一个placement operator new ,请确定也写出了对应的placement operator delete.如果没有这样做,你的程序可能会发生隐微而时断时续的内存泄漏. 当你声明 ...

  8. 浅谈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 ...

  9. SSD(Single Shot MultiBox Detector)的安装配置和运行

    下文图文介绍转自watersink的博文SSD(Single Shot MultiBox Detector)不得不说的那些事. 该方法出自2016年的一篇ECCV的oral paper,SSD: Si ...

随机推荐

  1. 【轮子狂魔】手把手教你自造Redis Client

    为什么做Redis Client? Redis Client顾名思义,redis的客户端,主要是封装了一些对于Redis的操作. 而目前用的比较广泛的 ServiceStack.Redis 不学好,居 ...

  2. PLSQL_数据泵Datapump导入导出数据IMPDP / EXPDP(概念)(Oracle数据导入导出工具)(转)

    一.摘要 在平常备库和数据库迁移的时候,当遇到大的数据库的时候在用exp的时候往往是需要好几个小时,耗费大量时间.oracle10g以后可以用expdp来导出数据库花费的时间要远小于exp花费的时间, ...

  3. TCP/IP理解

    目录 1.概述 2.TCP/IP寻址及其协议族 3.TCP/IP 邮件 1.概述 介绍:什么是TCP/IP? TCP/IP协议是对计算机必须遵守的规则的描述,遵守了规则才能通信. 应用: 浏览器与服务 ...

  4. variadic templates & pass by const reference & member operator [] in const map & gcc sucks

    /// bugs code with comments #include <iostream> #include <memory> #include <unordered ...

  5. Django中settings设计模式(单例模式)

    配置文件: 需求:配置文件,默认配置和手动配置分开,参考django的配置文件方案,默认配置文件放在项目容器内部,只让用户做常用配置. /bin/settings.py(手动配置) PLUGIN_IT ...

  6. OpenGL学习笔记(6) 基础光照的计算方法

    这个笔记只是冯氏光照模型下漫反射光以及镜面光照的计算方式的笔记 基础光照 基础光照分为环境光,漫反射光,镜面光照 环境光 环境光是一个常量,表示在没有光源的情况下物体的光 漫反射光 漫反射光分量的计算 ...

  7. scrapy的简单使用

    使用之前的创建虚拟环境方法(pipenv) 创建虚拟环境并进入虚拟环境 mkdir douban cd douban pipenv install pipenv shell 再安装我们的scrapy ...

  8. Spring入门学习笔记(4)——JDBC的使用

    目录 Spring JDBC框架概览 JdbcTemplate类 配置数据源 数据访问对象(Data Access Object,DAO) 执行SQL命令 Spring JDBC框架概览 使用传统的J ...

  9. [Paper Reading] Image Captioning using Deep Neural Architectures (arXiv: 1801.05568v1)

    Main Contributions: A brief introduction about two different methods (retrieval based method and gen ...

  10. IDEA 2018 最新激活码 License server

    IDEA 2018 最新激活码 License server 总会有一个属于适合你的!嘻嘻 http://hb5.s.osidea.cc:1017 http://idea.youbbs.org htt ...