Problem:
Convex Cut   As shown in the figure above, cut a convex polygon g by a line p1p2 and print the area of the cut polygon which is on the left-hand side of the line.  g is represented by a sequence of points p 1 , p 2 ,..., p n where line segments connecting p i and p i+1 (1 ≤ i ≤ n−1 ) are sides of the convex polygon. The line segment connecting p n and p 1 is also a side of the polygon. Input The input is given in the following format:  g (the sequence of the points of the polygon) q (the number of queries = the number of target lines)
1st query
2nd query
: q th query  g is given as a sequence of points p 1 ,..., p n in the following format:  n  x 1  y 1  x 2  y 2 : x n  y n  The first integer n is the number of points. The coordinate of the i -th point p i is given by two integers x i and y i . The coordinates of points are given in the order of counter-clockwise visit of them. Note that all interior angles of given convex polygons are less than or equal to 180. For each query, a line represented by two points p1 and p2 is given. The coordinates of the points are given by four integers p1x , p1y , p2x and p2y . Output For each query, print the area of the cut polygon. The output values should be in a decimal fraction with an error less than 0.00001. Constraints  3 ≤ n ≤ 100  1 ≤ q ≤ 100  -10000 ≤ x i , y i ≤ 10000  -10000 ≤ p1x , p1y , p2x , p2y ≤ 10000  No point in g will occur more than once.  p1 ≠ p2  Sample Input 4
1 1
4 1
4 3
1 3
2
2 0 2 4
2 4 2 0 Sample Output 2.00000000
4.00000000

Solution (Python):
from sys import stdin
readline = stdin.readline


class vector:
    def cross(a, b):
        return a.real * b.imag - a.imag * b.real

    def dot(a, b):
        return a.real * b.real + a.imag * b.imag

    def ccw(a, b, c):
        b -= a
        c -= a
        if vector.cross(b, c) > 0:
            return 1 
        if vector.cross(b, c) < 0:
            return 2
        if vector.dot(b, c) < 0:
            return 3
        if abs(b) < abs(c):
            return 4
        return 5

    def polygon(p):
        if len(p) < 3:
            return 0
        return 0.5 * sum(vector.cross(p[i - 1], p[i]) for i in range(len(p)))

    def intersection(p1, p2, p3, p4):
        a1 = p4 - p2
        b1 = p2 - p3
        b2 = p1 - p2
        s1 = vector.cross(a1, b2) / 2
        s2 = vector.cross(a1, b1) / 2
        if s1 + s2 == 0:
            return 0
        c1 = p1 + (p3 - p1) * s1 / (s1 + s2)
        return c1


def main():
    n = int(readline())
    p = [map(float, readline().split()) for _ in range(n)]
    p = [x + y * 1j for x, y in p]
    q = int(readline())

    for _ in range(q):
        p1x, p1y, p2x, p2y = map(float, readline().split())
        p1, p2 = p1x + p1y * 1j, p2x + p2y * 1j

        pre_tmp = vector.ccw(p[-1], p1, p2)
        left = []
        for i in range(len(p)):
            tmp = vector.ccw(p[i], p1, p2)
            if pre_tmp != tmp and all(i in (1, 2) for i in (pre_tmp, tmp)):
                c1 = vector.intersection(p1, p[i - 1], p2, p[i])
                left.append(c1)
            if tmp != 2:
                left.append(p[i])

            pre_tmp = tmp
        print('{:.6f}'.format(vector.polygon(left)))
main()

Solution (Python):
from sys import stdin
readline = stdin.readline


class vector:
    def cross(a, b):
        return a.real * b.imag - a.imag * b.real

    def dot(a, b):
        return a.real * b.real + a.imag * b.imag

    def ccw(a, b, c):
        b -= a
        c -= a
        if vector.cross(b, c) > 0:
            return 1 
        if vector.cross(b, c) < 0:
            return 2
        if vector.dot(b, c) < 0:
            return 3
        if abs(b) < abs(c):
            return 4
        return 5

    def polygon(p):
        if len(p) < 3:
            return 0
        return 0.5 * sum(vector.cross(p[i - 1], p[i]) for i in range(len(p)))

    def intersection(p1, p2, p3, p4):
        a1 = p4 - p2
        b1 = p2 - p3
        b2 = p1 - p2
        s1 = vector.cross(a1, b2) / 2
        s2 = vector.cross(a1, b1) / 2
        if s1 + s2 == 0:
            return 0
        c1 = p1 + (p3 - p1) * s1 / (s1 + s2)
        return c1


def main():
    n = int(readline())
    p = [map(float, readline().split()) for _ in range(n)]
    p = [x + y * 1j for x, y in p]
    q = int(readline())

    for _ in range(q):
        p1x, p1y, p2x, p2y = map(float, readline().split())
        p1, p2 = p1x + p1y * 1j, p2x + p2y * 1j

        pre_tmp = vector.ccw(p[-1], p1, p2)
        left = []
        for i in range(len(p)):
            tmp = vector.ccw(p[i], p1, p2)
            if pre_tmp != tmp and all(i in (1, 2) for i in (pre_tmp, tmp)):
                c1 = vector.intersection(p1, p[i - 1], p2, p[i])
                left.append(c1)
            if tmp != 2:
                left.append(p[i])

            pre_tmp = tmp
        print('{:.6f}'.format(vector.polygon(left)))

import sys
if sys.hexversion >= 0x030203F0:
    main()
else:
    print('Error')

Solution (Python):
n = input()
ps = [map(int, raw_input().split()) for i in xrange(n)]
def intersection(p1, p2, q1, q2):
    dx0 = p2[0] - p1[0]
    dy0 = p2[1] - p1[1]
    dx1 = q2[0] - q1[0]
    dy1 = q2[1] - q1[1]
    a = dy0*dx1; b = dy1*dx0; c = dx0*dx1; d = dy0*dy1
    if a == b: return None
    x = (a*p1[0] - b*q1[0] + c*(q1[1] - p1[1])) / float(a - b)
    y = (b*p1[1] - a*q1[1] + d*(q1[0] - p1[0])) / float(b - a)
    return x, y
def cross(a, b, c):
    return (b[0]-a[0])*(c[1]-a[1]) - (b[1]-a[1])*(c[0]-a[0])
def calc_area(ps):
    return abs(sum(ps[i][0]*ps[i-1][1] - ps[i][1]*ps[i-1][0] for i in xrange(len(ps)))) / 2.
for t in xrange(input()):
    vs = []
    x1, y1, x2, y2 = map(int, raw_input().split())
    p1 = (x1, y1); p2 = (x2, y2)
    for i in xrange(n):
        q1 = ps[i-1]; q2 = ps[i]
        if cross(p1, p2, q1) * cross(p1, p2, q2) <= 0:
            r = intersection(p1, p2, q1, q2)
            if r is not None:
                vs.append(r)
        if cross(p1, p2, q2) >= 0:
            vs.append(q2)
    print "%.09f" % calc_area(vs)

Solution (Python):
def cross(a, b):
    return a.real * b.imag - a.imag * b.real


def cross_point(c, d):
    l = d - c
    v1 = cross(lv, l)
    v2 = cross(lv, lt - c)
    return c + v2 / v1 * l


n = int(input())
points = [complex(*map(int, input().split())) for _ in range(n)]
point0 = points.pop(0)
points.append(point0)

q = int(input())
while q:
    x1, y1, x2, y2 = map(int, input().split())
    ls, lt = (x1 + 1j * y1, x2 + 1j * y2)
    lv = lt - ls

    area = 0
    prev = point0
    prev_flag = cross(lv, prev - ls) >= 0
    cp1, cp2 = None, None
    for p in points:
        curr_flag = cross(lv, p - ls) >= 0
        if prev_flag and curr_flag:
            area += cross(prev, p)
        elif prev_flag != curr_flag:
            cp = cross_point(prev, p)
            if prev_flag:
                area += cross(prev, cp)
                cp1 = cp
            else:
                area += cross(cp, p)
                cp2 = cp
        prev, prev_flag = p, curr_flag
    if cp1 is not None and cp2 is not None:
        area += cross(cp1, cp2)
    print(area / 2)
    q -= 1

Solution (Python):

def cross(c1, c2):
    return c1.real * c2.imag - c1.imag * c2.real

def cross_point(p1, p2, p3, p4):
    
    
    base = p4 - p3
    hypo1 = p1 - p3
    hypo2 = p2 - p3
    d1 = cross(base, hypo1) / abs(base)
    d2 = cross(base, hypo2) / abs(base)
    cp = p1 + d1 / (d1 - d2) * (p2 - p1)
    return cp


def _area_of_triangle(c1, c2, c3):
    v1 = c2 - c1
    v2 = c3 - c1
    return abs(v1.real * v2.imag - v1.imag * v2.real) / 2


def convex_cut(points, c1, c2):
    points.append(points[0])
    ref_vec = c2 - c1
    cross_point1 = None
    flag = 0
    
    for i, segment in enumerate(zip(points, points[1:])):
        p1, p2 = segment
        cross1 = cross(ref_vec, p1 - c1)
        cross2 = cross(ref_vec, p2 - c1)
        flag += cross1
        if cross1 <= 0 and cross2 > 0:
            cross_point1 = cross_point(c1, c2, p1, p2)
            points = points[i+1:]
            break
        elif cross1 > 0 and cross2 <= 0:
            cross_point1 = cross_point(c1, c2, p1, p2)
            points = points[i::-1] + points[:i:-1]
            break
    
    if cross_point1 == None:
        if flag > 0:
            cross_point1 = points[0]
            points = points[1:]
        else:
            return 0
    
    cut_area = 0
    for p1, p2 in zip(points, points[1:]):
        if cross(ref_vec, p1 - c1) * cross(ref_vec, p2 - c1) <= 0:
            cross_point2 = cross_point(c1, c2, p1, p2)
            cut_area += _area_of_triangle(cross_point1, cross_point2, p1)
            break
        else:
            cut_area += _area_of_triangle(cross_point1, p1, p2)
    return cut_area


import sys

file_input = sys.stdin

n = int(file_input.readline())

def string_to_complex(s):
    x, y = map(float, s.split())
    return x + y * 1j

G = [string_to_complex(file_input.readline()) for i in range(n)]


q = int(file_input.readline())

for line in file_input:
    p1x, p1y, p2x, p2y = map(int, line.split())
    p1 = p1x + p1y * 1j
    p2 = p2x + p2y * 1j
    ans = convex_cut(G.copy(), p1, p2)
    print("{:f}".format(ans))

Solution (Python):
import sys
readline = sys.stdin.readline
write = sys.stdout.write
def cross3(O, A, B):
    ox, oy = O; ax, ay = A; bx, by = B
    return (ax - ox) * (by - oy) - (bx - ox) * (ay - oy)
def cross_point(p0, p1, q0, q1):
    x0, y0 = p0; x1, y1 = p1
    x2, y2 = q0; x3, y3 = q1
    dx0 = x1 - x0; dy0 = y1 - y0
    dx1 = x3 - x2; dy1 = y3 - y2
    s = (y0-y2)*dx1 - (x0-x2)*dy1
    sm = dx0*dy1 - dy0*dx1
    if -EPS < sm < EPS:
        return None
    return x0 + s*dx0/sm, y0 + s*dy0/sm
EPS = 1e-9
def convex_cut(P, line):
    q0, q1 = line
    N = len(P)
    Q = []
    for i in range(N):
        p0 = P[i-1]; p1 = P[i]
        cv0 = cross3(q0, q1, p0)
        cv1 = cross3(q0, q1, p1)
        if cv0 * cv1 < EPS:
            v = cross_point(q0, q1, p0, p1)
            if v is not None:
                Q.append(v)
        if cv1 > -EPS:
            Q.append(p1)
    return Q
def polygon_area(P):
    s = 0
    N = len(P)
    for i in range(N):
        p0 = P[i-1]; p1 = P[i]
        s += p0[0]*p1[1] - p0[1]*p1[0]
    return abs(s) / 2
def solve():
    N = int(readline())
    P = [list(map(int, readline().split())) for i in range(N)]
    Q = int(readline())
    for i in range(Q):
        x0, y0, x1, y1 = map(int, readline().split())
        P0 = convex_cut(P, ((x0, y0), (x1, y1)))
        write("%.16f\n" % polygon_area(P0))
solve()

Solution (Python):
import cmath
import math
import os
import sys

if os.getenv("LOCAL"):
    sys.stdin = open("_in.txt", "r")

sys.setrecursionlimit(10 ** 9)
INF = float("inf")
IINF = 10 ** 18
MOD = 10 ** 9 + 7


PI = cmath.pi
TAU = cmath.pi * 2
EPS = 1e-10


class Point:
    """
    2次元空間上の点
    """

    
    CCW_COUNTER_CLOCKWISE = 1
    
    CCW_CLOCKWISE = -1
    
    CCW_ONLINE_BACK = 2
    
    CCW_ONLINE_FRONT = -2
    
    CCW_ON_SEGMENT = 0

    def __init__(self, c: complex):
        self.c = c

    @property
    def x(self):
        return self.c.real

    @property
    def y(self):
        return self.c.imag

    @staticmethod
    def from_rect(x: float, y: float):
        return Point(complex(x, y))

    @staticmethod
    def from_polar(r: float, phi: float):
        return Point(cmath.rect(r, phi))

    def __add__(self, p):
        """
        :param Point p:
        """
        return Point(self.c + p.c)

    def __iadd__(self, p):
        """
        :param Point p:
        """
        self.c += p.c
        return self

    def __sub__(self, p):
        """
        :param Point p:
        """
        return Point(self.c - p.c)

    def __isub__(self, p):
        """
        :param Point p:
        """
        self.c -= p.c
        return self

    def __mul__(self, f: float):
        return Point(self.c * f)

    def __imul__(self, f: float):
        self.c *= f
        return self

    def __truediv__(self, f: float):
        return Point(self.c / f)

    def __itruediv__(self, f: float):
        self.c /= f
        return self

    def __repr__(self):
        return "({}, {})".format(round(self.x, 10), round(self.y, 10))

    def __neg__(self):
        return Point(-self.c)

    def __eq__(self, p):
        return abs(self.c - p.c) < EPS

    def __abs__(self):
        return abs(self.c)

    @staticmethod
    def ccw(a, b, c):
        """
        線分 ab に対する c の位置
        線分上にあるか判定するだけなら on_segment とかのが速い
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C&lang=ja
        :param Point a:
        :param Point b:
        :param Point c:
        """
        b = b - a
        c = c - a
        det = b.det(c)
        if det > EPS:
            return Point.CCW_COUNTER_CLOCKWISE
        if det < -EPS:
            return Point.CCW_CLOCKWISE
        if b.dot(c) < -EPS:
            return Point.CCW_ONLINE_BACK
        if c.norm() - b.norm() > EPS:
            return Point.CCW_ONLINE_FRONT
        return Point.CCW_ON_SEGMENT

    def dot(self, p):
        """
        内積
        :param Point p:
        :rtype: float
        """
        return self.x * p.x + self.y * p.y

    def det(self, p):
        """
        外積
        :param Point p:
        :rtype: float
        """
        return self.x * p.y - self.y * p.x

    def dist(self, p):
        """
        距離
        :param Point p:
        :rtype: float
        """
        return abs(self.c - p.c)

    def norm(self):
        """
        原点からの距離
        :rtype: float
        """
        return abs(self.c)

    def phase(self):
        """
        原点からの角度
        :rtype: float
        """
        return cmath.phase(self.c)

    def angle(self, p, q):
        """
        p に向いてる状態から q まで反時計回りに回転するときの角度
        -pi <= ret <= pi
        :param Point p:
        :param Point q:
        :rtype: float
        """
        return (cmath.phase(q.c - self.c) - cmath.phase(p.c - self.c) + PI) % TAU - PI

    def area(self, p, q):
        """
        p, q となす三角形の面積
        :param Point p:
        :param Point q:
        :rtype: float
        """
        return abs((p - self).det(q - self) / 2)

    def projection_point(self, p, q, allow_outer=False):
        """
        線分 pq を通る直線上に垂線をおろしたときの足の座標
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_A&lang=ja
        :param Point p:
        :param Point q:
        :param allow_outer: 答えが線分の間になくても OK
        :rtype: Point|None
        """
        diff_q = q - p
        
        r = (self - p).dot(diff_q) / abs(diff_q)
        
        phase = diff_q.phase()

        ret = Point.from_polar(r, phase) + p
        if allow_outer or (p - ret).dot(q - ret) < EPS:
            return ret
        return None

    def reflection_point(self, p, q):
        """
        直線 pq を挟んで反対にある点
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_B&lang=ja
        :param Point p:
        :param Point q:
        :rtype: Point
        """
        
        r = abs(self - p)
        
        angle = p.angle(q, self)
        
        angle = (q - p).phase() - angle
        return Point.from_polar(r, angle) + p

    def on_segment(self, p, q, allow_side=True):
        """
        点が線分 pq の上に乗っているか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_1_C&lang=ja
        :param Point p:
        :param Point q:
        :param allow_side: 端っこでギリギリ触れているのを許容するか
        :rtype: bool
        """
        if not allow_side and (self == p or self == q):
            return False
        
        
        return abs((p - self).det(q - self)) < EPS and (p - self).dot(q - self) < EPS


class Line:
    """
    2次元空間上の直線
    """

    def __init__(self, a: float, b: float, c: float):
        """
        直線 ax + by + c = 0
        """
        self.a = a
        self.b = b
        self.c = c

    @staticmethod
    def from_gradient(grad: float, intercept: float):
        """
        直線 y = ax + b
        :param grad: 傾き
        :param intercept: 切片
        :return:
        """
        return Line(grad, -1, intercept)

    @staticmethod
    def from_segment(p1, p2):
        """
        :param Point p1:
        :param Point p2:
        """
        a = p2.y - p1.y
        b = p1.x - p2.x
        c = p2.y * (p2.x - p1.x) - p2.x * (p2.y - p1.y)
        return Line(a, b, c)

    @property
    def gradient(self):
        """
        傾き
        """
        return INF if self.b == 0 else -self.a / self.b

    @property
    def intercept(self):
        """
        切片
        """
        return INF if self.b == 0 else -self.c / self.b

    def is_parallel_to(self, l):
        """
        平行かどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A&lang=ja
        :param Line l:
        """
        
        return abs(Point.from_rect(self.a, self.b).det(Point.from_rect(l.a, l.b))) < EPS

    def is_orthogonal_to(self, l):
        """
        直行しているかどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A&lang=ja
        :param Line l:
        """
        
        return abs(Point.from_rect(self.a, self.b).dot(Point.from_rect(l.a, l.b))) < EPS

    def intersection_point(self, l):
        """
        交差する点
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_C&lang=ja
        :param Line l:
        :rtype: Point|None
        """
        a1, b1, c1 = self.a, self.b, self.c
        a2, b2, c2 = l.a, l.b, l.c
        det = a1 * b2 - a2 * b1
        if abs(det) < EPS:
            
            return None
        x = (b1 * c2 - b2 * c1) / det
        y = (a2 * c1 - a1 * c2) / det
        return Point.from_rect(x, y)

    def dist(self, p):
        """
        他の点との最短距離
        :param Point p:
        """
        raise NotImplementedError()

    def has_point(self, p):
        """
        p が直線上に乗っているかどうか
        :param Point p:
        """
        return abs(self.a * p.x + self.b * p.y + self.c) < EPS


class Segment:
    """
    2次元空間上の線分
    """

    def __init__(self, p1, p2):
        """
        :param Point p1:
        :param Point p2:
        """
        self.p1 = p1
        self.p2 = p2

    def norm(self):
        """
        線分の長さ
        """
        return abs(self.p1 - self.p2)

    def phase(self):
        """
        p1 を原点としたときの p2 の角度
        """
        return cmath.phase(self.p2 - self.p1)

    def is_parallel_to(self, s):
        """
        平行かどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A&lang=ja
        :param Segment s:
        :return:
        """
        
        return abs((self.p1 - self.p2).det(s.p1 - s.p2)) < EPS

    def is_orthogonal_to(self, s):
        """
        直行しているかどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_A&lang=ja
        :param Segment s:
        :return:
        """
        
        return abs((self.p1 - self.p2).dot(s.p1 - s.p2)) < EPS

    def intersects_with(self, s, allow_side=True):
        """
        交差するかどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_B&lang=ja
        :param Segment s:
        :param allow_side: 端っこでギリギリ触れているのを許容するか
        """
        if self.is_parallel_to(s):
            
            return (s.p1.on_segment(self.p1, self.p2, allow_side) or
                    s.p2.on_segment(self.p1, self.p2, allow_side) or
                    self.p1.on_segment(s.p1, s.p2, allow_side) or
                    self.p2.on_segment(s.p1, s.p2, allow_side))
        else:
            
            det_lower = EPS if allow_side else -EPS
            ok = True
            
            ok &= (self.p2 - self.p1).det(s.p1 - self.p1) * (self.p2 - self.p1).det(s.p2 - self.p1) < det_lower
            
            ok &= (s.p2 - s.p1).det(self.p1 - s.p1) * (s.p2 - s.p1).det(self.p2 - s.p1) < det_lower
            return ok

    def closest_point(self, p):
        """
        線分上の、p に最も近い点
        :param Point p:
        """
        
        d = (p - self.p1).dot(self.p2 - self.p1) / self.norm()
        
        if d < EPS:
            return self.p1
        
        if -EPS < d - self.norm():
            return self.p2
        
        return Point.from_polar(d, (self.p2 - self.p1).phase()) + self.p1

    def dist(self, p):
        """
        他の点との最短距離
        :param Point p:
        """
        return abs(p - self.closest_point(p))

    def dist_segment(self, s):
        """
        他の線分との最短距離
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_2_D&lang=ja
        :param Segment s:
        """
        if self.intersects_with(s):
            return 0.0
        return min(
            self.dist(s.p1),
            self.dist(s.p2),
            s.dist(self.p1),
            s.dist(self.p2),
        )

    def has_point(self, p, allow_side=True):
        """
        p が線分上に乗っているかどうか
        :param Point p:
        :param allow_side: 端っこでギリギリ触れているのを許容するか
        """
        return p.on_segment(self.p1, self.p2, allow_side=allow_side)


class Polygon:
    """
    2次元空間上の多角形
    """

    def __init__(self, points):
        """
        :param list of Point points:
        """
        self.points = points

    def iter2(self):
        """
        隣り合う2点を順に返すイテレータ
        :rtype: typing.Iterator[(Point, Point)]
        """
        return zip(self.points, self.points[1:] + self.points[:1])

    def iter3(self):
        """
        隣り合う3点を順に返すイテレータ
        :rtype: typing.Iterator[(Point, Point, Point)]
        """
        return zip(self.points,
                   self.points[1:] + self.points[:1],
                   self.points[2:] + self.points[:2])

    def area(self):
        """
        面積
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_A&lang=ja
        """
        
        dets = []
        for p, q in self.iter2():
            dets.append(p.det(q))
        return abs(math.fsum(dets)) / 2

    def is_convex(self, allow_straight=False, allow_collapsed=False):
        """
        凸多角形かどうか
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_B&lang=ja
        :param allow_straight: 3点がまっすぐ並んでるのを許容するかどうか
        :param allow_collapsed: 面積がゼロの場合を許容するか
        """
        ccw = []
        for a, b, c in self.iter3():
            ccw.append(Point.ccw(a, b, c))
        ccw = set(ccw)
        if len(ccw) == 1:
            if ccw == {Point.CCW_CLOCKWISE}:
                return True
            if ccw == {Point.CCW_COUNTER_CLOCKWISE}:
                return True
        if allow_straight and len(ccw) == 2:
            if ccw == {Point.CCW_ONLINE_FRONT, Point.CCW_CLOCKWISE}:
                return True
            if ccw == {Point.CCW_ONLINE_FRONT, Point.CCW_COUNTER_CLOCKWISE}:
                return True
        if allow_collapsed and len(ccw) == 3:
            return ccw == {Point.CCW_ONLINE_FRONT, Point.CCW_ONLINE_BACK, Point.CCW_ON_SEGMENT}
        return False

    def has_point_on_edge(self, p):
        """
        指定した点が辺上にあるか
        :param Point p:
        :rtype: bool
        """
        for a, b in self.iter2():
            if p.on_segment(a, b):
                return True
        return False

    def contains(self, p, allow_on_edge=True):
        """
        指定した点を含むか
        Winding Number Algorithm
        https://www.nttpc.co.jp/technology/number_algorithm.html
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_3_C&lang=ja
        :param Point p:
        :param bool allow_on_edge: 辺上の点を許容するか
        """
        angles = []
        for a, b in self.iter2():
            if p.on_segment(a, b):
                return allow_on_edge
            angles.append(p.angle(a, b))
        
        return abs(math.fsum(angles)) > EPS

    @staticmethod
    def convex_hull(points, allow_straight=False):
        """
        凸包。x が最も小さい点のうち y が最も小さい点から反時計回り。
        Graham Scan O(N log N)
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_A&lang=ja
        :param list of Point points:
        :param allow_straight: 3点がまっすぐ並んでるのを許容するかどうか
        :rtype: list of Point
        """
        points = points[:]
        points.sort(key=lambda p: (p.x, p.y))

        
        det_lower = -EPS if allow_straight else EPS

        sz = 0
        
        ret = [None] * (N * 2)
        for p in points:
            while sz > 1 and (ret[sz - 1] - ret[sz - 2]).det(p - ret[sz - 1]) < det_lower:
                sz -= 1
            ret[sz] = p
            sz += 1
        floor = sz
        for p in reversed(points[:-1]):
            while sz > floor and (ret[sz - 1] - ret[sz - 2]).det(p - ret[sz - 1]) < det_lower:
                sz -= 1
            ret[sz] = p
            sz += 1
        ret = ret[:sz - 1]

        if allow_straight and len(ret) > len(points):
            
            ret = points
        return ret

    @staticmethod
    def diameter(points):
        """
        直径
        凸包構築 O(N log N) + カリパー法 O(N)
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_B&lang=ja
        :param list of Point points:
        """
        
        points = Polygon.convex_hull(points, allow_straight=False)
        if len(points) == 1:
            return 0.0
        if len(points) == 2:
            return abs(points[0] - points[1])

        
        si = points.index(min(points, key=lambda p: (p.x, p.y)))
        sj = points.index(max(points, key=lambda p: (p.x, p.y)))
        n = len(points)

        ret = 0.0
        
        i, j = si, sj
        while i != sj or j != si:
            ret = max(ret, abs(points[i] - points[j]))
            ni = (i + 1) % n
            nj = (j + 1) % n
            
            if (points[ni] - points[i]).det(points[nj] - points[j]) > 0:
                j = nj
            else:
                i = ni
        return ret

    def convex_cut_by_line(self, line_p1, line_p2):
        """
        凸多角形を直線 line_p1-line_p2 でカットする。
        凸じゃないといけません
        Verify: http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=CGL_4_C&lang=ja
        :param line_p1:
        :param line_p2:
        :return: (line_p1-line_p2 の左側の多角形, line_p1-line_p2 の右側の多角形)
        :rtype: (Polygon|None, Polygon|None)
        """
        n = len(self.points)
        line = Line.from_segment(line_p1, line_p2)
        
        on_line_points = []
        for i, p in enumerate(self.points):
            if line.has_point(p):
                on_line_points.append(i)

        
        has_on_line_edge = False
        if len(on_line_points) >= 3:
            has_on_line_edge = True
        elif len(on_line_points) == 2:
            
            has_on_line_edge = abs(on_line_points[0] - on_line_points[1]) in [1, n - 1]
        
        if has_on_line_edge:
            for p in self.points:
                ccw = Point.ccw(line_p1, line_p2, p)
                if ccw == Point.CCW_COUNTER_CLOCKWISE:
                    return Polygon(self.points[:]), None
                if ccw == Point.CCW_CLOCKWISE:
                    return None, Polygon(self.points[:])

        ret_lefts = []
        ret_rights = []
        d = line_p2 - line_p1
        for p, q in self.iter2():
            det_p = d.det(p - line_p1)
            det_q = d.det(q - line_p1)
            if det_p > -EPS:
                ret_lefts.append(p)
            if det_p < EPS:
                ret_rights.append(p)
            
            if det_p * det_q < -EPS:
                intersection = line.intersection_point(Line.from_segment(p, q))
                ret_lefts.append(intersection)
                ret_rights.append(intersection)

        
        l = Polygon(ret_lefts) if len(ret_lefts) > 1 else None
        r = Polygon(ret_rights) if len(ret_rights) > 1 else None
        return l, r

N = int(sys.stdin.buffer.readline())
XY = [list(map(float, sys.stdin.buffer.readline().split())) for _ in range(N)]

points = []
for x, y in XY:
    points.append(Point(complex(x, y)))
polygon = Polygon(points)

Q = int(sys.stdin.buffer.readline())
POINTS = [list(map(int, sys.stdin.buffer.readline().split())) for _ in range(Q)]

for x1, y1, x2, y2 in POINTS:
    l, r = polygon.convex_cut_by_line(Point.from_rect(x1, y1), Point.from_rect(x2, y2))
    if l:
        print(l.area())
    else:
        print(0)

Solution (Python):


import array
from fractions import Fraction
import functools
import itertools
import math
import os
import sys


def main():
    N = read_int()
    P = [Vec(*read_ints()) for _ in range(N)]
    Q = read_int()
    for _ in range(Q):
        x1, y1, x2, y2 = read_ints()
        print(solve(N, P, Vec(x1, y1), Vec(x2, y2)))


def solve(N, P, A, B):
    b = B - A
    P = [p - A for p in P]

    ccw = 0
    cw = 0
    for p in P:
        c = b.cross(p)
        if c >= 0:
            ccw += 1
        if c <= 0:
            cw += 1

    if ccw == N:
        return float(poly_area(P))
    if cw == N:
        return 0

    cross_points = []

    for i in range(N):
        j = (i + 1) % N
        p = P[i]
        q = P[j]
        qp = q - p

        cross_qp_b = qp.cross(b)
        if cross_qp_b == 0:
            continue
        k = Fraction(b.cross(p), cross_qp_b)
        if 0 < k <= 1:
            t = Fraction(p.cross(qp), b.cross(qp))
            cross_points.append((t, i, k))

    cross_points.sort()
    _, i1, k1 = cross_points[0]
    _, i2, k2 = cross_points[1]

    x1 = P[i1] + k1 * (P[(i1 + 1) % N] - P[i1])
    x2 = P[i2] + k2 * (P[(i2 + 1) % N] - P[i2])
    Q = [x2]
    j = (i2 + 1) % N
    while j != i1:
        Q.append(P[j])
        j = (j + 1) % N
    Q.append(P[i1])
    Q.append(x1)

    return float(poly_area(Q))


def poly_area(P):
    N = len(P)
    a = 0
    for i in range(1, N - 1):
        a += Fraction((P[i + 1] - P[i]).cross(P[0] - P[i + 1]), 2)
    return a





class Vec(object):
    def __init__(self, x, y):
        self.x = x
        self.y = y
        super().__init__()

    def __add__(self, other):
        return Vec(self.x + other.x, self.y + other.y)

    def __sub__(self, other):
        return Vec(self.x - other.x, self.y - other.y)

    def __mul__(self, scalar):
        return Vec(self.x * scalar, self.y * scalar)

    def __rmul__(self, scalar):
        return Vec(self.x * scalar, self.y * scalar)

    def __truediv__(self, scalar):
        return Vec(self.x / scalar, self.y / scalar)

    def __iadd__(self, other):
        self.x += other.x
        self.y += other.y
        return self

    def __isub__(self, other):
        self.x -= other.x
        self.y -= other.y
        return self

    def __imul__(self, scalar):
        self.x *= scalar
        self.y *= scalar
        return self

    def __idiv__(self, scalar):
        self.x /= scalar
        self.y /= scalar
        return self

    def __neg__(self):
        return Vec(-self.x, -self.y)

    def __eq__(self, other):
        return self.x == other.x and self.y == other.y

    def __ne__(self, other):
        return not self.__eq__(other)

    def __hash__(self):
        return hash('Vec', self.x, self.y)

    def dot(self, other):
        return self.x * other.x + self.y * other.y

    def cross(self, other):
        return self.x * other.y - self.y * other.x

    def abs2(self):
        return self.x * self.x + self.y * self.y

    def __abs__(self):
        return math.sqrt(float(self.abs2()))

    def __repr__(self):
        return '({}, {})'.format(self.x, self.y)


DEBUG = 'DEBUG' in os.environ


def inp():
    return sys.stdin.readline().rstrip()


def read_int():
    return int(inp())


def read_ints():
    return [int(e) for e in inp().split()]


def dprint(*value, sep=' ', end='\n'):
    if DEBUG:
        print(*value, sep=sep, end=end)


if __name__ == '__main__':
    main()