from fractions import Fraction as F from math import gcd import itertools def edges(poly): return [(poly[i],poly[(i+1)%len(poly)]) for i in range(len(poly))] def reflect(d,a,b): ex,ey=b[0]-a[0],b[1]-a[1] dx,dy=d if ey==0: return (dx,-dy) if ex==0: return (-dx,dy) if ex*ey>0: return (dy,dx) return (-dy,-dx) def cross(ax,ay,bx,by): return ax*by-ay*bx def trace(poly,S,d,D,maxsteps=100000): """exact: returns 'lit','corner','loop'""" E=edges(poly); V=set(tuple(map(F,v)) for v in poly) P=(F(S[0]),F(S[1])); seen=set(); path=[P]; last=None for _ in range(maxsteps): best=None for i,(a,b) in enumerate(E): if i==last: continue ex,ey=b[0]-a[0],b[1]-a[1] den=cross(d[0],d[1],ex,ey) if den==0: continue wx,wy=a[0]-P[0],a[1]-P[1] t=F(cross(wx,wy,ex,ey),den); u=F(cross(wx,wy,d[0],d[1]),den) if t<=0 or u<0 or u>1: continue if best is None or tQ ? wx,wy=D[0]-P[0],D[1]-P[1] if cross(wx,wy,d[0],d[1])==0: s=F(wx*d[0]+wy*d[1], d[0]*d[0]+d[1]*d[1]) if 0