AOJ 1292 Top Spinning
問題
線分と円弧からなる図形が与えられる。
この図形の重心の座標、および重心が図形の内部にあるかどうかを求めよ。
制約条件
図形をつくる線分と円弧の数の和は100以下
誤差は10^-3以下でなければならない
方針
誤差がかなりゆるいので、円弧を折れ線で近似して良い。
1000分割くらいしたら問題なく通った。
多角形の重心は公式を使う。(ライブラリ化しておくべきだった)
ソースコード
P center(const G &p){ int n = p.size(); double a = 0; double cx = 0, cy = 0; rep(i, n){ a += p[i].real() * p[(i + 1) % n].imag() - p[(i + 1) % n].real() * p[i].imag(); cx += (p[i].real() + p[(i + 1) % n].real()) * (p[i].real() * p[(i + 1) % n].imag() - p[(i + 1) % n].real() * p[i].imag()); cy += (p[i].imag() + p[(i + 1) % n].imag()) * (p[i].real() * p[(i + 1) % n].imag() - p[(i + 1) % n].real() * p[i].imag()); } a *= 0.5; cx /= 6 * a; cy /= 6 * a; return P(cx, cy); } const int SPLIT = 1000; int main(){ string cmd; while(cin >> cmd, cmd != "end"){ G poly; double x, y, r; cin >> x >> y; poly.pb(P(x, y)); while(cin >> cmd, cmd != "close"){ if(cmd == "line"){ cin >> x >> y; poly.pb(P(x, y)); } else if(cmd == "arc"){ cin >> x >> y >> r; P cur = poly.back(), nxt(x, y); P dir = nxt - cur, m = (cur + nxt) * 0.5; double d = abs(dir); dir *= sqrt(r * r - d * d / 4) / d; if(r < 0) dir *= P(0, 1); else dir *= P(0, -1); m += dir; double a = arg(cur - m), b = arg(nxt - m); if(a < 0) a += 2 * PI; if(b < 0) b += 2 * PI; if(r < 0 && a > b) b += 2 * PI; if(r > 0 && a < b) a += 2 * PI; for(int i = 1; i <= SPLIT; i++){ double t = (i * b + (SPLIT - i) * a) / SPLIT; poly.pb(m + abs(r) * P(cos(t), sin(t))); } } else assert(0); } P g = center(poly); printf("%.9f %.9f ", g.real(), g.imag()); if(contains(poly, g) != OUT) cout << "+" << endl; else cout << "-" << endl; } return 0; }