zoukankan      html  css  js  c++  java
  • UVA10969计算几何+交叉圆形成的圆弧长

      1 /*UVA 10969计算几何
      2 这道题和LA2572相似,但相对简单些。
      3 思路:求圆间的交点,顺序枚举出圆上的圆弧,中点判断是否被覆盖。
      4 */
      5 #include <stdio.h>
      6 #include <stdlib.h>
      7 #include <string.h>
      8 #include <math.h>
      9 #include <ctype.h>
     10 #include <string>
     11 #include <iostream>
     12 #include <sstream>
     13 #include <vector>
     14 #include <queue>
     15 #include <stack>
     16 #include <map>
     17 #include <list>
     18 #include <set>
     19 #include <algorithm>
     20 #define INF 0x3f3f3f3f
     21 #define eps 1e-7
     22 #define eps2 1e-3
     23 using namespace std;
     24 
     25 struct Point
     26 {
     27     double x,y;
     28     Point() {}
     29     Point(double xx,double yy)
     30     {
     31         x=xx;
     32         y=yy;
     33     }
     34 };
     35 struct Circle
     36 {
     37     Point O;
     38     double r;
     39     Circle() {}
     40     Circle(Point O1,double r1)
     41     {
     42         O=O1;
     43         r=r1;
     44     }
     45     Point point(double a)
     46     {
     47         return Point(O.x+cos(a)*r,O.y+sin(a)*r);
     48     }
     49 };
     50 typedef Point Vector;
     51 
     52 bool operator==(Point A,Point B)
     53 {
     54     if ((fabs(A.x-B.x)<1e-10) && (fabs(A.y-B.y)<1e-10)) return true;
     55     else return false;
     56 }
     57 Vector operator-(Point A,Point B)//表示A指向B
     58 {
     59     return Vector(A.x-B.x,A.y-B.y);
     60 }
     61 Vector operator*(Vector A,double k)
     62 {
     63     return Vector(A.x*k,A.y*k);
     64 }
     65 Vector operator+(Point A,Point B)//表示A指向B
     66 {
     67     return Vector(B.x+A.x,B.y+A.y);
     68 }
     69 double Dot(Vector A,Vector B)
     70 {
     71     return A.x*B.x+A.y*B.y;
     72 }
     73 double Length(Vector A)
     74 {
     75     return sqrt(Dot(A,A));
     76 }
     77 double Cross(Vector A,Vector B)
     78 {
     79     return A.x*B.y-A.y*B.x;
     80 }
     81 int dcmp(double x)
     82 {
     83     if(fabs(x)<1e-10) return 0;
     84     else if(x>0) return 1;
     85     else return -1;
     86 }
     87 double angle(Vector v)
     88 {
     89     return atan2(v.y,v.x);
     90 }
     91 double normal(double rad)
     92 {
     93     return rad-2*M_PI*floor(rad/(2*M_PI));
     94 }
     95 
     96 Point GetMid(double a,double b,double r,double x,double y)//圆上两点,获得中点的坐标
     97 {
     98     double arf=(b+a)/2;
     99     double xx=r*cos(arf)+x;
    100     double xy=r*sin(arf)+y;
    101     Point P=Point(xx,xy);
    102     return P;
    103 }
    104 bool PInCircle(Point P,Circle C)//判断点在圆内
    105 {
    106     double dis=Length(P-C.O);
    107     if (dis-C.r>1e-6) return false;
    108     else return true;
    109 }
    110 void getcircleinter(Point c1,double r1,Point c2,double r2,vector<double>& rad)
    111 {
    112     double d=Length(c1-c2);
    113     if(dcmp(d)==0) return;
    114     if(dcmp(r1+r2-d)<0) return;
    115     if(dcmp(fabs(r1-r2)-d)>0) return;
    116     double a=angle(c2-c1);
    117     double da=acos((r1*r1+d*d-r2*r2)/(2*r1*d));
    118     rad.push_back(normal(a+da));
    119     rad.push_back(normal(a-da));
    120 }
    121 
    122 int n;
    123 Circle CC[110];//
    124 vector<double> Arf[110];//圆心角
    125 
    126 int cas;
    127 int main()
    128 {
    129     cin>>cas;
    130     while(cas--)
    131     {
    132         double ans=0.0;
    133         cin>>n;
    134         for(int i=1; i<=n; i++)//读取信息
    135         {
    136             double x,y,r;
    137             cin>>r>>x>>y;
    138             CC[i]=Circle(Point(x,y),r);
    139         }
    140         for(int i=1; i<=n; i++) {Arf[i].clear();Arf[i].push_back(0);Arf[i].push_back(2*M_PI);}
    141 
    142         for(int i=1; i<=n; i++)//获得圆上的交点的角度
    143         for(int j=1; j<=n; j++)
    144             getcircleinter(CC[i].O,CC[i].r,CC[j].O,CC[j].r,Arf[i]);
    145 
    146         for(int i=1; i<=n; i++) //枚举n个圆上的圆弧
    147         {
    148             int k=Arf[i].size();
    149             sort(Arf[i].begin(),Arf[i].end());
    150 
    151             for(int j=0; j<k-1; j++) //枚举每条弧
    152             {
    153                 Point Mid=GetMid(Arf[i][j],Arf[i][j+1],CC[i].r,CC[i].O.x,CC[i].O.y);
    154 
    155                 bool ok=true;//表示这条圆弧可见
    156                 for(int l=i+1; l<=n; l++) //判断中点是否可见
    157                     if (PInCircle(Mid,CC[l])) ok=false;
    158 
    159                 if(ok) ans+=(Arf[i][j+1]-Arf[i][j])*CC[i].r;
    160             }
    161         }
    162 
    163         printf("%.3lf
    ",(ans));//放缩回来
    164     }
    165     return 0;
    166 }
  • 相关阅读:
    IDEA的Debug详解
    websocket学习(转载)
    Shiro授权及注解式开发
    Redis分布式缓存安装和使用
    JEESZ-SSO解决方案
    英语是学习Java编程的基础吗
    深入分析 ThreadLocal 内存泄漏问题
    这些JVM命令配置参数你知道吗?
    安全开发Java动态代理
    学java编程软件开发,非计算机专业是否能学
  • 原文地址:https://www.cnblogs.com/little-w/p/3570299.html
Copyright © 2011-2022 走看看