• POJ 1375 圆的切线


    题意:

    求从光源透过圆形的阴影的线段,并排序输出。

    题解:

    求圆的切线,利用勾股定理和坐标旋转即可。

    处理出所有与地平线的交点,标号正负1,排序,然后扫一遍就好了~

    View Code
      1 #include <iostream>
      2 #include <cstring>
      3 #include <cstdio>
      4 #include <cstdlib>
      5 #include <algorithm>
      6 #include <cmath>
      7 
      8 #define N 2222
      9 #define BUG system("pause")
     10 
     11 using namespace std;
     12 
     13 struct PO
     14 {
     15     double x,y,r;
     16     int fg;
     17     void prt() {printf("%lf    %lf\n",x,y);}
     18 }p[N],s;
     19 
     20 struct FP
     21 {
     22     double x;
     23     int fg;
     24 }fp[N];
     25 
     26 struct LI
     27 {
     28     PO a,b;
     29     int fg;
     30 }li[N],flr;
     31 
     32 int n,cnt,gs;
     33 double lt;
     34 
     35 inline PO operator +(PO a,PO b)
     36 {
     37     PO as;
     38     as.x=a.x+b.x; as.y=a.y+b.y;
     39     return as;
     40 }
     41 
     42 inline PO operator -(PO a,PO b)
     43 {
     44     PO as;
     45     as.x=a.x-b.x; as.y=a.y-b.y;
     46     return as;
     47 }
     48 
     49 inline PO operator /(PO a,double k)
     50 {
     51     a.x/=k; a.y/=k;
     52     return a;
     53 }
     54 
     55 inline PO operator *(PO a,double k)
     56 {
     57     a.x*=k; a.y*=k;
     58     return a;
     59 }
     60 
     61 inline void read()
     62 {
     63     scanf("%lf%lf",&s.x,&s.y);
     64     for(int i=1;i<=n;i++) scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r);
     65 }
     66 
     67 inline PO rotate(PO a,double sss,double ccc)
     68 {
     69     PO ans;
     70     ans.x=a.x*ccc-a.y*sss;
     71     ans.y=a.x*sss+a.y*ccc;
     72     return ans;
     73 }
     74 
     75 inline double getdis(PO &a,PO &b)
     76 {
     77     return sqrt((a.x-b.x)*(a.x-b.x)+(a.y-b.y)*(a.y-b.y));
     78 }
     79 
     80 inline void getli(PO &s,PO &c,PO &a,PO &b)
     81 {
     82     double sc=getdis(s,c);
     83     double sp=sqrt(sc*sc-c.r*c.r);
     84     double sss=c.r/sc;
     85     double ccc=sp/sc;
     86     PO len=(c-s)*sp/sc;
     87     a=s+rotate(len,sss,ccc);
     88     b=s+rotate(len,-sss,ccc);
     89 }
     90 
     91 inline double cross(PO &a,PO &b,PO &c)
     92 {
     93     return (b.x-a.x)*(c.y-a.y)-(c.x-a.x)*(b.y-a.y);
     94 }
     95 
     96 inline PO getpoint(PO &a,PO &b,PO &c,PO &d)
     97 {
     98     double k1=cross(a,d,c),k2=cross(b,c,d);
     99     PO res=b-a;
    100     res=a+res*k1/(k1+k2);
    101     return res;
    102 }
    103 
    104 inline bool cmp(const FP &a,const FP &b)
    105 {
    106     return a.x<b.x;
    107 }
    108 
    109 inline void go()
    110 {
    111     cnt=gs=0;PO a,b;
    112     for(int i=1;i<=n;i++)
    113     {
    114         getli(s,p[i],a,b);
    115         if(a.x>b.x) swap(a,b);
    116         li[++cnt].a=s; li[cnt].b=a; li[cnt].fg=1;
    117         li[++cnt].a=s; li[cnt].b=b; li[cnt].fg=-1;
    118     }
    119     flr.a.x=flr.a.y=flr.b.y=0; flr.b.x=1;
    120     for(int i=1;i<=cnt;i++)
    121     {
    122         PO tmp=getpoint(flr.a,flr.b,li[i].a,li[i].b);
    123         fp[i].x=tmp.x;
    124         fp[i].fg=li[i].fg;
    125     }
    126     sort(fp+1,fp+1+cnt,cmp);
    127     for(int i=1;i<=cnt;i++)
    128     {
    129         gs+=fp[i].fg;
    130         if(gs==1&&fp[i].fg==1) lt=fp[i].x;//注意缺一不可! 
    131         else if(gs==0) printf("%.2lf %.2lf\n",lt,fp[i].x);
    132     }
    133     puts("");
    134 }
    135 
    136 int main()
    137 {
    138     while(scanf("%d",&n),n) read(),go();
    139     return 0;
    140 }
  • 相关阅读:
    PPT幻灯片放映不显示备注,只让备注显示在自己屏幕上
    Available Date 相关
    App Store常用推广方法
    iPhone应用提交流程:如何将App程序发布到App Store-转
    [转]关于适配iphone5,Invalid Launch Image的退信
    NSLog 不打印中文 - 解决
    Xcode GDB 调试
    xcode找不到真机设备 - 转
    使用静态库的一些问题 -all_load
    [深入浅出iOS库]之图形库CorePlot
  • 原文地址:https://www.cnblogs.com/proverbs/p/2937943.html
Copyright © 2020-2023  润新知