Problem p02302 (C++) — buggy submission, verdict: Runtime Error

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <utility>
#include <vector>

using namespace std;

static const double EPS = 1e-12;
static const double INF = 1e24;

using Point = complex<double>;
using Plane = vector<Point>;
using Polygon = vector<Point>;

bool operator<(const Point &a, const Point &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}

double cross_prod(const Point &a, const Point &b) { return imag(conj(a) * b); }

double dot_prod(const Point &a, const Point &b) { return real(conj(a) * b); }

enum {
  ONLINE_FRONT = -2,
  CLOCKWISE,
  ON_SEGMENT,
  COUNTER_CLOCKWISE,
  ONLINE_BACK,
};

int ccwise(Point a, Point b, Point c) {
  b -= a;
  c -= a;

  if (cross_prod(b, c) > 0) {
    return COUNTER_CLOCKWISE;
  } else if (cross_prod(b, c) < 0) {
    return CLOCKWISE;
  } else if (dot_prod(b, c) < 0) {
    return ONLINE_BACK;
  } else if (norm(b) < norm(c)) {
    return ONLINE_FRONT;
  } else {
    return ON_SEGMENT;
  }
}

template <class LineType> int ccwise(LineType l, Point p) {
  return ccwise(l.first, l.second, p);
}

struct Line : public pair<Point, Point> {
  Line() {}
  Line(const Point &a, const Point &b) {
    first = a;
    second = b;
  }
};

struct LineSeg : public pair<Point, Point> {
  LineSeg() {}
  LineSeg(const Point &a, const Point &b) {
    first = a;
    second = b;
  }
};

bool intersects(const Line &lhs, const Line &rhs) {
  if (abs(cross_prod(lhs.second - lhs.first, rhs.second - rhs.first)) > EPS)
    return true;

  return abs(cross_prod(lhs.second - lhs.first, rhs.first - lhs.first)) < EPS;
}

bool is_parallel(const Line &l, const Line &m) {
  return abs(cross_prod(l.second - l.first, m.second - m.first)) < EPS;
}

Point get_ipoint(const Line &l, const Line &m) {
  double x1 = l.first.real(), x2 = l.second.real();
  double x3 = m.first.real(), x4 = m.second.real();
  double y1 = l.first.imag(), y2 = l.second.imag();
  double y3 = m.first.imag(), y4 = m.second.imag();

  double x = (y4 - y3) * (x4 - x1) - (x4 - x3) * (y4 - y1);
  double d = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);

  return Point(x1, y1) + (x / d) * Point(x2 - x1, y2 - y1);
}

Polygon convex_cut(const Polygon &g, const Line &l) {
  Polygon h;
  for (size_t i = 0; i < g.size(); ++i) {
    Point A = g[i], B = g[(i + 1) % g.size()];
    if (ccwise(l, A) != CLOCKWISE)
      h.push_back(A);

    if (ccwise(l, A) * ccwise(l, B) < 0)
      if (!(intersects(Line(A, B), l) && is_parallel(Line(A, B), l)))
        h.push_back(get_ipoint(Line(A, B), l));
  }
  return h;
}

double get_area(const Polygon &g) {
  double res = 0.0;
  for (size_t i = 0; i < g.size(); ++i)
    res += cross_prod(g[i], g[(i + 1) % g.size()]);

  return res / 2.0;
}

int main() {
  size_t n;
  scanf("%zu", &n);

  Polygon g(n);
  for (size_t i = 0; i < n; ++i) {
    double x, y;
    scanf("%lf %lf", &x, &y);
    g[i] = Point(x, y);
  }

  size_t q;
  scanf("%zu", &q);

  for (size_t i = 0; i < q; ++i) {
    double x, y;
    scanf("%lf %lf", &x, &y);
    Point p1(x, y);

    scanf("%lf %lf", &x, &y);
    Point p2(x, y);
    Line l(p1, p2);

    Polygon h = convex_cut(g, l);
    printf("%.12f\\n", get_area(h));
  }

  return 0;
}

Error: WA

Fixed submission:

#include <algorithm>
#include <cmath>
#include <complex>
#include <cstdio>
#include <functional>
#include <utility>
#include <vector>

using namespace std;

static const double EPS = 1e-12;
static const double INF = 1e24;

using Point = complex<double>;
using Plane = vector<Point>;
using Polygon = vector<Point>;

bool operator<(const Point &a, const Point &b) {
  return real(a) != real(b) ? real(a) < real(b) : imag(a) < imag(b);
}

double cross_prod(const Point &a, const Point &b) { return imag(conj(a) * b); }

double dot_prod(const Point &a, const Point &b) { return real(conj(a) * b); }

enum {
  ONLINE_FRONT = -2,
  CLOCKWISE,
  ON_SEGMENT,
  COUNTER_CLOCKWISE,
  ONLINE_BACK,
};

int ccwise(Point a, Point b, Point c) {
  b -= a;
  c -= a;

  if (cross_prod(b, c) > 0) {
    return COUNTER_CLOCKWISE;
  } else if (cross_prod(b, c) < 0) {
    return CLOCKWISE;
  } else if (dot_prod(b, c) < 0) {
    return ONLINE_BACK;
  } else if (norm(b) < norm(c)) {
    return ONLINE_FRONT;
  } else {
    return ON_SEGMENT;
  }
}

template <class LineType> int ccwise(LineType l, Point p) {
  return ccwise(l.first, l.second, p);
}

struct Line : public pair<Point, Point> {
  Line() {}
  Line(const Point &a, const Point &b) {
    first = a;
    second = b;
  }
};

struct LineSeg : public pair<Point, Point> {
  LineSeg() {}
  LineSeg(const Point &a, const Point &b) {
    first = a;
    second = b;
  }
};

bool intersects(const Line &lhs, const Line &rhs) {
  if (abs(cross_prod(lhs.second - lhs.first, rhs.second - rhs.first)) > EPS)
    return true;

  return abs(cross_prod(lhs.second - lhs.first, rhs.first - lhs.first)) < EPS;
}

Point get_ipoint(const Line &l, const Line &m) {
  double x1 = l.first.real(), x2 = l.second.real();
  double x3 = m.first.real(), x4 = m.second.real();
  double y1 = l.first.imag(), y2 = l.second.imag();
  double y3 = m.first.imag(), y4 = m.second.imag();

  double x = (y4 - y3) * (x4 - x1) - (x4 - x3) * (y4 - y1);
  double d = (y4 - y3) * (x2 - x1) - (x4 - x3) * (y2 - y1);

  return Point(x1, y1) + (x / d) * Point(x2 - x1, y2 - y1);
}

Polygon convex_cut(const Polygon &g, const Line &l) {
  Polygon h;
  for (size_t i = 0; i < g.size(); ++i) {
    Point A = g[i], B = g[(i + 1) % g.size()];
    if (ccwise(l, A) != CLOCKWISE)
      h.push_back(A);

    if (ccwise(l, A) * ccwise(l, B) < 0)
      if (!intersects(Line(A, B), l))
        h.push_back(get_ipoint(Line(A, B), l));
  }
  return h;
}

double get_area(const Polygon &g) {
  fprintf(stderr, "%zd\\n", g.size());
  double res = 0.0;
  for (size_t i = 0; i < g.size(); ++i)
    fprintf(stderr, "(%f, %f)\\n", g[i].real(), g[i].imag()),
        res += cross_prod(g[i], g[(i + 1) % g.size()]);

  return res / 2.0;
}

int main() {
  size_t n;
  scanf("%zu", &n);

  Polygon g(n);
  for (size_t i = 0; i < n; ++i) {
    double x, y;
    scanf("%lf %lf", &x, &y);
    g[i] = Point(x, y);
  }

  size_t q;
  scanf("%zu", &q);

  for (size_t i = 0; i < q; ++i) {
    double x, y;
    scanf("%lf %lf", &x, &y);
    Point p1(x, y);

    scanf("%lf %lf", &x, &y);
    Point p2(x, y);
    Line l(p1, p2);

    Polygon h = convex_cut(g, l);
    printf("%.12f\\n", get_area(h));
  }

  return 0;
}