码迷,mamicode.com
首页 > 其他好文 > 详细

[poj] 1375 Interval || 圆的切线&和直线的交点

时间:2017-12-22 23:57:48      阅读:290      评论:0      收藏:0      [点我收藏+]

标签:通过   problem   sdn   const   algo   point   圆的切线   inter   logs   

原题

每组数据给出一些圆(障碍物)的圆心和半径,一个点和一条线段,求站在这个点,能开到的线段的部分的左端点和右端点。没有则输出“No View”


相当于求过该点的圆的两条切线,切线外即为可见的地方。
借鉴于这个blog:http://blog.csdn.net/acm_cxlove/article/details/7896110
只要求出两条直线和竖直的夹角,然后通过向量旋转即可得到交点横坐标。

#include<cstdio>
#include<algorithm>
#include<cmath>
using namespace std;
int n;
double r,d;
struct point
{
    double x,y;
    point() {}
    point(double _x,double _y) : x(_x),y(_y) {}
    point operator - (const point &b) const
    {
        return point(b.x-x,b.y-y);
    }
    double dis()
    {
        return sqrt(x*x+y*y);
    }
}p,q;
struct edge
{
    double l,r;
    bool operator < (const edge &b) const
    {
        if (l==b.l) return r<b.r;
        return l<b.l;
    }
}line[510];

int main()
{
    while (~scanf("%d",&n) && n)
    {
    scanf("%lf%lf",&p.x,&p.y);
    for (int i=0;i<n;i++)
    {
        scanf("%lf%lf%lf",&q.x,&q.y,&r);
        d=(p-q).dis();
        double a=asin(r/d),b=asin((p.x-q.x)/d);
        double ang1=a+b,ang2=b-a;
        line[i].l=p.x-p.y*tan(ang1);
        line[i].r=p.x-p.y*tan(ang2);
    }
    sort(line,line+n);
    double L=line[0].l,R=line[0].r;
    for (int i=1;i<n;i++)
    {
        if (line[i].l>R)
        {
        printf("%.2f %.2f\n",L,R);
        L=line[i].l;
        R=line[i].r;
        }
        else R=max(line[i].r,R);
    }
    printf("%.2f %.2f\n\n",L,R);
    }
    return 0;
}

[poj] 1375 Interval || 圆的切线&和直线的交点

标签:通过   problem   sdn   const   algo   point   圆的切线   inter   logs   

原文地址:http://www.cnblogs.com/mrha/p/8087884.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!