题目描述

题目计算日出后指定时刻太阳圆盘可见部分的面积比例。这是一个涉及一个行星和一个恒星的二体问题。

假设行星为完美球体,半径为 395039503950 英里。恒星(太阳)位于距行星中心 92,900,00092,900,00092,900,000 英里处,被视为一个圆盘,其平面垂直于行星中心与太阳圆盘中心的连线。太阳圆盘半径为 432,000432,000432,000 英里。行星均匀自转,每 242424 小时转一圈。太阳始终位于行星赤道的正上方。

时间从日出时刻(太阳第一缕光线到达赤道上给定参考点)开始测量,以秒为单位。对于每个输入的时间值,计算此时太阳圆盘照亮该参考点的面积比例。

输入格式

输入包含多个浮点数,每行一个,表示以秒为单位的时间值。时间值在 000600600600 之间(含)。输入以文件结束符(EOF\texttt{EOF}EOF)终止。

输出格式

对于每个输入的时间值,输出一行一个浮点数,表示太阳圆盘可见部分的面积比例。如果比例为零,输出值应在 [−0.001,0.001][-0.001, 0.001][0.001,0.001] 区间内。非零答案的误差需在 0.1%0.1\%0.1% 以内。

样例

输入

0.0
600.0

输出

0.000000
1.000000

题目分析

本题的核心是计算太阳圆盘被行星遮挡部分的面积比例。由于太阳的角直径远大于行星的视直径,日出时太阳并非完全被遮挡,而是逐渐露出。

几何模型

设:

  • 行星半径 Re=3950R_e = 3950Re=3950 英里
  • 太阳半径 Rs=432000R_s = 432000Rs=432000 英里
  • 行星中心到太阳中心距离 D=92900000D = 92900000D=92900000 英里
  • 地球自转周期 T=24T = 24T=24 小时 =86400= 86400=86400

日出时刻,太阳圆盘的上边缘恰好与行星表面在参考点处相切。此时,从行星中心到参考点与到太阳圆盘上边缘的视线之间的夹角为 α\alphaα

角度 α\alphaα 的计算

在日出时刻,由几何关系可得:
L=D2+Rs2−Re2 L = \sqrt{D^2 + R_s^2 - R_e^2} L=D2+Rs2Re2
该距离表示从行星中心到太阳圆盘上边缘切点的距离。

太阳圆盘对行星中心的半张角为 θs=arctan⁡(Rs/D)\theta_s = \arctan(R_s / D)θs=arctan(Rs/D),行星对太阳圆盘上边缘的切线半角为 θt=arctan⁡(L/Re)\theta_t = \arctan(L / R_e)θt=arctan(L/Re)。因此:
α=θs+θt=arctan⁡(RsD)+arctan⁡(LRe) \alpha = \theta_s + \theta_t = \arctan\left(\frac{R_s}{D}\right) + \arctan\left(\frac{L}{R_e}\right) α=θs+θt=arctan(DRs)+arctan(ReL)

时间与角度的关系

行星自转角速度为:
ω=2π86400 弧度/秒 \omega = \frac{2\pi}{86400} \text{ 弧度/秒} ω=864002π 弧度/
设从日出时刻起经过 ttt 秒,行星自转过的角度为 ωt\omega tωt。此时,参考点相对于太阳中心的方向角为:
β=α−ωt \beta = \alpha - \omega t β=αωt

太阳圆盘可见部分

hhh 为行星遮挡边缘与太阳圆盘中心的垂直距离。若行星表面在参考点处的切线与太阳中心方向的夹角为 β\betaβ,则有:
h=Re−Dcos⁡β/sin⁡β h = R_e - D \cos \beta / \sin \beta h=ReDcosβ/sinβ

但更简洁的推导基于圆被直线切割的面积公式。设太阳圆盘被一条距离圆心为 ∣h∣|h|h 的直线切割,则切割后较小部分的面积比例为:
f(∣h∣)=1πarccos⁡(∣h∣Rs)−∣h∣πRs2Rs2−h2 f(|h|) = \frac{1}{\pi} \arccos\left(\frac{|h|}{R_s}\right) - \frac{|h|}{\pi R_s^2} \sqrt{R_s^2 - h^2} f(h)=π1arccos(Rsh)πRs2hRs2h2

  • h≥Rsh \ge R_shRs,太阳完全被遮挡,比例为 000
  • h≤−Rsh \le -R_shRs,太阳完全可见,比例为 111
  • −Rs<h<0-R_s < h < 0Rs<h<0,可见部分为圆盘的较大部分,比例 =1−f(∣h∣)= 1 - f(|h|)=1f(h)
  • 0≤h<Rs0 \le h < R_s0h<Rs,可见部分为圆盘的较小部分,比例 =f(h)= f(h)=f(h)

公式推导说明

由于 D≫Re,RsD \gg R_e, R_sDRe,Rs,太阳的视张角很小,但本题要求精确计算,因此不能使用小角度近似。上述公式基于严格的几何关系。

复杂度分析

每组输入仅需常数次浮点运算,时间复杂度 O(1)O(1)O(1)

代码实现

// Sunrise
// UVa ID: 415
// Verdict: Accepted
// Submission Date: 2016-08-05
// UVa Run Time: 0.000s
//
// 版权所有(C)2016,邱秋。metaphysis # yeah dot net

#include <bits/stdc++.h>

using namespace std;

const double pi = 2 * acos(0);

int main(int argc, char *argv[])
{
    cin.tie(0); cout.tie(0); ios::sync_with_stdio(false);

    double Sr = 432000, Er = 3950, D = 92900000;
    
    double L = sqrt(D * D + Sr * Sr - Er * Er);
    double alpha = atan(Sr / D) + atan(L / Er);
    
    double seconds;
    while (cin >> seconds)
    {
        double h, beta = alpha - 2.0 * pi * seconds / 3600.0 / 24.0;

        h = (Er - D * cos(beta)) / sin(beta);
        
        if (h >= Sr)
        {
            cout << "0.000000\n";
            continue;
        }
        
        if (h <= -Sr)
        {
            cout << "1.000000\n";
            continue;
        }
        
        double percentage = acos(fabs(h) / Sr) / pi - fabs(h) * sqrt(Sr * Sr - h * h) / (pi * Sr * Sr);
        if (h < 0)
            percentage = 1.0 - percentage;
        cout << fixed << setprecision(6) << percentage << '\n';
    }
    
    return 0;
}
Logo

AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。

更多推荐