程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> poj 1375 Intervals 圓的切線

poj 1375 Intervals 圓的切線

編輯:C++入門知識

題意:有一光源,被若干個圓摭住了,求地面上陰影
 
題解:利用向量旋轉求出切線與圓的兩個交點,根據兩點成線得出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.2cto.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

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved