#include #include #include #include #include #include using namespace std; #define E 0.00000000001 typedef pair Point; int ccw( Point &p0, Point &p1, Point &p2 ) { double dx1 = p1.first - p0.first; double dy1 = p1.second - p0.second; double dx2 = p2.first - p0.first; double dy2 = p2.second - p0.second; double cp = dx1 * dy2 - dy1 * dx2; if( cp > +E ) return +1; if( cp < -E ) return -1; return 0; if( dx1 * dx2 < -E || dy1 * dy2 < -E ) return -1; if( dx1 * dx1 + dy1 * dy1 + E < dx2 * dx2 + dy2 * dy2 ) return +1; } int intersect( Point p0, Point p1, Point q0, Point q1 ) { return ccw( p0, p1, q0 ) * ccw( p0, p1, q1 ) < 0 && ccw( q0, q1, p0 ) * ccw( q0, q1, p1 ) < 0; } int cp0( double a, double b, double c, double d, double e, double f, Point &r0 ) { double A = b * d - a * e; double B = a * f - c * d; if( A != 0 ){ r0.second = B / A; if( fabs(a) > fabs(d) ) r0.first = (-c -b * r0.second) / a; else r0.first = (-f -e * r0.second) / d; return 0; } else return -1; } int cp1( Point p0, Point p1, Point q0, Point q1, Point &r ) { double x0, y0, x1, y1; x0 = p0.first; y0 = p0.second; x1 = p1.first; y1 = p1.second; double a = y0 - y1, b = x1 - x0, c = x0 * y1 - x1 * y0; x0 = q0.first; y0 = q0.second; x1 = q1.first; y1 = q1.second; double d = y0 - y1, e = x1 - x0, f = x0 * y1 - x1 * y0; return cp0( a, b, c, d, e, f, r ); } void get( double x0, double y0, double x1, double y1, double p, double q, double &x, double &y ) { double a = y1 - y0; double b = -(x1 - x0); double c = y1 * x0 - x1 * y0; double d = -b; double e = a; double f = d * p + e * q; x = 2 * (c * e - b * f) / (a * e - b * d) - p; y = 2 * (a * f - c * d) / (a * e - b * d) - q; // printf( "mirror: (%lf, %lf) - (%lf, %lf)\n", x0, y0, x1, y1 ); // printf( "(%lf, %lf) -> (%lf, %lf)\n", p, q, x, y ); return; } int main( void ) { FILE *in = fopen( "mirror.in", "r" ); if( in == NULL ) return 0; int TT; while( 1 ){ double X, Y; fscanf( in, "%lf%lf\n", &X, &Y ); if( X == 0 && Y == 0 ) break; double x0[2], y0[2], x1[2], y1[2]; fscanf( in, "%lf%lf%lf%lf\n", x0 + 0, y0 + 0, x1 + 0, y1 + 0 ); double X0, Y0, X1, Y1; fscanf( in, "%lf%lf%lf%lf\n", x0 + 1, y0 + 1, x1 + 1, y1 + 1 ); int r = 0; vector< pair > ps; ps.push_back( pair( X, Y ) ); int mirror = 0; int CC = 0; for( double x = X, y = Y; CC < 10000; mirror = 1 - mirror, CC ++ ){ double xx, yy; get( x0[mirror], y0[mirror], x1[mirror], y1[mirror], x, y, xx, yy ); // printf( "%lf, %lf\n", xx, yy ); ps.push_back( Point(xx, yy) ); x = xx, y = yy; xx = X, yy = Y; int flag = 1; for( int i = ps.size() - 1, mirror0 = mirror; i >= 0; i --, mirror0 = 1 - mirror0 ){ Point aa(x0[mirror0], y0[mirror0]), bb(x1[mirror0], y1[mirror0]), ee(x0[1-mirror0], y0[1-mirror0]), ff(x1[1-mirror0], y1[1-mirror0]), cc(xx, yy), dd(ps[i].first, ps[i].second); if( i == ps.size() - 1 ){ /* printf( "mirrorA: (%lf, %lf) - (%lf, %lf)\n", aa.first, aa.second, bb.first, bb.second ); printf( "mirrorB: (%lf, %lf) - (%lf, %lf)\n", ee.first, ee.second, ff.first, ff.second ); printf( "eye: (%lf, %lf) - (%lf, %lf)\n", cc.first, cc.second, dd.first, dd.second ); */ if( intersect( aa, bb, cc, dd ) ){ Point auau; if( cp1( aa, bb, cc, dd, auau ) < 0 ){ flag = 0; break; } if( intersect( ee, ff, cc, auau ) ){ flag = 0; break; } xx = auau.first, yy = auau.second; } else{ flag = 0; break; } } else if( i == 0 ){ if( intersect( aa, bb, cc, dd ) ){ flag = 0; break; } } else{ /* printf( "mirrorA: (%lf, %lf) - (%lf, %lf)\n", aa.first, aa.second, bb.first, bb.second ); printf( "mirrorB: (%lf, %lf) - (%lf, %lf)\n", ee.first, ee.second, ff.first, ff.second ); printf( "eye: (%lf, %lf) - (%lf, %lf)\n", cc.first, cc.second, dd.first, dd.second ); */ if( intersect( aa, bb, cc, dd ) ){ Point auau; if( cp1( aa, bb, cc, dd, auau ) < 0 ){ flag = 0; break; } xx = auau.first, yy = auau.second; } else{ flag = 0; break; } } } // if( !flag ) // break; if( flag ) r ++; // printf( "%lf, %lf\n", x, y ); if( r >= 101 ) break; } mirror = 1; ps.clear(); ps.push_back( pair( X, Y ) ); CC = 0; for( double x = X, y = Y; CC < 10000; mirror = 1 - mirror, CC ++ ){ double xx, yy; get( x0[mirror], y0[mirror], x1[mirror], y1[mirror], x, y, xx, yy ); // printf( "%lf, %lf\n", xx, yy ); ps.push_back( Point(xx, yy) ); x = xx, y = yy; xx = X, yy = Y; int flag = 1; for( int i = ps.size() - 1, mirror0 = mirror; i >= 0; i --, mirror0 = 1 - mirror0 ){ Point aa(x0[mirror0], y0[mirror0]), bb(x1[mirror0], y1[mirror0]), ee(x0[1-mirror0], y0[1-mirror0]), ff(x1[1-mirror0], y1[1-mirror0]), cc(xx, yy), dd(ps[i].first, ps[i].second); if( i == ps.size() - 1 ){ /* printf( "mirrorA: (%lf, %lf) - (%lf, %lf)\n", aa.first, aa.second, bb.first, bb.second ); printf( "mirrorB: (%lf, %lf) - (%lf, %lf)\n", ee.first, ee.second, ff.first, ff.second ); printf( "eye: (%lf, %lf) - (%lf, %lf)\n", cc.first, cc.second, dd.first, dd.second ); */ if( intersect( aa, bb, cc, dd ) ){ Point auau; if( cp1( aa, bb, cc, dd, auau ) < 0 ){ flag = 0; break; } if( intersect( ee, ff, cc, auau ) ){ flag = 0; break; } xx = auau.first, yy = auau.second; } else{ flag = 0; break; } } else if( i == 0 ){ if( intersect( aa, bb, cc, dd ) ){ flag = 0; break; } } else{ /* printf( "mirrorA: (%lf, %lf) - (%lf, %lf)\n", aa.first, aa.second, bb.first, bb.second ); printf( "mirrorB: (%lf, %lf) - (%lf, %lf)\n", ee.first, ee.second, ff.first, ff.second ); printf( "eye: (%lf, %lf) - (%lf, %lf)\n", cc.first, cc.second, dd.first, dd.second ); */ if( intersect( aa, bb, cc, dd ) ){ Point auau; if( cp1( aa, bb, cc, dd, auau ) < 0 ){ flag = 0; break; } xx = auau.first, yy = auau.second; } else{ flag = 0; break; } } } // if( !flag ) // break; if( flag ) r ++; // printf( "%lf, %lf\n", x, y ); if( r >= 101 ) break; } if( r >= 100 ) printf( "TOO MANY\n" ); else printf( "%d\n", r ); } fclose( in ); return 0; }