#include typedef float real; // could be double. #define C const #define bigReal 1.E38 // FLT_MAX, DBL_MAX if double above #include typedef struct{real x; real y;} point; real inter(int na, point a[na], int nb, point b[nb]){ typedef struct{point min; point max;} box; typedef long long int hp; typedef struct{long int x; long int y;} ipoint; typedef struct{long int mn; long int mx;} rng; typedef struct{ipoint ip; rng rx; rng ry; short int in;} vertex; vertex ipa[na+1], ipb[nb+1]; box B = {{bigReal, bigReal}, {-bigReal, -bigReal}}; double ascale; void range(int c, point x[c]){ while(c--){ void bd(real * X, real y){*X = *Xy ? *X:y;} bd(&B.min.x, x[c].x); bu(&B.max.x, x[c].x); bd(&B.min.y, x[c].y); bu(&B.max.y, x[c].y);}} if(na < 3 || nb < 3) return 0; range(na, a); range(nb, b); { const real gamut = 500000000., mid = gamut/2.; real rngx = B.max.x - B.min.x, sclx = gamut/rngx, rngy = B.max.y - B.min.y, scly = gamut/rngy; {void fit(int cx, point x[cx], vertex * ix, int fudge){ {int c=cx; while(c--){ ix[c].ip.x = (long)((x[c].x - B.min.x)*sclx - mid)&~7|fudge|c&1; ix[c].ip.y = (long)((x[c].y - B.min.y)*scly - mid)&~7|fudge; }} ix[0].ip.y += cx&1; ix[cx] = ix[0]; {int c=cx; while(c--) { ix[c].rx = ix[c].ip.x < ix[c+1].ip.x ? (rng){ix[c].ip.x,ix[c+1].ip.x}:(rng){ix[c+1].ip.x,ix[c].ip.x}; ix[c].ry = ix[c].ip.y < ix[c+1].ip.y ? (rng){ix[c].ip.y,ix[c+1].ip.y}:(rng){ix[c+1].ip.y,ix[c].ip.y}; ix[c].in=0;}}} fit(na, a, ipa, 0); fit(nb, b, ipb, 2);} ascale = sclx*scly;} { hp area(ipoint a, ipoint p, ipoint q) {return (hp)p.x*q.y - (hp)p.y*q.x + (hp)a.x*(p.y - q.y) + (hp)a.y*(q.x - p.x);} hp s = 0; int j, k; void cntrib(ipoint f, ipoint t, short w) {s += (hp)w*(t.x-f.x)*(t.y+f.y)/2;} int ovl(rng p, rng q){return p.mn < q.mx && q.mn < p.mx;} for(j=0; jip.x + r1*(b->ip.x-a->ip.x), a->ip.y + r1*(b->ip.y-a->ip.y)}, b->ip, 1); cntrib(d->ip, (ipoint){ c->ip.x + r2*(d->ip.x - c->ip.x), c->ip.y + r2*(d->ip.y - c->ip.y)}, 1); ++a->in; --c->in;} if(o) cross(&ipa[j], &ipa[j+1], &ipb[k], &ipb[k+1], a1, a2, a3, a4); else cross(&ipb[k], &ipb[k+1], &ipa[j], &ipa[j+1], a3, a4, a1, a2); }}}} {void inness(int cP, vertex P[cP], int cQ, vertex Q[cQ]){ int s=0, c=cQ; ipoint p = P[0].ip; while(c--)if(Q[c].rx.mn < p.x && p.x < Q[c].rx.mx) {int sgn = 0 < area(p, Q[c].ip, Q[c+1].ip); s += sgn != Q[c].ip.x < Q[c+1].ip.x ? 0 : (sgn?-1:1); } {int j; for(j=0; j