计算几何,直接模拟即可
找最近的交点然后模拟旋转
会求直线交点&向量旋转即可
注:
- (acos)值域([0,pi])
- (asin,atan)值域([-pi/2,pi/2])
- (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);
}