• SHOI2015激光发生器





    计算几何,直接模拟即可

    找最近的交点然后模拟旋转

    会求直线交点&向量旋转即可

    注:

    1. (acos)值域([0,pi])
    2. (asin,atan)值域([-pi/2,pi/2])
    3. (atan2)值域([-pi,pi])(平面直角坐标系上找点)
    #include<bits/stdc++.h>
    using namespace std;
    struct poin{
    	double x,y;
    	poin(){}
    	poin(double x,double y):x(x),y(y){}
    	inline poin operator +(const poin &a)const{
    		return poin(x+a.x,y+a.y);
    	}
    	inline poin operator -(const poin &a)const{
    		return poin(x-a.x,y-a.y);
    	}
    	inline poin operator *(const double &a)const{
    		return poin(x*a,y*a);
    	}
    	inline double operator *(const poin &a)const{
    		return x*a.y-y*a.x;
    	}
    	inline double operator ^(const poin &a)const{
    		return x*a.x+y*a.y;
    	}
    }; 
    inline double dis(poin a){
    	return sqrt(a.x*a.x+a.y*a.y);
    }
    inline poin rotate(poin a,double d){//clockwise
    	return poin(a.x*cos(d)-a.y*sin(d),a.x*sin(d)+a.y*cos(d));
    }
    struct line{
    	poin a,b;
    	line(){}
    	line(poin a,poin b):a(a),b(b){}
    };
    poin ins;
    inline bool inters(line x,line y){
    	double u=(y.b-y.a)*(x.a-y.a);
    	double d=u+(x.b-y.a)*(y.b-y.a);
    	ins=x.a+(x.b-x.a)*(u/d);
    	if(u/d<0||u/d>1||((y.a-ins)^(y.b-y.a))>0)return 0;
    	return 1;
    }
    const int N=104;
    const double inf=1e18,eps=1e-8,pi=acos(-1.0);
    poin a,b;
    line s[N];
    int n;
    double z[N];
    int main(){
    	scanf("%lf%lf%lf%lf%d",&a.x,&a.y,&b.x,&b.y,&n);
    	for(int i=1;i<=n;i++){
    		double x,y;
    		scanf("%lf%lf%lf%lf%lf%lf",&s[i].a.x,&s[i].a.y,&s[i].b.x,&s[i].b.y,&x,&y);
    		z[i]=x/y;
    	}
    	double mn,d;
    	poin u,p,v;
    	for(int T=1,lst=0,id;T<=10;T++){
    		id=0;mn=inf;
    		for(int i=1;i<=n;i++){
    			if(i==lst||fabs((s[i].b-s[i].a)*b)<eps||!inters(s[i],line(a,a+b)))continue;
    			d=dis(ins-a);
    			if(d<mn){id=i;mn=d;p=ins;}
    		}
    		if(!id){
    			if(T==1)puts("NONE");
    			return (0-0);
    		}
    		cout<<id<<" ";
    		u=p-a;
    		v=s[id].a-s[id].b;
    		v=rotate(v,pi/2);
    		if((u^v)>eps)v=rotate(v,pi);
    		d=acos(-(u^v)/dis(u)/dis(v));
    		a=p;
    		if(u*v>0)b=rotate(b,pi-(z[id]+1)*d);
    		else b=rotate(b,pi+(z[id]+1)*d);
    		lst=id;
    	}
    	return (0-0);
    }
    
  • 相关阅读:
    bootstrap 网格系统学习
    在asp.net web api中利用过滤器设置输出缓存
    解决在开发环境中访问json配置文件时报HTTP 错误 404.3
    Newtonsoft.Json序列化和反序列
    装饰者模式学习
    SQL server跨库查询
    python-安装xlrd xlwt 插件
    vim 实际行跟屏幕行移动命令
    vim-缓存区中打开另外一个文件的方法
    vim 计算器寄存器使用
  • 原文地址:https://www.cnblogs.com/aurora2004/p/12566675.html
Copyright © 2020-2023  润新知