CP Notebook

← all snippets

CirclePolygonIntersection

Returns the area of the intersection of a circle with a ccw polygon.

Time: O(n) 19 lines Tested on GNYR 2019 Gerrymandering, stress-tested

Needs: "../../content/geometry/Point.h"

content/geometry/CirclePolygonIntersection.h — chilli, Takanori MAEHARA, source: https://github.com/spaghetti-source/algorithm/blob/master/geometry/_geom.cc#L744

typedef Point<double> P;
#define arg(p, q) atan2(p.cross(q), p.dot(q))
double circlePoly(P c, double r, vector<P> ps) {
	auto tri = [&](P p, P q) {
		auto r2 = r * r / 2;
		P d = q - p;
		auto a = d.dot(p)/d.dist2(), b = (p.dist2()-r*r)/d.dist2();
		auto det = a * a - b;
		if (det <= 0) return arg(p, q) * r2;
		auto s = max(0., -a-sqrt(det)), t = min(1., -a+sqrt(det));
		if (t < 0 || 1 <= s) return arg(p, q) * r2;
		P u = p + d * s, v = q + d * (t-1);
		return arg(p,u) * r2 + u.cross(v)/2 + arg(v,q) * r2;
	};
	auto sum = 0.0;
	rep(i,0,sz(ps))
		sum += tri(ps[i] - c, ps[(i + 1) % sz(ps)] - c);
	return sum;
}