题意:给一束激光,一个三棱柱,三棱柱会折射光,问这束激光最终是否会和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. JavaScript 数组——filter()、map()、some()、every()、forEach()、lastIndexOf()、indexOf()

    filter():   语法: var filteredArray = array.filter(callback[, thisObject]); 参数说明: callback: 要对每个数组元素执行 ...

  2. linux下的静态库与动态库

    目录 静态库 定义: 生成及使用方法: 静态库的优缺点 动态库 定义: 生成及使用方法: 动态库优缺点: 静态库 先说说我们为什么需要库? 当有些代码我们大量会在程序中使用比如(scanf,print ...

  3. css布局笔记(二)Flex

    flex Flex是"Flexible Box"的缩写,意为"弹性布局",用来为盒状模型提供最大的灵活性. 任何一个容器都可指定为Flex布局. .box{di ...

  4. ruby安装卸载

    1.用命令yum install ruby安装,是2.0以下的版本.不建议使用 2.2.2以上  下载地址:https://www.ruby-lang.org/en/news/2018/03/28/r ...

  5. JDBC Mysql 驱动连接异常

    在做JDBC连接Mysql的时候遇到了三个异常: 第一个是:mysql8.0 caching_sha2_password 这个异常是由于是因为在mysql8.0之前的密码规则是mysql_native ...

  6. 《Redis设计与实现》阅读笔记(一)--Redis学习

    Redis学习资料与过程记录 在实习中经常会用到很多Redis,对Redis有了一些模糊的了解,总觉得隔靴搔痒的不痛快,所以决定开始深入的了解Redis,也作为我实习期间的目标. 这篇只是为了占个位置 ...

  7. CHAPTER 5 ‘The Master of Those Who know’ Aristotle 第5章 “有识之士的大师” 亚里士多德

    CHAPTER 5 ‘The Master of Those Who know’ Aristotle 第5章 “有识之士的大师” 亚里士多德 ‘All men by nature desire to ...

  8. Linear Regression and Maximum Likelihood Estimation

    Imagination is an outcome of what you learned. If you can imagine the world, that means you have lea ...

  9. mongodb 如何删除 字段值为 json对象中的某个字段值

    例如: { attributes: { birthday:'1988-01-01', name: 'aq' } } birthday是attributes字段的value的一个字段, 我要删除birt ...

  10. JDK自带的监控工具方法

    一.概述       SUN 的JDK中的几个工具,非常好用.秉承着有免费,不用商用的原则.以下简单介绍一下这几种工具.(注:本文章下的所有工具都存在JDK5.0以上版本的工具集里(jdk的bin目录 ...