#include <iostream>
#include <iomanip>
#include <complex>
#include <vector>
#include <map>
#include <algorithm>
#include <limits>
using namespace std;

// 点
typedef complex<double> point;
istream& operator>>( istream& is, point& pt )
{
	double x, y;
	is >> x >> y;
	pt = point(x,y);
	return is;
}

// 光線 : a-->b
struct ray
{
	point a, b;
	ray( point a, point b ) : a(a), b(b) {}
};

// 辺 : a-->b : 左が内側
struct edge
{
	point a, b;
	edge( point a, point b ) : a(a), b(b) {}

	vector<double> cross;

	// 辺に関して点を鏡像反転
	point flip( point p ) const
	{
		point v = (b-a)/abs(b-a);
		return conj((p-a)/v)*v + a;
	}

	// 光線との交点計算
	bool cross_impl( const ray& r, double* cp=0, double* rp=0 ) const
	{
		// ra-->rb と 0-->len の交点があれば、という問題に変換
		double len = abs(b-a);
		point   ra = (r.a-a) / ((b-a)/len);
		point   rb = (r.b-a) / ((b-a)/len);

		// 自明にダメな例をはじく
		if( ra.imag() <= 0 )      return false; // 始点が壁の裏
		if( (rb-ra).imag() >= 0 ) return false; // 光線が逆方向

		// 実軸との交点を計算
		double p =
			(-ra.imag() * (rb-ra).real() / (rb-ra).imag() + ra.real()) / len;
		if(cp) *cp=p;
		if(rp) *rp=(-ra.imag() / (rb-ra).imag());
		double eps = numeric_limits<double>::epsilon();
		return (0-eps<=p && p<=1+eps);
	}

	bool rayseg_crosses( const ray& r, point* pt=0 ) const
	{
		double p, q;
		if( !cross_impl(r,&p,&q) || !(0<q && q<1) )
			return false;
		if(pt) *pt = (b-a)*p+a;
		return true;
	}

	void add_cross( const ray& r )
	{
		double p;
		if( cross_impl(r,&p) )
			cross.push_back(p);
	}

	// Sortして重複除去
	void manip_cross()
	{
		sort( cross.begin(), cross.end() );
		cross.erase( unique(cross.begin(),cross.end()), cross.end() );
	}

	// この辺上の点pが0回or1回反射でsrcから見えるかどうか
	// pからsrcへの任意の経路は他の頂点をかすめないことが保証されている
	bool is_pt_visible( const vector<edge>& es, point src, double pp )
	{
		point p = a+(b-a)*pp;
		if( !is_ray_collides(es,ray(src,p)) )
		{
			cerr << "direct" << endl;
			return true;
		}
		for(int j=0; j!=es.size(); ++j)
			if( &es[j] != this )
			{
				point q;
				if( es[j].rayseg_crosses( ray(src,es[j].flip(p)), &q ) )
					if( !is_ray_collides(es,ray(src,q)) )
					if( !is_ray_collides(es,ray(q,p)) )
					{
						cerr << "reflection at: " << src << "===" << q << "===>"
							<< es[j].flip(p) << endl;
						return true;
					}
			}
		return false;
	}

	// 光線分が壁にぶつかるか?
	bool is_ray_collides( const vector<edge>& es, const ray& r )
	{
		for(int j=0; j!=es.size(); ++j)
			if( es[j].rayseg_crosses(r) )
				return true;
		return false;
	}
};

double solve( vector<edge>& es, const vector<point>& ps, point src )
{
	// 0回反射、1回反射で出現しうる全光線を列挙
	vector<ray> rs;
	for(int i=0; i!=ps.size(); ++i)
		rs.push_back( ray(src,ps[i]) );
	for(int j=0; j!=es.size(); ++j)
		for(int i=0; i!=ps.size(); ++i)
			rs.push_back( ray(es[j].flip(src),ps[i]) ),
			rs.push_back( ray(es[j].flip(src),es[j].flip(ps[i])) );

	// 全光線から出現しうる全交点を列挙
	for(int j=0; j!=es.size(); ++j)
		for(int k=0; k!=rs.size(); ++k)
			es[j].add_cross(rs[k]);

	// 列挙した交点をSortして重複除去
	for(int j=0; j!=es.size(); ++j)
		es[j].manip_cross();

	// 各区間が見えるか見えないか判定して和を取る
	double sum = 0.0;
	for(int j=0; j!=es.size(); ++j)
		for(int k=0; k+1<es[j].cross.size(); ++k)
			if( !es[j].is_pt_visible(es,src,(es[j].cross[k]+es[j].cross[k+1])/2) )
				cerr << "D: " << es[j].a+(es[j].b-es[j].a)*es[j].cross[k]
			         << "-"   << es[j].a+(es[j].b-es[j].a)*es[j].cross[k+1] << endl,
				sum += abs(es[j].b-es[j].a) * (es[j].cross[k+1]-es[j].cross[k]);
			else
				cerr << "L: " << es[j].a+(es[j].b-es[j].a)*es[j].cross[k]
			         << "-"   << es[j].a+(es[j].b-es[j].a)*es[j].cross[k+1] << endl;
	return sum;
}

int main()
{
	for(int N; cin>>N,N; )
	{
		// 入力
		vector<point> ps(N);
		for(int i=0; i!=N; ++i)
			cin >> ps[i];
		point src;
			cin >> src;

		// 加工
		vector<edge> es;
		for(int i=0; i!=N; ++i)
			es.push_back( edge(ps[i%N],ps[(i+1)%N])  );

		// 出力
		cout << setiosflags(ios::fixed) << setprecision(8)
		     << solve(es,ps,src) << endl;
	}
}