#include <bits/stdc++.h>
#define REP(i,n) for (int i=0;i<(n);i++)
#define FOR(i,a,n) for (int i = (a);i<(n);i++)
const double PI = acos(-1);
const double EPS = 1e-10;
using namespace std;
double INF = 1e+9;
int N;
double theta, phi;
    int V[103], H[103];
    double x[103][13], y[102][13];
double sx, sy, tx, ty;
double mindist[103][103];
struct Point{
  double x,y;
  Point operator - (const Point& p) {return Point{x - p.x, y - p.y};}
};
struct Segment{
  Point p1,p2;
};

double norm(Point a){return a.x*a.x + a.y*a.y;}
double abs(Point a){return sqrt(norm(a));}
double dot(Point a, Point b){return a.x * b.x + a.y * b.y;}
double cross(Point a, Point b){return a.x * b.y - a.y * b.x;}

int ccw(Point p1,Point p2, Point p3){
  Point a = p2 - p1;
  Point b = p3 - p1;
  if(cross(a,b) > EPS)return 1;
  if(cross(a,b) < -EPS)return -1;
  if(dot(a,b) < -EPS)return 2;
  if(norm(a)< norm(b)) return -2;
     return 0;
}

bool intersect(Point p1, Point p2, Point p3, Point p4){
  return ccw(p1,p2,p3) * ccw(p1,p2,p4) <= 0 && ccw(p3,p4,p1)*ccw(p3,p4,p2) <= 0;
  }
bool intersect(Segment s1, Segment s2){
  return intersect(s1.p1, s1.p2, s2.p1, s2.p2);
}
double getDistSP(Segment s, Point p){
  if(dot(s.p2 - s.p1, p - s.p1) < EPS) return abs(p - s.p1);
  if(dot(s.p1 - s.p2, p - s.p2) < EPS) return abs(p - s.p2);
  return abs(cross(s.p2 - s.p1, p - s.p1) / abs(s.p2 - s.p1));
}

double getDist(Segment s1, Segment s2){
  if(intersect(s1.p1, s1.p2, s2.p1,s2.p2)) return 0.0;
  return min(min(getDistSP(s1, s2.p1),getDistSP(s1,s2.p2)),
             min(getDistSP(s2, s1.p1), getDistSP(s2, s1.p2)));
}
using Polygon = vector<Point>;

static const int COUNTER_CLOCKWISE = 1;
bool compare(const Point& a,const Point& b){
	if(a.y == b.y)return a.x < b.x;
	return a.y < b.y;
}

Polygon andrewScan(Polygon g){
	Polygon u,l;
	if(g.size() < 3) return g;
  sort(g.begin(),g.end(),compare);//compare????????§x???????????????
	u.push_back(g[0]);
	u.push_back(g[1]);
	l.push_back(g[g.size() - 1]);
	l.push_back(g[g.size() - 2]);
	// ??????????????¨?????????
	for(int i =2;i < g.size();i++){
		for(int n = u.size();n>=2&&ccw(u[n-2],u[n-1],g[i]) == COUNTER_CLOCKWISE;n--){
			u.pop_back();
		}
		u.push_back(g[i]);
	}
	// ??????????????¨?????????
	for(int i = g.size() - 3;i >= 0;i--){
		for(int n = l.size();n>=2&&ccw(l[n-2],l[n-1],g[i])==COUNTER_CLOCKWISE;n--){
			l.pop_back();
		}
		l.push_back(g[i]);
	}
		reverse(l.begin(),l.end());
	for(int i = u.size() - 2;i>=1;i--)l.push_back(u[i]);
	return l;
}

int contains(Polygon& g, Point p){
	int n = g.size();
	bool x = false;
	REP(i,n){
 		Point a = g[i] - p, b = g[(i+1)%n] - p;
		if(abs(cross(a,b)) < EPS && dot(a,b) < EPS)return 1;
		if(a.y > b.y) swap(a,b);
		if(a.y < EPS && EPS < b.y && cross(a,b) > EPS) x = !x;
	}
	return x ? 2 : 0;
}

vector<Point> buildings[103];// 0 is builidings, 1 is shade
int main(){
  while(cin >> N, N){
    REP(i,N){
      cin >> V[i] >> H[i];
      REP(j,V[i]){
        cin >> x[i][j] >> y[i][j];
      }
    }
    cin >> theta >> phi;
    cin >> sx >> sy >> tx >> ty;
    REP(i,N){
      buildings[i].clear();
      double xshade = -H[i] / tan(phi / 180.0 * PI) * cos(theta/ 180.0 * PI);
      double yshade = -H[i] / tan(phi / 180.0 * PI) * sin(theta/ 180.0 * PI);
      REP(j,V[i]){
        buildings[i].push_back(Point{x[i][j], y[i][j]});
        buildings[i].push_back(Point{x[i][j] + xshade, y[i][j] + yshade});
      }
      buildings[i] = andrewScan(buildings[i]);
    }
    buildings[N].clear();
    buildings[N + 1].clear();
    buildings[N].push_back(Point{sx, sy});
    buildings[N + 1].push_back(Point{tx, ty});
    N+=2;
    V[N-2] = V[N-1] = 1;
    fill(mindist[0], mindist[N], INF);
    REP(i,N){
      FOR(j,i + 1,N){
        for(int a = 0;a < buildings[i].size();a++)
          for(int b = 0;b < buildings[j].size();b++){
            int a_n = buildings[i].size();
            int b_n = buildings[j].size();
            Segment s1 = Segment{buildings[i][a] ,buildings[i][(a+1)%a_n]};
            Segment s2 = Segment{buildings[j][b] ,buildings[j][(b+1)%b_n]};
            mindist[j][i] = mindist[i][j] = min(getDist(s1, s2),mindist[i][j]);
            if(contains(buildings[i],buildings[j][b]) || contains(buildings[j],buildings[i][a])){
              mindist[j][i] = mindist[i][j] = 0;
              break;
            }
          }
      }
    }
    REP(k,N){
      REP(i,N){
        REP(j,N){
          mindist[i][j] = min(mindist[i][j], mindist[i][k] + mindist[k][j]);
        }
      }
    }
    cout << fixed << setprecision(8) << mindist[N-2][N-1] << endl;
  }
  return 0;
}

Measured memory_bytes: 3784