//Based on Spaghetti source (http://www.prefield.com/algorithm/geometry/ccw.html.)
//Based on the library written by tailed.

#include <complex>
#include <vector>
#include <iostream>
#include <cassert>
using namespace std;

typedef complex<double> xy_t;
typedef pair<xy_t, xy_t> line_t;
typedef pair<xy_t, double> circle_t;
typedef vector<xy_t> poly_t;

namespace std {
  bool operator<(const xy_t &a, const xy_t &b){
    return a.real() == b.real() ? a.imag() < b.imag() : a.real() < b.real();
  }
}

const double EPS = 1e-9;

inline bool equal(double a, double b){
  return abs(a - b) < EPS;
}

istream &operator>>(istream &is, xy_t &p)   {
  double x, y;
  is >> x >> y;
  p = xy_t(x, y);
  return is;
}

istream &operator>>(istream &is, line_t &l) {
  return is >> l.first >> l.second;
}

inline double cross(const xy_t &a, const xy_t &b){
  return imag(conj(a) * b);
}

inline double dot(const xy_t &a, const xy_t &b){
  return real(conj(a) * b);
}

inline xy_t rotate(const xy_t &a, double theta){
  return a * polar(1.0, theta);
}

inline xy_t direction(const line_t &line){
  return line.second - line.first;
}

int ccw(const xy_t &a, xy_t b, xy_t c){
  b -= a;
  c -= a;
  if (cross(b, c) > 0) return 1;
  if (cross(b, c) < 0) return -1;
  if (dot(b, c)   < 0) return 2;
  if (norm(b) < norm(c)) return -2;
  return 0;
}

int ccw(const line_t &l, const xy_t &a){
  return ccw(l.first, l.second, a);
}

line_t bisector(const xy_t &a, const xy_t &b){
  xy_t v = rotate(b - a, M_PI / 4);
  xy_t m = (a + b) * 0.5;
  return line_t (m, m + v);
};

bool intersectSP(const line_t &s, const xy_t &p) {
  return abs(s.first - p) + abs(s.second - p) - abs(direction(s)) < EPS;
}

bool intersectSS(const line_t &s, const line_t &t) {
  return ccw(s, t.first) * ccw(s, t.second) <= 0 &&
         ccw(t, s.first) * ccw(t, s.second) <= 0;
}

xy_t projection(const line_t &l, const xy_t &p) {
  double t = dot(p - l.first, direction(l) / norm(direction(l)));
  return l.first + t*(direction(l));
}

double distanceSP(const line_t &s, const xy_t &p) {
  const xy_t r = projection(s, p);
  if (intersectSP(s, r)) return abs(r - p);
  return min(abs(s.first - p), abs(s.second - p));
}

double distanceSS(const line_t &s, const line_t &t) {
  if (intersectSS(s, t)) return 0;
  
  return min(min(distanceSP(s, t.second), distanceSP(s, t.second)),
             min(distanceSP(t, s.first ), distanceSP(t, s.second)));
}

xy_t crosspoint(const line_t &l, const line_t &m){
  xy_t l_vec = direction(l);
  xy_t m_vec = direction(m);
  double A = cross(l_vec, m_vec);
  assert(!equal(A, 0));
  return m.first + cross(l_vec, l.second-m.first) / A * m_vec;
}

inline size_t next_index(const poly_t &poly, size_t curr){
  return (curr + 1) % poly.size();
}

inline size_t prev_index(const poly_t &poly, size_t curr){
  return (curr + poly.size() - 1)  % poly.size();
}

poly_t convex_cut(const poly_t &poly, const line_t &line){
  poly_t new_poly;
  
  for (size_t i = 0; i < poly.size(); i++){
    xy_t a = poly[i];
    xy_t b = poly[next_index(poly, i)];

    if (ccw(line, a) != -1) new_poly.push_back(a);
    
    if (ccw(line, a) * ccw(line, b) < 0){
      new_poly.push_back(crosspoint(line_t (a, b), line));
    }
  }
  return new_poly;
}

double signed_area(const poly_t &poly){
  double res = 0;
  for (size_t i = 0; i < poly.size(); i++){
    res += cross(poly[i], poly[next_index(poly, i)]);
  }
  return res * 0.5;
}

double area(const poly_t &poly){
  return abs(signed_area(poly));
}