use std::cmp;
use std::cmp::max;

fn main() {
    let (r, w) = (std::io::stdin(), std::io::stdout());
    let mut sc = IO::new(r.lock(), w.lock());
    loop {
        let n: usize = sc.read();
        if n == 0 {
            return;
        }

        let mut buildings = vec![];
        for _ in 0..n {
            let v: usize = sc.read();
            let h: f64 = sc.read();
            let v: Vec<(f64, f64)> = (0..v).map(|_| (sc.read(), sc.read())).collect();
            buildings.push((h, v));
        }

        let theta: f64 = sc.read::<f64>().to_radians();
        let phi: f64 = sc.read::<f64>().to_radians();
        let mut points = vec![];
        for (h, mut v) in buildings.into_iter() {
            let r = h / phi.tan();
            let n = v.len();
            for i in 0..n {
                let (x, y) = v[i];
                let dy = -theta.sin() * r;
                let dx = -theta.cos() * r;
                let nx = x + dx;
                let ny = y + dy;
                v.push((nx, ny));
            }

            let p = v
                .into_iter()
                .map(|(x, y)| Point { x, y })
                .collect::<Vec<_>>();
            let i = extract_convex_hull(&p, false);
            let p = i.into_iter().map(|i| p[i]).collect::<Vec<_>>();
            points.push(p);
        }

        let sx: f64 = sc.read();
        let sy: f64 = sc.read();
        let tx: f64 = sc.read();
        let ty: f64 = sc.read();

        points.push(vec![Point { x: sx, y: sy }]);
        points.push(vec![Point { x: tx, y: ty }]);

        let n = points.len();
        let mut dist = vec![vec![1e18; n]; n];
        for i in 0..n {
            dist[i][i] = 0.0;
            for j in 0..i {
                dist[i][j] = b2b_d2(&points[i], &points[j]).sqrt();
                dist[j][i] = dist[i][j];
            }
        }

        for k in 0..n {
            for i in 0..n {
                for j in 0..n {
                    dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]);
                }
            }
        }

        println!("{}", dist[n - 2][n - 1]);
    }
}

fn min<T: PartialOrd>(a: T, b: T) -> T {
    if a > b {
        b
    } else {
        a
    }
}

fn b2b_d2(b1: &[Point], b2: &[Point]) -> f64 {
    let mut min_d = 1e18;

    for b1i in 0..b1.len() {
        let p0 = b1[b1i];
        for b2i in 0..b2.len() {
            let p1 = b2[b2i];
            let p2 = b2[(b2i + 1) % b2.len()];
            min_d = min(min_d, min_d2(&p0, &p1, &p2));
        }

        if is_included(&p0, b2) {
            return 0.0;
        }
    }
    for b2i in 0..b2.len() {
        let p0 = b2[b2i];
        for b1i in 0..b1.len() {
            let p1 = b1[b1i];
            let p2 = b1[(b1i + 1) % b1.len()];
            min_d = min(min_d, min_d2(&p0, &p1, &p2));
        }

        if is_included(&p0, b1) {
            return 0.0;
        }
    }

    for i in 0..b1.len() {
        for j in 0..b2.len() {
            let dx = b1[i].x - b2[j].x;
            let dy = b1[i].y - b2[j].y;
            min_d = min(min_d, dx * dx + dy * dy);
        }
    }
    min_d
}

fn is_included(p: &Point, convex: &[Point]) -> bool {
    let mut convex = convex.to_vec();
    convex.push(p.clone());
    let c = extract_convex_hull(&convex, false);
    if c.contains(&(convex.len() - 1)) {
        false
    } else {
        true
    }
}

fn min_d2(p0: &Point, p1: &Point, p2: &Point) -> f64 {
    let x0 = p0.x;
    let y0 = p0.y;
    let x1 = p1.x;
    let y1 = p1.y;
    let x2 = p2.x;
    let y2 = p2.y;
    let a = x2 - x1;
    let b = y2 - y1;
    let a2 = a * a;
    let b2 = b * b;
    let r2 = a2 + b2;
    let tt = -(a * (x1 - x0) + b * (y1 - y0));
    if tt < 0.0 {
        return (x1 - x0) * (x1 - x0) + (y1 - y0) * (y1 - y0);
    }
    if tt > r2 {
        return (x2 - x0) * (x2 - x0) + (y2 - y0) * (y2 - y0);
    }
    let f1 = a * (y1 - y0) - b * (x1 - x0);
    return (f1 * f1) / r2;
}

pub fn extract_convex_hull(points: &[Point], contain_on_segment: bool) -> Vec<usize> {
    let n = points.len();
    if n <= 1 {
        return vec![0];
    }

    let mut ps: Vec<usize> = (0..n).collect();
    ps.sort_by(|&a, &b| {
        if (points[a].x - points[b].x).abs() < std::f64::EPSILON {
            points[a].y.partial_cmp(&points[b].y).unwrap()
        } else {
            points[a].x.partial_cmp(&points[b].x).unwrap()
        }
    });

    let mut qs: Vec<usize> = Vec::new();
    for &i in &ps {
        while qs.len() > 1 {
            let k = qs.len();
            let det = (points[qs[k - 1]] - points[qs[k - 2]]).det(&(points[i] - points[qs[k - 1]]));
            if det < 0.0 || (det <= 0.0 && !contain_on_segment) {
                qs.pop();
            } else {
                break;
            }
        }
        qs.push(i);
    }

    let t = qs.len();
    for i in (0..(n - 1)).rev() {
        let i = ps[i];
        while qs.len() > t {
            let k = qs.len();
            let det = (points[qs[k - 1]] - points[qs[k - 2]]).det(&(points[i] - points[qs[k - 1]]));
            if det < 0.0 || (det <= 0.0 && !contain_on_segment) {
                qs.pop();
            } else {
                break;
            }
        }
        qs.push(i);
    }

    qs.pop();
    qs
}

#[derive(Debug, Copy, Clone)]
pub struct Point {
    x: f64,
    y: f64,
}

impl std::ops::Sub for Point {
    type Output = Point;
    fn sub(self, other: Point) -> Point {
        Point {
            x: self.x - other.x,
            y: self.y - other.y,
        }
    }
}

impl Point {
    pub fn det(&self, other: &Point) -> f64 {
        self.x * other.y - self.y * other.x
    }
}
pub struct IO<R, W: std::io::Write>(R, std::io::BufWriter<W>);

impl<R: std::io::Read, W: std::io::Write> IO<R, W> {
    pub fn new(r: R, w: W) -> Self {
        IO(r, std::io::BufWriter::new(w))
    }
    pub fn write<S: ToString>(&mut self, s: S) {
        use std::io::Write;
        self.1.write_all(s.to_string().as_bytes()).unwrap();
    }
    pub fn read<T: std::str::FromStr>(&mut self) -> T {
        use std::io::Read;
        let buf = self
            .0
            .by_ref()
            .bytes()
            .map(|b| b.unwrap())
            .skip_while(|&b| b == b' ' || b == b'\n' || b == b'\r' || b == b'\t')
            .take_while(|&b| b != b' ' && b != b'\n' && b != b'\r' && b != b'\t')
            .collect::<Vec<_>>();
        unsafe { std::str::from_utf8_unchecked(&buf) }
            .parse()
            .ok()
            .expect("Parse error.")
    }
    pub fn vec<T: std::str::FromStr>(&mut self, n: usize) -> Vec<T> {
        (0..n).map(|_| self.read()).collect()
    }
    pub fn chars(&mut self) -> Vec<char> {
        self.read::<String>().chars().collect()
    }
}



Measured memory_bytes: 5292