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

Posted Mrha

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了[poj] 1375 Interval || 圆的切线&和直线的交点相关的知识,希望对你有一定的参考价值。

原题

每组数据给出一些圆(障碍物)的圆心和半径,一个点和一条线段,求站在这个点,能开到的线段的部分的左端点和右端点。没有则输出“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 || 圆的切线&和直线的交点的主要内容,如果未能解决你的问题,请参考以下文章

POJ 1375 Intervals | 解析几何

poj3819 Coverage (求直线与圆的交占直线的百分比 )

POJ - 1981 :Circle and Points (圆的扫描线) hihocoder1508

[poj] 3384 Feng Shui || 半平面交

POJ 1328(模拟&贪心_A题)解题报告

POJ 2932 Coneology计算最外层圆个数