题目描述
平面上有一块栅栏围成的区域。
栅栏的高度为h,且在平面上的投影是一个封闭的多边形(不存在多边形的边交叉的情况
),它的N个顶点可以由笛卡尔坐标系中的坐标(Xi,Yi)表示。
在原点O(0,0)处有一个台灯。台灯可能在栅栏内或栅栏外,但不会刚好在栅栏的边上。
如下图所示(细线表示没有被台灯照亮的边):
栅栏是完全黑的,即,它不会反射光线,散射光线,或让光线通过。
研究和实验发现,能被光线照到的任意一个点的光强度有如下公式:
I0=k/r
其中k是一个常量,r是该点与台灯在平面上的距离。
栅栏上一段宽度为dl、高度为h的无穷窄的板(在平面投影上为一个点A)的亮度为:
dI=I0*|cosa|*dl*h
其中I0是这段板(即点A)的光强度,a是点A到台灯的方向(AO)与点A所在的栅栏的法向量
所形成的角度。
你需要写一个程序来计算栅栏上的总亮度。
解题思路:
把dl=rdă代入就能求得I=ă*k*h,其中ă是每条边对原点夹的角,比如对边AB,它的ă就是
<AOB。那么下面的问题就转化为整个图形对原点所夹的角的最大值,这里可能有个问题
,比如对于一个螺旋型的Fence,原点在中心,那么可能求出的夹角大于2*PI,由于
Fence是不能透光、反射、散射的,因此最大值只能为2*PI。又由于Fence不能经过原点
,因此每条边的夹角在 -PI~PI之间,这里求整个图形对原点所夹的角用了一个很强的
方法,可以保证无论从哪个点开始算,只要是按顺序,它一定能求得最大的角度(我领
悟了半天啊),而且min一定要初始化为0而不是2*PI等大于0的数,考虑下原点在图形内
部的情况就知道了~~至于正确性,可以自已画个图就能理解了~
http://zh.wikipedia.org/zh/Atan2
#include <stdio.h>
#include <math.h>
#define PI 3.1415926 //3.1415926535897932
struct point
{
double x,y;
}a[110];
double Getangle(point a,point b)
{
double x=atan2(a.x,a.y);
double y=atan2(b.x,b.y);
if(x-y>PI) y+=2*PI;
if(y-x>PI) x+=2*PI;
return x-y;
}
int main()
{
int n,i;
double k,h,temp,min,max,sum;
scanf("%lf%lf%d",&k,&h,&n);
for(i=0;i<n;i++)
scanf("%lf%lf",&a[i].x,&a[i].y);
a[n].x=a[0].x;
a[n].y=a[0].y;
sum=0;
max=min=0;
for(i=0;i<n;i++)
{
temp=Getangle(a[i],a[i+1]);
sum+=temp;
if(sum<min)min=sum;
if(sum>max)max=sum;
if((max-min)>=2*PI)
{
max=min+2*PI;
break;
}
}
printf("%.2lf\n",(max-min)*k*h);
return 0;
}