poj1375Intervals(点到圆的切线)

链接

貌似这样的叫解析几何

重点如何求得过光源到圆的切线与地板的交点x坐标,可以通过角度及距离来算,如图,

根据距离和半径可以求得角度a、b、r,自然也可以求得d1,d2.

至于方向问题,在求r得时候 可以使r = asin((p.x-c.x)/d) p为源点,c为圆心 ,d为两点距离。

若在反方向,自然r为负角 ,并不影响最后的结果。

排序后,统计区间就可以了。

 1 #include <iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<stdlib.h>
 6 #include<vector>
 7 #include<cmath>
 8 #include<queue>
 9 #include<set>
10 using namespace std;
11 #define N 505
12 #define LL long long
13 #define INF 0xfffffff
14 const double eps = 1e-8;
15 const double pi = acos(-1.0);
16 const double inf = ~0u>>2;
17 struct point
18 {
19     double x,y;
20     double r;
21     point(double x=0,double y=0):x(x),y(y){}
22 }p[N];
23 struct node
24 {
25     double l,r;
26 }li[N],ans[N];
27 typedef point pointt;
28 pointt operator -(point a,point b)
29 {
30     return point(a.x-b.x,a.y-b.y);
31 }
32 double dis(point a)
33 {
34     return sqrt(a.x*a.x+a.y*a.y);
35 }
36 node cal(point a,point b)
37 {
38     double ang1,ang2,ang3,ang4;
39     double d = dis(a-b);
40     ang1 = asin(a.r/d);
41     ang2 = asin((b.x-a.x)/d);
42     ang3 = ang1+ang2;
43     ang4 = ang2-ang1;
44     //cout<<ang1<<" "<<ang2<<" "<<ang3<<" "<<ang4<<endl;
45     node ll;
46     double l = b.x-b.y*tan(ang3);
47     double r = b.x-b.y*tan(ang4);
48     ll.l = min(l,r);
49     ll.r = max(l,r);
50     return ll;
51 }
52 bool cmp(node a,node b)
53 {
54     return a.l<b.l;
55 }
56 int main()
57 {
58     int n,i;
59     point pp;
60     while(scanf("%d",&n)&&n)
61     {
62         scanf("%lf%lf",&pp.x,&pp.y);
63         for(i = 1; i <= n; i++)
64         scanf("%lf%lf%lf",&p[i].x,&p[i].y,&p[i].r);
65         for(i = 1; i <= n; i++)
66         {
67             li[i] = cal(p[i],pp);
68         }
69         sort(li+1,li+n+1,cmp);
70         int g = 1;
71         ans[g].l = li[1].l;
72         double te = li[1].r;
73         for(i = 2 ; i <= n; i++)
74         {
75             if(li[i].l>te)
76             {
77                 ans[g].r = te;
78                 ans[++g].l = li[i].l;
79             }
80             te = max(te,li[i].r);
81         }
82         ans[g].r = te;
83         for(i = 1; i <= g; i++)
84         printf("%.2f %.2f\n",ans[i].l,ans[i].r);
85         puts("");
86     }
87     return 0;
88 }

poj1375Intervals(点到圆的切线),布布扣,bubuko.com

时间: 2024-10-12 08:10:24

poj1375Intervals(点到圆的切线)的相关文章

poj 1375 Intervals(解析几何 过圆外一点求与圆的切线)

题目大意:给出一个光源,给出一些圆,求投影区间. 如图,先可以求出角a,通过半径与PQ距离,而角b也可以求出.那么就可以求出两条切线与Y轴的夹角,分别为a+b,b-a. 之后利用角度求出各投影线段的左右顶点,排序判断即可. #include<iostream> #include<algorithm> #include<cmath> #include<cstdio> using namespace std; struct Point { double x,y;

POJ 1375 Intervals 解析几何 求圆的切线

题目大意:给出一个点,再给出都处于这个点之下的一些圆,求这个点光源照到这些圆上之后所得到的阴影的并集. 思路:求出每一个圆关于那个点的切线,每一个圆可以处理出来两个切线,这两个切线在x轴上交点的中间部分就是要求的阴影.最后将所有的阴影部分取并输出. 关于求切线,我是利用方向向量解方程做的.应该有更简洁的方法吧.. CODE: #include <cmath> #include <cstdio> #include <cstring> #include <iostre

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

原题 每组数据给出一些圆(障碍物)的圆心和半径,一个点和一条线段,求站在这个点,能开到的线段的部分的左端点和右端点.没有则输出"No View" 相当于求过该点的圆的两条切线,切线外即为可见的地方. 借鉴于这个blog:http://blog.csdn.net/acm_cxlove/article/details/7896110 只要求出两条直线和竖直的夹角,然后通过向量旋转即可得到交点横坐标. #include<cstdio> #include<algorithm&

计算几何-圆 模板 训练指南267

#include #include #include #include #include #include #include #include #include #include #define MM(a) memset(a,0,sizeof(a)) typedef long long ll; typedef unsigned long long ULL; const double eps = 1e-10; const int inf = 0x3f3f3f3f; using namespace

【计算几何】【分类讨论】Gym - 101173C - Convex Contour

注意等边三角形的上顶点是卡不到边界上的. 于是整个凸包分成三部分:左边的连续的三角形.中间的.右边的连续的三角形. 套个计算几何板子求个三角形顶点到圆的切线.三角形顶点到正方形左上角距离啥的就行了,分类比较多. #include<cstdio> #include<cmath> using namespace std; const double PI=acos(-1.0); int n; char a[25]; struct Point{ double x,y; double len

HDU 4667 Building Fence(求凸包的周长)

A - Building Fence Time Limit:1000MS     Memory Limit:65535KB     64bit IO Format:%I64d & %I64u Submit Status Description Long long ago, there is a famous farmer named John. He owns a big farm and many cows. There are two kinds of cows on his farm, o

简单几何(直线与线段相交) POJ 1039 Pipe

题目传送门 题意:一根管道,有光源从入口发射,问光源最远到达的地方. 分析:黑书上的例题,解法是枚举任意的一个上顶点和一个下顶点(优化后),组成直线,如果直线与所有竖直线段有交点,则表示能穿过管道. /************************************************ * Author :Running_Time * Created Time :2015/10/31 星期六 10:28:12 * File Name :POJ_1039.cpp ***********

简单几何(线段相交) POJ 1410 Intersection

题目传送门 题意:一个矩形和一条线段,问是否有相交 分析:考虑各种情况.坑点:给出的矩形的两个端点是无序的,还有线段完全在矩形内也算相交 /************************************************ * Author :Running_Time * Created Time :2015/10/27 星期二 13:17:49 * File Name :POJ_1410.cpp ******************************************

二维平面计算几何模板

1 //author Eterna 2 #include<iostream> 3 #include<algorithm> 4 #include<cstdio> 5 #include<vector> 6 #include<cstring> 7 #include<string> 8 #include<cmath> 9 #include<cstdlib> 10 #include<utility> 11 #