#include #include #include FILE *fp; double CX[30],CY[30],R[30]; double x,y,dx,dy,cx,cy; int NumS,Hits,Scene=1; double hitx,hity; int LastHit; /* per non rifare il controllo sulla stessa */ /* non fare con l'ultima toccata */ /* prende il t con la sfera i. 0 se non si toccano */ double IntSp(int i) { double cx,cy,a,b,t1,t2,r; double delta; cx = CX[i]; cy = CY[i]; r = R[i]; a = x-cx; b = y-cy; delta = (a*dx + b*dy)*(a*dx + b*dy) - (dx*dx + dy*dy)*(a*a + b*b - r*r); if (delta < 0) return 0; t1 = (-(a*dx + b*dy) + sqrt(delta)) / (dx*dx + dy*dy); t2 = (-(a*dx + b*dy) - sqrt(delta)) / (dx*dx + dy*dy); /* printf("trovo t = %f %f\n",t1,t2); */ if (t1 < 0 && t2 < 0) return 0; if (t1 < 0) return t2; if (t2 < 0) return t1; if (t1 < t2) return t1; else return t2; } void NewD() { double cpx,cpy,dpx,dpy,crx,cry,drx,dry; double px,py,det,a1,a2; cpx=cx; cpy=cy; dpx=hitx-cx; dpy=hity-cy; crx=x; cry=y; drx=-dpy; dry=dpx; det=dpx*dry-dpy*drx; a1=cpy*dpx-cpx*dpy; a2=cry*drx-crx*dry; px=(drx*a1-dpx*a2)/det; py=(dry*a1-dpy*a2)/det; dx=(2*px-x)-hitx; dy=(2*py-y)-hity; } /* -1 se non c'e' */ int Inter(void) { int i,mini; double min = 10E9; for (i=0; i < NumS; i++) if (i != LastHit) if (IntSp(i) > 0 && IntSp(i) < min ) { min = IntSp(i); mini = i; } if (min == 10E9) return -1; hitx = x+dx*min; hity = y+dy*min; cx = CX[mini]; cy = CY[mini]; NewD(); x = hitx; y = hity; LastHit = mini; /* printf("HIT in %f %f t = %f retta = %.2f %.2f %.2f %.2f\n",hitx,hity,min,x,y,dx,dy); */ return mini; } int main(void) { fp=fopen("reflect.in","r"); while (fscanf(fp,"%d",&NumS),NumS) { int i; for (i=0; i < NumS; i++) fscanf(fp,"%lf %lf %lf",&CX[i],&CY[i],&R[i]); fscanf(fp,"%lf %lf %lf %lf",&x,&y,&dx,&dy); printf("Scene %d\n",Scene++); LastHit = -1; /* okkio all'inf se sono esattamente dieci */ for (Hits =0; Hits < 10; Hits++) { int s = Inter(); if (s == -1) { puts("inf"); puts(""); break; } printf("%d ",s+1); } if (Hits >= 10) { if (Inter() == -1) puts("inf"); else puts("..."); puts(""); } } return 0; }