#include <iostream>#include<cstring>#include<cstdio>#include<cmath>#include<algorithm>using namespacestd;structpoint{Doublex; Doubley;} p[1001], px[10001];intN;Doubleeps=1e-8;intCMP (Point A, point B) {if(ABS (a.x-b.x) <EPS)returna.y<b.y; returna.x<b.x;}DoubleDist (Point A,point B)//Ask for distance{ returnsqrt ((a.x-b.x) * (a.x-b.x) + (A.Y-B.Y) * (a.y-b.y));}Doubledirection (Point pi,point pj,point PK) {return(pk.x-pi.x) * (PJ.Y-PI.Y)-(pj.x-pi.x) * (pk.y-pi.y);}BOOLOn_segment (Point pi,point pj,point PK)//Judging point PK time on line pi, PJ{ if(Direction (pi, pj, pk) = =0) { if(Pk.x>=min (pi.x,pj.x) &&pk.x<=max (pi.x,pj.x) &&pk.y>=min (PI.Y,PJ.Y) &&pk.y<=Max (PI.Y,PJ.Y))return true; } return false;}BOOLSegments_intersect (Point p1,point p2,point p3,point P4)//determine if segments intersect{ Doubled1=direction (P3,P4,P1); DoubleD2=direction (P3,P4,P2); Doubled3=direction (P1,P2,P3); Doubled4=direction (P1,P2,P4); if(d1*d2<0&&d3*d4<0) return true; Else if(d1==0&&on_segment (P3,P4,P1))return true; Else if(d2==0&&on_segment (P3,P4,P2))return true; Else if(d3==0&&on_segment (P1,P2,P3))return true; Else if(d4==0&&on_segment (P1,P2,P4))return true; return false;} Point intersection (Point A1, Point A2, point B1, point B2)//calculate the intersection of segments{point ret=A1; DoubleT = ((a1.x-b1.x) * (B1.Y-B2.Y)-(A1.Y-B1.Y) * (b1.x-b2.x))/((a1.x-a2.x) * (B1.Y-B2.Y)-(A1.Y-A2.Y) * (b1.x-b2.x)); Ret.x+ = (a2.x-a1.x) *T; Ret.y+ = (A2.Y-A1.Y) *T; returnret;}intInpolygon (Point a)//determines whether a point is inside a polygon{ inti; Point B,c,d; B.y=a.y; b.x=1E15;//define Ray intflag=0; intCount=0; for(i=0; i<n; i++) {C=P[i]; D= P[i +1]; if(On_segment (C,d,a))//the point is on one side of the polygon return 1; if(ABS (C.Y-D.Y) <EPS)Continue; if(On_segment (A,B,C))//and Vertex intersection, if the Y value is larger, take { if(c.y>d.y) Count++; } Else if(On_segment (A,B,D))//and Vertex intersection, if the Y value is larger, take { if(d.y>c.y) Count++; } Else if(Segments_intersect (A,B,C,D))//intersect with edgescount++; } returncount%2;//when the number of intersections of L and Polygon C is odd, p is within the polygon and is even if p is outside the polygon. }BOOLIntersect (Point s,point e,point a,point b) {returnDirection (e,a,s) *direction (e,b,s) <=0;}//where the line intersectsDoubleCalculate (Point S,point e) {inti,j,k=0; Doublesum; Point A,b,temp; for(i=0; i<n; i++)//traverse all points compute intersections{a=P[i]; b=p[i+1]; if(ABS (direction (e,a,s)) <eps&&abs (direction (e,b,s)) <EPS) {Px[k++]=A; Px[k++]=b; } Else if(Intersect (S,E,A,B))//Two line intersection{px[k++]=intersection (S,E,A,B);//Two line intersection } } if(k==0) return 0.0; Sort (px,px+K,CMP);//sort, since the secant is a straight line, so the intersection must be linearly distributedpx[k]=px[0]; Sum=0; for(i=0; i<k-1; i++) {a=Px[i]; b=px[i+1]; Temp.x= (a.x+b.x)/2.0; TEMP.Y= (A.Y+B.Y)/2.0; if(Inpolygon (temp))//if the midpoint of the two point is outside the polygon, the line is outsidesum+=Dist (A, b); } returnsum;}intMain () {intq,i,j; Doublesum; Point S,e; while(~SCANF ("%d",&N)) {if(n==0) Break; for(i=0; i<n; i++) scanf ("%LF%LF",&p[i].x,&p[i].y); P[n]=p[0]; scanf ("%LF%LF%LF%LF",&s.x,&s.y,&e.x,&e.y); Sum=Calculate (s,e); printf ("%.3f\n", sum); } return 0;}
Computer College College Student Program Design Competition (1002) Polygon