2015年10月6日 星期二

[UVA] 1026 - The Solar System

題意:
克普勒定律,
1.每一個行星都沿各自的橢圓軌道環繞太陽,而太陽則處在橢圓的一個焦點中。
2.在相等時間內,太陽和運動著的行星的連線所掃過的面積都是相等的。
3.(t1/t2)平方=(a1/a2)三方。
參考維基百科

現在有兩顆星球,
給你第一顆星球的半長軸(a1),半短軸(b1),還有週期(t1),
再給你另一顆星球的半長軸(a2)和半短軸(b2),
在給一個時間 t,
問第二顆星球從起始點(a2,0),
經過 t 時間後,移動後的座標。


--------------------------------------------------

我的作法:
幾個數學知識可以先背起來,
。π = 2*acos(0)
。橢圓面積 = π *半短軸*半長軸
。中心到焦點的距離 c =開根號(半長軸平方 - 半短軸平方)
。橢圓扇形面積 = π *半短軸*半長軸/2要先算出第二顆星球的週期 t2,
可以利用克普勒第三定律求出,
有週期後,可以算出行星經過 t 時間後走的面積(繞著焦點),
如下圖,










藍色區塊 = 經過 t 時間後行星走的面積
               = 橢圓面積(πab) * t/t2
               = 橢圓扇形面積(θab/2) - 紅色三角形面積(cbsinθ)


利用二分法,找出角度θ,
所求座標(x,y)=( 半長軸*cosθ , 半短軸*sinθ)。

--------------------------------------------------

/* 20151007
 * hanting
 * UVa 1026 - The Solar System
 * C++
 */
#include <iostream>
#include <iomanip> //setprecision
#include <cmath> //acos,sqrt,sin,cos
using namespace std;
#define pi 2*acos(0)
double a1,b1,t1,a2,b2,t2,t;
int main()
{
    int caseN=1;
    while(cin>>a1>>b1>>t1>>a2>>b2>>t and a1+b1+t1)
    {
        t2=sqrt(t1*t1*a2*a2*a2/a1/a1/a1);//  t1平方/t2平方 = a1三方/a2三方
        t=fmod(t,t2);
        double ellipseArea = pi*a2*b2;//橢圓面積
        double runArea=ellipseArea*(t/t2);//t時間行星行走的面積
        double low=0,up=2*pi;
        double mid=(low+up)/2;//theta

        double c2=sqrt(a2*a2-b2*b2);//中心到焦點的距離
        while(up-low>1e-7)
        {
            double area=(mid*a2*b2)/2. - (c2*b2*sin(mid))/2.;
            //令theta為角度,介於0到2pi
            //扇形面積 = theta*a*b/2  , 三角形面積 = 底(c2)*高(b2*sin(theta))/2
            if(area<runArea)
            {
                low=mid;
                mid=(low+up)/2;
            }
            else
            {
                up=mid;
                mid=(low+up)/2;
            }
        }
        cout<<"Solar System "<<caseN++<<": "<<fixed<<setprecision(3)<<a2*cos(low)<<" "<<b2*sin(low)<<endl;
    }
    return 0;
}

沒有留言:

張貼留言