#include #include #include #include #include #include #include #include #include using namespace std; typedef pair< int, pair > term; typedef vector< term > value; #define A second.first #define B second.second #define R first typedef pair Point; #define E 0.000000000000001 #define x first #define y second int ccw2( Point &p0, Point &p1, Point &p2 ) { double dx1 = p1.x - p0.x; double dy1 = p1.y - p0.y; double dx2 = p2.x - p0.x; double dy2 = p2.y - p0.y; double cp = dx1 * dy2 - dy1 * dx2; if( cp > +E ) return +1; if( cp < -E ) return -1; return 0; } int prop_intersect( Point &p0, Point &p1, Point &q0, Point &q1 ) { return ccw2( p0, p1, q0 ) * ccw2( p0, p1, q1 ) < 0 && ccw2( q0, q1, p0 ) * ccw2( q0, q1, p1 ) < 0; } int cp3( Point &p0, Point &p1, Point &q0, Point &q1, double *s, double *t ) { double x0 = p0.x; double y0 = p0.y; double x1 = p1.x; double y1 = p1.y; double a = + p1.x - p0.x; double c = + p1.y - p0.y; double b = - q1.x + q0.x; double d = - q1.y + q0.y; double X = + q0.x - p0.x; double Y = + q0.y - p0.y; double det = a * d - b * c; *s = (+ d * X - b * Y) / det; *s = max( *s, 0.0 ); *s = min( *s, 1.0 ); *t = (- c * X + a * Y) / det; *t = max( *t, 0.0 ); *t = min( *t, 1.0 ); return 0; } #undef x #undef y Point cp[500][500]; int iscp[500][500]; int main( void ) { FILE *in = fopen( "hills.in", "r" ); int T; fscanf( in, "%d", &T ); for( int C = 0; C < T; C ++ ){ int n; fscanf( in, "%d", &n ); #define N n vector< pair > l; for( int i = 0; i < N; i ++ ){ double x0, y0, x1, y1; fscanf( in, "%lf%lf%lf%lf", &x0, &y0, &x1, &y1 ); l.push_back( pair( Point(x0,y0),Point(x1,y1) ) ); } vector< vector< pair< double, int > > > cp2( n ); for( int i = 0; i < n; i ++ ){ for( int j = i + 1; j < n; j ++ ){ double s, t; if( prop_intersect( l[i].first, l[i].second, l[j].first, l[j].second ) ){ cp3( l[i].first, l[i].second, l[j].first, l[j].second, &s, &t ); cp2[i].push_back( pair< double, int >( s, j ) ); cp2[j].push_back( pair< double, int >( t, i ) ); Point pp( l[i].first.first + s * (l[i].second.first - l[i].first.first), l[i].first.second + s * (l[i].second.second - l[i].first.second) ); // printf( "%d and %d: %lf, %lf (%lf, %lf)\n", i, j, s, t, pp.first, pp.second ); cp[i][j] = cp[j][i] = pp; iscp[i][j] = iscp[j][i] = 1; } else iscp[i][j] = iscp[j][i] = 0; } } int r = 0; for( int i = 0; i < n; i ++ ){ sort( cp2[i].begin(), cp2[i].end() ); for( int J = 0; J + 1 < cp2[i].size(); J ++ ){ int j = cp2[i][J].second; int k = cp2[i][J+1].second; if( !( i < j && i < k ) ) continue; Point p0 = cp[i][j]; Point p1 = cp[i][k]; Point p2 = cp[j][k]; if( !iscp[j][k] || j == k ) continue; int flag = 1; // printf( "%d, %d, %d\n", i, j, k ); for( int k2 = 0; k2 < n; k2 ++ ){ if( k2 == i || k2 == j || k2 == k ) continue; if( prop_intersect( p0, p1, l[k2].first, l[k2].second ) || prop_intersect( p2, p1, l[k2].first, l[k2].second ) || prop_intersect( p2, p0, l[k2].first, l[k2].second ) ){ // printf( "%d, %d, %d: %d\n", i, j, k, k2 ); flag = 0; break; } } if( flag ){ // printf( "%d, %d, %d\n", i, j, k ); r += flag; } } } printf( "%d\n", r ); } }