Language: C++

#include<cstdio>
#include<cmath>
#include<utility>
#include<vector>
#include<complex>
#include<algorithm>
 
using namespace std;
 
typedef long double Real;
typedef complex<Real> Point;
typedef complex<Real> Vector;
typedef pair<Point,Point> Line;
typedef pair<Point,Point> Segment;
typedef vector<Point> Polygon;
 
const Real eps=1e-9;
const Real PI=acos(-1.0);
const Real inf=1e9;
 
const Real eps2=1e-6;
 
const Point NPoint=Point(NAN,NAN);
 
void print(Point p,char ch='\n'){
    printf("(%f %f)%c",p.real(),p.imag(),ch);
}
 
template<class T> bool eq(T a,T b){
    return abs(a-b)<eps;
}
template<class T> int sgn(T a){
    if(eq(a,0.0)) return 0;
    if(a>0) return 1;
    return -1;
}
template<class T> bool eq2(T a,T b){
    return abs(a-b)<eps2;
}
template<class T> int sgn2(T a){
    if(eq2(a,0.0)) return 0;
    if(a>0) return 1;
    return -1;
}
 
bool onSeg(Point a,Point b,Point c){
    return eq(abs(a-b),abs(a-c)+abs(c-b));
}
 
bool onSeg(Segment s,Point p){
    return onSeg(s.first,s.second,p);
}
 
Real doP(Vector a,Vector b){
    return (conj(a)*b).real();
}
 
Real crP(Vector a,Vector b){
    return (conj(a)*b).imag();
}
 
Vector proj(Vector p,Vector b){
    return b*doP(p,b)/norm(b);
}
 
Point perp(Line l,Point a){
    Point p=l.first,q=l.second;
    return p+proj(a-p,q-p);
}
 
bool isPara(Vector a,Vector b){
    return eq(crP(a,b),(Real)0);
}
 
bool isPara(Line l1,Line l2){
    return isPara(l1.second-l1.first,l2.second-l2.first);
}
 
Real arg(Point p){
    return atan2(p.imag(),p.real());
}
 
Real normalize(Real x){//[-PI,PI)
    while(x<-PI) x+=PI*2;
    while(x>=PI) x-=PI*2;
    return x;
}
 
struct Circle:vector<Real>{
    Point c;
    Real r;
    Circle(){}
    Circle(Point c,Real r):c(c),r(r){}
};
 
Point getP(Point c,Real r,Real ang){
    return c+r*Point(cos(ang),sin(ang));
}
 
void iCL(Circle &c_,Line l){//tangent: not intersect
    //lが中心を通る場合!!!
    Point c=c_.c;
    Real r=c_.r;
    Point p=l.first,q=l.second;
    Point h=perp(l,c);
    Real d=abs(h-c);
    if(sgn(d-r)>=0) return;
    Real theta=arg(h-c);
    Real phi=acos(d/r);
    c_.push_back(normalize(theta-phi));
    c_.push_back(normalize(theta+phi));
}
 
void iCS(Circle &c_,Segment s){
//  printf("iCS\n");
//  print(c_.c,' ');
//  printf("%f\n",c_.r);
//  print(s.first,' ');
//  print(s.second);
    Point c=c_.c;
    Real r=c_.r;
    Point p=s.first,q=s.second;
    Point h=perp(s,c);
    Real d=abs(h-c);
    if(sgn(d-r)>=0) return;
    if(eq(d,(Real)0)){
        Point dir=s.second-s.first;
        dir/=abs(dir);
        Point p1=c+r*dir;
        Point p2=c-r*dir;
//      printf("in iCS\n");
//      print(p1);
//      print(p2);
        if(onSeg(p,q,p1)) c_.push_back(arg(dir));
        if(onSeg(p,q,p2)) c_.push_back(arg(dir)-PI);
        return;
    }
    Real theta=arg(h-c);
    Real phi=acos(d/r);
    Point p1=getP(c,r,theta-phi);
    if(onSeg(p,q,p1)) c_.push_back(theta-phi);
    Point p2=getP(c,r,theta+phi);
    if(onSeg(p,q,p2)) c_.push_back(theta+phi);
}
 
Segment shrink(Segment s){
    Segment res;
    res.first=s.first+(s.second-s.first)*eps;
    res.second=s.second+(s.first-s.second)*eps;
    return res;
}
 
Polygon poly;
 
vector<Point> getTouchingPoints(Segment s){
    vector<Point> res;
    for(int i=0;i<poly.size();i++){
        if(onSeg(s,poly[i])) res.push_back(poly[i]);
    }
    for(int i=0;i<poly.size();i++){
        Point p=poly[i],q=poly[i+1==poly.size()?0:i+1];
        if(onSeg(p,q,s.first)) res.push_back(s.first);
        if(onSeg(p,q,s.second)) res.push_back(s.second);
    }
    return res;
}
 
Real getAngDis(Real from,Real to,bool rev=false){
    if(rev) return getAngDis(to,from);
    Real res=to-from;
    while(res<0) res+=PI*2;
    return res;
}
 
Real getRotateAngle(Point p,Point q){
//  printf("getRotAng");
//  print(p,' ');
//  print(q);
    vector<Point> pts;
    Real r=abs(p-q);
    if(eq(r,(Real)0)) return -1;
    Circle c=Circle(p,r);
    for(int i=0;i<poly.size();i++){
        Point p=poly[i],q=poly[i+1==poly.size()?0:i+1];
        Segment s_=Segment(p,q);
        Segment s=shrink(s_);
        if(sgn(abs(s.first-c.c)-c.r)<0) pts.push_back(s.first);
        if(sgn(abs(s.second-c.c)-c.r)<0) pts.push_back(s.second);
        iCS(c,s);
    }
    for(int i=0;i<c.size();i++){
        pts.push_back(getP(c.c,c.r,c[i]));
    }
//  for(int i=0;i<pts.size();i++){
//      print(pts[i]);
//  }
    Point nxt;
    Real ang=PI*3;
    Real init_dir=arg(q-p);
    for(int i=0;i<pts.size();i++){
        if(eq(pts[i],p)) continue;
        Real dir=arg(pts[i]-p);
        Real cur=getAngDis(init_dir,dir,true);
        if(cur<ang){
            Real tmp=getAngDis(init_dir,arg(pts[i]-p),true);
            if(sgn(tmp)<=0) continue;
            ang=cur;
            nxt=pts[i];
        }
    }
    return getAngDis(init_dir,arg(nxt-p),true);
}
 
bool checkNonzero(Segment s,Point p);
 
Real getRotateAngle(Segment s,Point c){
    bool flg=checkNonzero(s,c);
    if(!flg){
//      printf("check = false\n");
        return 0;
    }
    Real res=PI*3;
    if(!eq(s.first,c)){
        Real cur=getRotateAngle(c,s.first);
        res=min(res,cur);
    }
    if(!eq(s.second,c)){
        Real cur=getRotateAngle(c,s.second);
        res=min(res,cur);
    }
    return res;
}
 
Point rotatePoint(Point p,Point c,Real ang){
    return c+(p-c)*(Point(cos(-ang),sin(-ang)));
}
 
Segment rotateSegment(Segment s,Point c,Real ang){
    s.first=rotatePoint(s.first,c,ang);
    s.second=rotatePoint(s.second,c,ang);
    return s;
}
 
Point iLL(Line l1,Line l2){
    if(isPara(l1,l2)) return NPoint;
    Point a1=l1.first,a2=l1.second;
    Point b1=l2.first,b2=l2.second;
    double num=crP(b1-a1,a2-a1);
    double den=crP(a2-a1,b2-b1);
    return b1+(b2-b1)*(num/den);
}
 
Point iSS(Segment s1,Segment s2){
    Point p=iLL(s1,s2);
    if(isnan(p.real())) return p;
    if(onSeg(s1,p)&&onSeg(s2,p)) return p;
    return NPoint;
}
 
const Real eps_rot=1e-6;
 
Point rot(Point p,Point q,Real a){
    return p+(q-p)*(Point(cos(a),sin(a)));
}
 
bool inPoly_(Polygon poly,Point pt){//ON is IN
    bool in=false;
    for(int i=0;i<poly.size();i++){
        Point a=poly[i],b=poly[(i+1)%poly.size()];
        a-=pt,b-=pt;
//      if(a.imag()>b.imag()) swap(a,b);
        if(sgn(a.imag()-b.imag())>0) swap(a,b);
//      if(a.imag()<=0&&0<b.imag()){
        if(sgn(a.imag())<=0&&sgn(b.imag())>0){
//          if(crP(a,b)<0) in=!in;
            int s=sgn(crP(a,b));
            if(s==0) return true;//ON
            if(s==-1) in=!in;
        }
    }
    return in;
}
 
bool checkNonzero(Segment s,Point p){
//  printf("checkNonzero\n");
//  print(s.first,' ');
//  print(s.second);
/// print(p);
    Segment ns;
    ns.first=rot(p,s.first,-eps_rot);
    ns.second=rot(p,s.second,-eps_rot);
    vector<Point> ps;
    for(int i=0;i<poly.size();i++){
        Point v1=poly[i],v2=poly[i+1==poly.size()?0:i+1];
        Segment e=Segment(v1,v2);
        Point in=iSS(e,ns);
//      if(!isnan(in.real())) ps.push_back(in);
        if(!isnan(in.real())){
//          return false;
//          printf("inter:");
//          print(in,' ');
//          printf("d=%.9f\n",abs(p-in));
            if((!eq2(ns.first,in))&&(!eq2(ns.second,in))&&(!eq2(e.first,in))&&(!eq2(e.second,in))
                &&(!eq2(p,in))){
//              printf("this is invalid\n");
                return false;
            }else{
//              printf("ok\n");
            }
        }
    }
    ps.push_back(ns.first);
    ps.push_back(ns.second);
    for(int i=0;i<ps.size();i++){
        if(!inPoly_(poly,ps[i])){
//          printf("not inside");
//          print(ps[i]);
            return false;
        }
    }
    //printf("true\n");
    return true;
}
 
typedef pair<Real,Point> P;
/*
Segment rotate(Segment s){
    vector<Point> cands=getTouchingPoints(s);
    vector<P> vec;
    for(int i=0;i<cands.size();i++){
        */
 
Real remRotateAng;
Segment seg;
 
Point solve(){
    int cnt_zero=0;
    while(remRotateAng>eps){
        if(cnt_zero>150) break;
        vector<Point> cands=getTouchingPoints(seg);
        //printf("cands::\n");
        //for(int i=0;i<cands.size();i++){
        //  print(cands[i]);
        //}
        vector<Real> vec;
        for(int i=0;i<cands.size();i++){
            vec.push_back(abs(seg.first-cands[i]));
        }
        sort(vec.begin(),vec.end());
        Point dir=seg.second-seg.first;
        dir/=(abs(dir));
        Point p1=seg.first+dir*vec.front();
        Point p2=seg.first+dir*vec.back();
        Real ang1=getRotateAngle(seg,p1);
        Real ang2=getRotateAngle(seg,p2);
//      printf("---\n");
//      print(p1,' ');
//      print(p2);
//      printf("%f %f\n",ang1,ang2);
//      printf("---\n");
        if(ang1>eps){
            Real rotateAng=min(ang1,remRotateAng);
            Segment nseg=rotateSegment(seg,p1,rotateAng);
            remRotateAng-=rotateAng;
            //printf("center=");
            //print(p1);
            //printf("ang=%f\n",rotateAng);
            seg=nseg;
        }else if(ang2>eps){
            Real rotateAng=min(ang2,remRotateAng);
            Segment nseg=rotateSegment(seg,p2,rotateAng);
            remRotateAng-=rotateAng;
            //printf("center=");
            //print(p2);
            //printf("ang=%f\n",rotateAng);
            seg=nseg;
        }else{
            cnt_zero++;
            //printf("zero\n");
            //print(seg.first,' ');
            //print(seg.second);
            //print(p1);
            //print(p2);
            break;
        }
        cnt_zero=0;
//      printf("remAng=%f\n",remRotateAng);
    }
    return seg.first;
}
 
int main(){
    int tnum=0;
    while(true){
        Real L,R;
        int N;
        scanf("%lf%lf%d",&L,&R,&N);
        if(N==0) break;
        tnum++;
        //printf("test case %d\n",tnum);
        poly.clear();
        for(int i=0;i<N;i++){
            Real x,y;
            scanf("%lf%lf",&x,&y);
            poly.push_back(Point(x,y));
        }
        remRotateAng=PI*2.0*R;
        seg=Segment(Point(0,0),Point(0,L));
        Point ans=solve();
        //fprintf(stderr,"%.9f %.9f\n",ans.real(),ans.imag());
        printf("%.9lf %.9lf\n",ans.real(),ans.imag());
    //  break;
    }
    return 0;
}

Compiler output:
a.cc: In function 'Point iLL(Line, Line)':
a.cc:250:22: error: no match for 'operator*' (operand types are 'std::complex<long double>' and 'double')
  250 |     return b1+(b2-b1)*(num/den);
      |               ~~~~~~~^~~~~~~~~~
      |                  |        |
      |                  |        double
      |                  std::complex<long double>
In file included from a.cc:5:
/usr/include/c++/14/complex:400:5: note: candidate: 'template<class _Tp> std::complex<_Tp> std::operator*(const complex<_Tp>&, const complex<_Tp>&)'
  400 |     operator*(const complex<_Tp>& __x, const complex<_Tp>& __y)
      |     ^~~~~~~~
/usr/include/c++/14/complex:400:5: note:   template argument deduction/substitution failed:
a.cc:250:31: note:   mismatched types 'const std::complex<_Tp>' and 'double'
  250 |     return b1+(b2-b1)*(num/den);
      |                               ^
/usr/include/c++/14/complex:409:5: note: candidate: 'template<class _Tp> std::complex<_Tp> std::operator*(const complex<_Tp>&, const _Tp&)'
  409 |     operator*(const complex<_Tp>& __x, const _Tp& __y)
      |     ^~~~~~~~
/usr/include/c++/14/complex:409:5: note:   template argument deduction/substitution failed:
a.cc:250:31: note:   deduced conflicting types for parameter 'const _Tp' ('long double' and 'double')
  250 |     return b1+(b2-b1)*(num/den);
      |                               ^
/usr/include/c++/14/complex:418:5: note: candidate: 'template<class _Tp> std::complex<_Tp> std::operator*(const _Tp&, const complex<_Tp>&)'
  418 |     operator*(const _Tp& __x, const complex<_Tp>& __y)
      |     ^~~~~~~~
/usr/include/c++/14/complex:418:5: note:   template argument deduction/substitution failed:
a.cc:250:31: note:   mismatched types 'const std::complex<_Tp>' and 'double'
  250 |     return b1+(b2-b1)*(num/den);
      |                               ^
a.cc: In instantiation of 'int sgn(T) [with T = long double]':
a.cc:107:11:   required from here
  107 |     if(sgn(d-r)>=0) return;
      |        ~~~^~~~~
a.cc:33:10: error: no matching function for call to 'eq(long double&, double)'
   33 |     if(eq(a,0.0)) return 0;
      |        ~~^~~~~~~
a.cc:29:24: note: candidate: 'template<class T> bool eq(T, T)'
   29 | template<class T> bool eq(T a,T b){
      |                        ^~
a.cc:29:24: note:   template argument deduction/substitution failed:
a.cc:33:10: note:   deduced conflicting types for parameter 'T' ('long double' and 'double')
   33 |     if(eq(a,0.0)) return 0;
      |        ~~^~~~~~~