当前位置:编程学习 > C/C++ >>

poj 1375 Intervals 圆的切线

题意:有一光源,被若干个圆摭住了,求地面上阴影
 
题解:利用向量旋转求出切线与圆的两个交点,根据两点成线得出aX+bY+c=0的直线,令Y=0时,求出地面的坐标,再合并有连接的阴影。
 
//代码如下:
 
 
[cpp] 
#include<iostream> 
#include<cstdio> 
#include<algorithm> 
#include<math.h> 
#define eps 1e-8 
 
//using namespace std; 
const int maxn=1000; 
struct point{double x,y;}; 
struct circle {point cen;double r;}cir[maxn]; 
struct Node{double s,e;}node[maxn]; 
 
double f[maxn][2]; 
point st; 
double distance(point p1,point p2) 

    return sqrt((p1.x-p2.x)*(p1.x-p2.x)+(p1.y-p2.y)*(p1.y-p2.y)); 

void getline(point p1,point p2,double &a,double &b,double &c) 

    a=p2.y-p1.y; 
    b=p1.x-p2.x; 
    c=p2.x*p1.y-p1.x*p2.y; 

 
void cirinser(circle c,point &inser1,point &inser2)//圆与切线交点(保证st在圆外) 
 

    point dir; 
    double dis=distance(c.cen,st); 
    double temp=sqrt(dis*dis-c.r*c.r); 
    double sina=temp/dis; 
    double cosa=c.r/dis; 
    dir.x=(st.x-c.cen.x)/dis*c.r; 
    dir.y=(st.y-c.cen.y)/dis*c.r; 
    inser1.x=c.cen.x+(dir.x*cosa-dir.y*sina); 
    inser1.y=c.cen.y+(dir.x*sina+dir.y*cosa); 
     
    inser2.x=c.cen.x+(dir.x*cosa+dir.y*sina); 
    inser2.y=c.cen.y+(-dir.x*sina+dir.y*cosa); 

bool zero(double x){return x>0? x<eps:x>-eps;} 
bool cmp( Node a, Node b) 

    if(zero(a.s-b.s))return a.e-b.e<0; 
    else return a.s-b.s<0; 

int main() 

    int n; 
    while(scanf("%d",&n),n) 
    { 
        scanf("%lf%lf",&st.x,&st.y); 
        int i; 
        point inser1,inser2; 
        double a,b,c; 
        for(i=0;i<n;i++) 
        { 
            scanf("%lf%lf%lf",&cir[i].cen.x,&cir[i].cen.y,&cir[i].r); 
            cirinser(cir[i],inser1,inser2); 
            getline(st,inser1,a,b,c); 
            node[i].s=-c/a; 
            getline(st,inser2,a,b,c); 
            node[i].e=-c/a; 
            if(node[i].s-node[i].e>0)std::swap(node[i].s,node[i].e); 
        } 
        std::sort(node,node+n,cmp); 
         
        f[0][0]=node[0].s; 
        f[0][1]=node[0].e; 
        int cnt=0; www.zzzyk.com
        for(i=1;i<n;i++) 
        { 
            if(node[i].s-f[cnt][1]<eps &&node[i].e-f[cnt][1]>0)f[cnt][1]=node[i].e; 
            else if(node[i].s-f[cnt][1]>0) 
            { 
                f[++cnt][0]=node[i].s; 
                f[cnt][1]=node[i].e; 
            } 
        } 
        for(i=0;i<=cnt;i++) 
            printf("%.2lf %.2lf\n",f[i][0],f[i][1]); 
        printf("\n"); 
    } 
    return 0; 


作者:ssslpk
补充:软件开发 , C++ ,
CopyRight © 2022 站长资源库 编程知识问答 zzzyk.com All Rights Reserved
部分文章来自网络,