zoukankan      html  css  js  c++  java
  • 简单多边形与圆交面积模板

      1 /*
      2    求多边形与圆相交的面积
      3 */
      4 
      5 #include <iostream>
      6 #include <cstdio>
      7 #include <cmath>
      8 #define max(x,y) ((x)>(y)?(x):(y))
      9 #define min(x,y) ((x)<(y)?(x):(y))
     10 #define PI acos(-1.0)
     11 #define EPS 1e-10
     12 using namespace std;
     13 
     14 inline int DB(double x) {
     15     if(x<-EPS) return -1;
     16     if(x>EPS) return 1;
     17     return 0;
     18 }
     19 
     20 
     21 struct point {
     22     double x,y;
     23 
     24     point() {}
     25     point(double _x,double _y):x(_x),y(_y) {}
     26 
     27     point operator-(point a) {
     28         return point(x-a.x,y-a.y);
     29     }
     30     point operator+(point a) {
     31         return point(x+a.x,y+a.y);
     32     }
     33 
     34     double operator*(point a) {
     35         return x*a.y-y*a.x;
     36     }
     37 
     38     point oppose() {
     39         return point(-x,-y);
     40     }
     41 
     42     double length() {
     43         return sqrt(x*x+y*y);
     44     }
     45 
     46     point adjust(double L) {
     47         L/=length();
     48         return point(x*L,y*L);
     49     }
     50 
     51     point vertical() {
     52         return point(-y,x);
     53     }
     54 
     55     double operator^(point a) {
     56         return x*a.x+y*a.y;
     57     }
     58 };
     59 
     60 
     61 struct segment {
     62     point a,b;
     63 
     64     segment() {}
     65     segment(point _a,point _b):a(_a),b(_b) {}
     66 
     67     point intersect(segment s) {
     68         double s1=(s.a-a)*(s.b-a);
     69         double s2=(s.b-b)*(s.a-b);
     70         double t=s1+s2;
     71         s1/=t;
     72         s2/=t;
     73         return point(a.x*s2+b.x*s1,a.y*s2+b.y*s1);
     74     }
     75     point vertical(point p) {
     76         point t=(b-a).vertical();
     77         return intersect(segment(p,p+t));
     78     }
     79     int isonsegment(point p) {
     80         return DB(min(a.x,b.x)-p.x)<=0&&
     81                DB(max(a.x,b.x)-p.x)>=0&&
     82                DB(min(a.y,b.y)-p.y)<=0&&
     83                DB(max(a.y,b.y)-p.y)>=0;
     84     }
     85 };
     86 
     87 struct circle {
     88     point p;
     89     double R;
     90 };
     91 
     92 circle C;
     93 point p[105];
     94 int n;
     95 
     96 
     97 double cross_area(point a,point b,circle C) {
     98     point p=C.p;
     99     double R=C.R;
    100     int sgn=DB((b-p)*(a-p));
    101     double La=(a-p).length(),Lb=(b-p).length();
    102     int ra=DB(La-R),rb=DB(Lb-R);
    103     double ang=acos(((b-p)^(a-p))/(La*Lb));
    104     segment t(a,b);
    105     point s;
    106     point h,u,temp;
    107     double ans,L,d,ang1;
    108 
    109     if(!DB(La)||!DB(Lb)||!sgn) ans=0;
    110     else if(ra<=0&&rb<=0) ans=fabs((b-p)*(a-p))/2;
    111     else if(ra>=0&&rb>=0) {
    112         h=t.vertical(p);
    113         L=(h-p).length();
    114         if(!t.isonsegment(h)||DB(L-R)>=0) ans=R*R*(ang/2);
    115         else {
    116             ans=R*R*(ang/2);
    117             ang1=acos(L/R);
    118             ans-=R*R*ang1;
    119             ans+=R*sin(ang1)*L;
    120         }
    121     } else {
    122         h=t.vertical(p);
    123         L=(h-p).length();
    124         s=b-a;
    125         d=sqrt(R*R-L*L);
    126         s=s.adjust(d);
    127         if(t.isonsegment(h+s)) u=h+s;
    128         else u=h+s.oppose();
    129         if(ra==1) temp=a,a=b,b=temp;
    130         ans=fabs((a-p)*(u-p))/2;
    131         ang1=acos(((u-p)^(b-p))/((u-p).length()*(b-p).length()));
    132         ans+=R*R*(ang1/2);
    133     }
    134     return ans*sgn;
    135 }
    136 
    137 double cal_cross(circle C,point p[],int n) {
    138     double ans=0;
    139     int i;
    140     p[n]=p[0];
    141     for(i=0; i<n; i++) ans+=cross_area(p[i],p[i+1],C);
    142     return fabs(ans);
    143 }
    144 
    145 double x,y,v,det,t,g,R;
    146 
    147 int input() {
    148     scanf("%lf%lf%lf%lf%lf%lf%lf",&x,&y,&v,&det,&t,&g,&R);
    149     return x||y||v||det||t||g||R;
    150 }
    151 
    152 
    153 int main() {
    154     //freopen("test.in","r",stdin);
    155     while(input()) {
    156         scanf("%d",&n);
    157         int i;
    158         for(i=0; i<n; i++) scanf("%lf%lf",&p[i].x,&p[i].y);
    159         det=det/180*PI;
    160         C.R=R;
    161         C.p.x=x+v*cos(det)*t;
    162         C.p.y=y+v*sin(det)*t-0.5*g*t*t;
    163         double area=cal_cross(C,p,n);
    164         printf("%.2lf
    ",area);
    165     }
    166     return 0;
    167 }
    View Code

    转自:http://blog.csdn.net/acm_baihuzi/article/details/48473725

    多边形面积求法:https://www.cnblogs.com/xiexinxinlove/p/3708147.html

  • 相关阅读:
    [转]网站架构收集 朱燚:
    SQLServer 2005 海量数据解决方案 分区表 朱燚:
    【轻松一下】女朋友的保健作用 朱燚:
    A tip when running javascript dynamically 朱燚:
    【组图】地震前线归来心中的震撼 朱燚:
    系统自动启动程序之十大藏身之所 朱燚:
    [轻松一下]90%的男人想作的事情 朱燚:
    JavaScript的9个陷阱及评点 朱燚:
    【转】c++中的sizeof 朱燚:
    PG数据库中相关操作
  • 原文地址:https://www.cnblogs.com/zmin/p/8329118.html
Copyright © 2011-2022 走看看