zoukankan      html  css  js  c++  java
  • poj2986A Triangle and a Circle&&poj3675Telescope(三角形剖分)

    链接

    2986是3675的简化版,只有一个三角形。

    这题主要在于求剖分后三角形与圆的相交面积,需要分情况讨论。

    具体可以看此博客 http://hi.baidu.com/billdu/item/703ad4e15d819db52f140b0b

    在分析第3、4两种情况时,我是用角度来进行判断的,如果<obc||<ocb大于90度就为他所说的第四种情况,不然就是第三种情况。

    还有对于sig的解释貌似网上都没写,可能都觉得太简单了。。。自己手画了一下,大体是这个样子的

    红色标记那块三角形是需要减掉对于当前多边形,可以看出以最下角进行剖分三角形时,cross(b,c)算的那块小三角形的确是负的,所以需要判断一下当前的面积是要加上的还是要减掉的。

    讨论的东西比较多,细节比较多,WA了好多遍,对着数据查了好久终于过了。。

    附上一些数据

      1 #include <iostream>
      2 #include<cstdio>
      3 #include<cstring>
      4 #include<algorithm>
      5 #include<stdlib.h>
      6 #include<vector>
      7 #include<cmath>
      8 #include<queue>
      9 #include<set>
     10 using namespace std;
     11 #define N 100
     12 #define LL long long
     13 #define INF 0xfffffff
     14 const double eps = 1e-8;
     15 const double pi = acos(-1.0);
     16 const double inf = ~0u>>2;
     17 struct point
     18 {
     19     double x,y;
     20     point(double x=0,double y=0):x(x),y(y) {}
     21 } p[N];
     22 struct tri
     23 {
     24     point a,b,c;
     25 } tr[N];
     26 typedef point pointt;
     27 point operator -(point a,point b)
     28 {
     29     return point(a.x-b.x,a.y-b.y);
     30 }
     31 point operator *(point a,double r)
     32 {
     33     return point(a.x*r,a.y*r);
     34 }
     35 point operator +(point a,point b)
     36 {
     37     return point(a.x+b.x,a.y+b.y);
     38 }
     39 struct line
     40 {
     41     point u,v;
     42     point ppoint(double t)
     43     {
     44         return point(u+v*t);
     45     }
     46 };
     47 struct circle
     48 {
     49     point c;
     50     double r;
     51     circle(point c,double r):c(c),r(r) {}
     52     point ppoint(double a)
     53     {
     54         return point(c.x+cos(a)*r,c.y+sin(a)*r);
     55     }
     56 };
     57 double r;
     58 point ip;
     59 double dcmp(double x)
     60 {
     61     if(fabs(x)<eps) return 0;
     62     return x<0?-1:1;
     63 }
     64 double dis(point a)
     65 {
     66     return sqrt(a.x*a.x+a.y*a.y);
     67 }
     68 double dot(point a,point b)
     69 {
     70     return a.x*b.x+a.y*b.y;
     71 }
     72 double cross(point a,point b)
     73 {
     74     return a.x*b.y-a.y*b.x;
     75 }
     76 double area(point a,point b,point c)
     77 {
     78     return fabs(cross(a-c,b-c))/2;
     79 }
     80 
     81 int getlinecircle(line ll,circle cc,point &p1,point &p2)
     82 {
     83     double a = ll.v.x,b = ll.u.x-cc.c.x,c = ll.v.y,d = ll.u.y-cc.c.y;
     84     double e = a*a+c*c,f = 2*(a*b+c*d),g = b*b+d*d-cc.r*cc.r;
     85     double delta = f*f-4*e*g;
     86     double t1,t2;
     87     if(dcmp(delta)<0)return 0;//ÏàÀë
     88     if(dcmp(delta)==0)
     89     {
     90         t1 = t2 = -f/(2*e);//cout<<t1<<" -"<<e<<" "<<f<<endl;
     91         p1 = ll.ppoint(t1);
     92         return 1;//ÏàÇÐ
     93     }
     94     //Ïཻ
     95     t1 = (-f-sqrt(delta))/(2*e);
     96     p1 = ll.ppoint(t1);
     97     t2 = (-f+sqrt(delta))/(2*e);
     98     p2 = ll.ppoint(t2);
     99     // cout<<p1.x<<" "<<p1.y<<" "<<p2.x<<" "<<p2.y<<endl;
    100     return 2;
    101 }
    102 double mul(point a,point b,point c)
    103 {
    104     return cross(b-a,c-a);
    105 }
    106 bool cmp(point a,point b)
    107 {
    108     if(dcmp(mul(ip,a,b))==0)
    109         return dis(a-ip)<dis(b-ip);
    110     else
    111         return dcmp(mul(ip,a,b))>0;
    112 }
    113 double distancetoline(point p,point a,point b)
    114 {
    115     point v1 = a-b,v2 = p-b;
    116     return fabs(cross(v1,v2))/dis(v1);
    117 }
    118 int dot_online_in(point p,point l1,point l2)
    119 {
    120     return !dcmp(mul(p,l1,l2))&&(l1.x-p.x)*(l2.x-p.x)<eps&&(l1.y-p.y)*(l2.y-p.y)<eps;
    121 }
    122 double angle(point a,point b)
    123 {
    124     return acos(dot(a,b)/dis(a)/dis(b));
    125 }
    126 double cal(tri tr)
    127 {
    128     circle cp=circle(point(0,0),r);
    129     int sig = dcmp(cross(tr.b,tr.c));
    130     if(sig==0) return 0;
    131     double d1 = dis(tr.a-tr.b),d2 = dis(tr.a-tr.c);
    132     if(dcmp(d1-r)<=0&&dcmp(d2-r)<=0)
    133     {
    134         double s = sig*area(tr.a,tr.b,tr.c);
    135         return s;
    136     }
    137     double dline = distancetoline(cp.c,tr.b,tr.c);
    138     if(dcmp(d1-r)>=0&&dcmp(d2-r)>=0&&dcmp(dline-r)>=0)
    139     {
    140         return sig*angle(tr.b,tr.c)*r*r/2.0;
    141     }
    142     double ag = angle(tr.c-tr.b,tr.a-tr.b),bg = angle(tr.b-tr.c,tr.a-tr.c);
    143     point p1,p2;
    144     line l1;
    145     l1.u = tr.b,l1.v = tr.c-tr.b;
    146     getlinecircle(l1,cp,p1,p2);
    147 
    148     if(dcmp(d1-r)>=0&&dcmp(d2-r)>=0&&dcmp(dline-r)<0&&(dcmp(ag-pi/2)>=0||dcmp(bg-pi/2)>=0))
    149     {
    150 
    151         double s = sig*angle(tr.b,tr.c)*r*r/2;
    152         return s;
    153     }
    154     if(dcmp(d1-r)>=0&&dcmp(d2-r)>=0&&dcmp(dline-r)<0)
    155     {
    156         double s = (angle(tr.b,tr.c)-angle(p1,p2))*r*r/2.0+area(tr.a,p1,p2);
    157         return sig*s;
    158     }
    159 
    160     p1 = dot_online_in(p1,tr.b,tr.c)?p1:p2;
    161     if(dcmp(d1-r)<0)
    162     {
    163         return sig*(angle(tr.c,p1)*r*r/2+area(tr.a,p1,tr.b));
    164     }
    165     else
    166     {
    167         return sig*(angle(p1,tr.b)*r*r/2+area(tr.a,p1,tr.c));
    168     }
    169 }
    170 int dots_inline(point p1,point p2,point p3)
    171 {
    172     return !dcmp(mul(p1,p2,p3));
    173 }
    174 int main()
    175 {
    176     int i,n;
    177     while(scanf("%lf",&r)!=EOF)
    178     {
    179         scanf("%d",&n);
    180         for(i = 0; i < n ; i++)
    181         {
    182             scanf("%lf%lf",&p[i].x,&p[i].y);
    183         }
    184         p[n] = p[0];
    185         double ans = 0;
    186         for(i = 0 ; i < n ; i++)
    187         {
    188             if(dots_inline(ip,p[i],p[i+1])) continue;
    189             tr[i].a = point(0,0);
    190             tr[i].b = p[i];
    191             tr[i].c = p[i+1];
    192             ans+=cal(tr[i]);
    193         }
    194         printf("%.2f
    ",fabs(ans)+eps);
    195     }
    196     return 0;
    197 }
    View Code


    589.00 191.00 -554.00 710.00 748.00 774.00 -888.00 -588.00 902.00

    201.00 -847.00 -365.00 886.00 -557.00 -609.00 272.00 -345.00 189.00

    -358.00 981.00 269.00 511.00 158.00 -304.00 468.00 463.00 834.00

    969.00 514.00 -445.00 460.00 -177.00 774.00 -34.00 -125.00 162.00

    -467.00 413.00 -714.00 -986.00 362.00 666.00 813.00 271.00 264.00

    -497.00 908.00 -414.00 631.00 -220.00 868.00 166.00 -258.00 306.00

    -107.00 -743.00 -952.00 322.00 -273.00 -214.00 -14.00 466.00 758.00

    511.00 -416.00 -934.00 -745.00 -335.00 -132.00 -482.00 391.00 626.00

    928.00 821.00 -293.00 -853.00 -488.00 -312.00 -27.00 94.00 361.00

    -979.00 -280.00 791.00 -943.00 -300.00 -278.00 -821.00 684.00 365.00

    -700.00 955.00 -315.00 154.00 -103.00 -606.00 404.00 -792.00 940.00

    607.00 783.00 597.00 944.00 -672.00 -323.00 343.00 -799.00 526.00

    815.00 -390.00 -291.00 37.00 422.00 687.00 672.00 613.00 848.00

    -988.00 363.00 -529.00 660.00 -597.00 143.00 502.00 459.00 522.00

    -206.00 484.00 109.00 -111.00 424.00 650.00 330.00 -545.00 480.00

    94.00 -638.00 -59.00 -9.00 -400.00 -702.00 0.00 267.00 741.00

    -859.00 522.00 109.00 -640.00 383.00 712.00 489.00 -663.00 635.00

    808.00 -31.00 471.00 172.00 -374.00 21.00 120.00 -860.00 474.00

    -539.00 -887.00 498.00 844.00 -453.00 -213.00 -479.00 -9.00 315.00

    答案

    Case 1
    0.00
    Case 2
    0.00
    Case 3
    274955.27
    Case 4
    0.00
    Case 5
    0.00
    Case 6
    0.00
    Case 7
    25157.17
    Case 8
    9943.87
    Case 9
    181113.99
    Case 10
    0.00
    Case 11
    11846.16
    Case 12
    0.00
    Case 13
    404668.37
    Case 14
    0.00
    Case 15
    0.00
    Case 16
    74663.53
    Case 17
    80015.79
    Case 18
    0.00
    Case 19
    57316.85
    Case 20
    0.00

  • 相关阅读:
    WCF客户端链接服务超时客户端close
    C# byte数组常用扩展浅析(转)
    代码生成相关工具及技术
    已处理证书链,但是在不受信任提供程序信任的根证书中终止。
    清理SQL Server数据库日志的两种方法
    开源框架项目列表
    SQL Server数据库文件恢复技术
    VS2008找不到导出模板
    jquery 学习笔记(二)
    方法的参数的默认值设置
  • 原文地址:https://www.cnblogs.com/shangyu/p/3904597.html
Copyright © 2011-2022 走看看