Module: When::Ephemeris::ChineseTrueLunation::MethodJ

Includes:
JujiMethods
Defined in:
lib/when_exe/region/chinese.rb

Overview

授時暦の定朔の計算

Instance Method Summary collapse

Methods included from JujiMethods

#_perihelion_, #_winter_solstice_, #_year_length_

Instance Method Details

#_anomaly_a(mean_lunation, year, solar_unit, mean_motion) ⇒ Object

経朔 - 定朔 ( A 方式 - 階差)



562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
# File 'lib/when_exe/region/chinese.rb', line 562

def _anomaly_a(mean_lunation, year, solar_unit, mean_motion)

  # 遅速差(月の中心差) / (日 / 10000_0000)
  gen   = ((mean_lunation + @anomalistic_month_shift) % @anomalistic_month_length) / @lunar_unit
  minus = gen - gen.floor
  plus  = 1 - minus
  lunar_anomalies = [-minus, 0, +plus].map {|diff|
    equation_of_centre(gen+diff, @m)
  }

  # 盈縮差(太陽の中心差) / (日 / 10000_0000)
  solar_anomalies = (@solar_weight == 0 ? [0] : [-minus * @lunar_unit, 0, plus * @lunar_unit]).map {|diff|
    solar_unit * equation_of_centre(((mean_lunation - _perihelion(year) + diff) / solar_unit) % @year_length, @s)
  }
  solar_anomalies = solar_anomalies * 3 if @solar_weight == 0

  # 経朔 - 定朔
  (lunar_anomalies[1] - solar_anomalies[1]) / (((lunar_anomalies[2] - lunar_anomalies[0]) -
                                                (solar_anomalies[2] - solar_anomalies[0])) / @lunar_unit + mean_motion)
end

#_anomaly_b(mean_lunation, year, solar_unit, mean_motion) ⇒ Object

経朔 - 定朔 ( B 方式 - 微分)



603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
# File 'lib/when_exe/region/chinese.rb', line 603

def _anomaly_b(mean_lunation, year, solar_unit, mean_motion)

  # 遅速差(月の中心差) / (日 / 10000_0000)
  lunar_anomalies = [0,1].map {|diff|
    equation_of_centre(((mean_lunation + @anomalistic_month_shift) % @anomalistic_month_length) / @lunar_unit, @m, diff)
  }

  # 盈縮差(太陽の中心差) / (日 / 10000_0000)
  solar_anomalies = (0..@solar_weight).to_a.map {|diff|
    solar_unit * equation_of_centre(((mean_lunation - _perihelion(year)) / solar_unit) % @year_length, @s, diff)
  }
  solar_anomalies[1] ||= 0

  # 経朔 - 定朔
  (lunar_anomalies[0] - solar_anomalies[0]) / (lunar_anomalies[1] / @lunar_unit -
                                               solar_anomalies[1] /  solar_unit + mean_motion)
end

#_anomaly_c(mean_lunation, year, solar_unit, mean_motion) ⇒ Object

経朔 - 定朔 ( C 方式 - 幾何学的補正)



622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
# File 'lib/when_exe/region/chinese.rb', line 622

def _anomaly_c(mean_lunation, year, solar_unit, mean_motion)
  diff = 0
  loop do

    # 遅速差(月の中心差) / (日 / 10000_0000)
    lunar_anomaly = equation_of_centre(((mean_lunation - diff + @anomalistic_month_shift) % @anomalistic_month_length) / @lunar_unit, @m)

    # 盈縮差(太陽の中心差) / (日 / 10000_0000)
    solar_anomaly = solar_unit * equation_of_centre(((mean_lunation - diff - _perihelion(year)) / solar_unit) % @year_length, @s)

    # 次の差分
    next_diff = (lunar_anomaly - solar_anomaly) / mean_motion
    return next_diff if (next_diff - diff).abs < @anomaly_precision
    diff = next_diff
  end 
end

#_anomaly_d(mean_lunation, year, solar_unit, mean_motion) ⇒ Object

経朔 - 定朔 ( D 方式 - 差分)



584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
# File 'lib/when_exe/region/chinese.rb', line 584

def _anomaly_d(mean_lunation, year, solar_unit, mean_motion)

  # 遅速差(月の中心差) / (日 / 10000_0000)
  lunar_anomalies = [0,1].map {|day|
    equation_of_centre(((mean_lunation + day + @anomalistic_month_shift) % @anomalistic_month_length) / @lunar_unit, @m)
  }

  # 盈縮差(太陽の中心差) / (日 / 10000_0000)
  solar_anomalies = (0..@solar_weight).to_a.map {|day|
    solar_unit * equation_of_centre(((mean_lunation + day - _perihelion(year)) / solar_unit) % @year_length, @s)
  }
  solar_anomalies[1] ||= solar_anomalies[0]

  # 経朔 - 定朔
  (lunar_anomalies[0] - solar_anomalies[0]) / ((lunar_anomalies[1] - lunar_anomalies[0]) -
                                               (solar_anomalies[1] - solar_anomalies[0]) + mean_motion)
end

#_anomaly_u(mean_lunation, year, solar_unit, mean_motion) ⇒ Object

経朔 - 定朔 ( U 方式 - Chinese-Uighur)



640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
# File 'lib/when_exe/region/chinese.rb', line 640

def _anomaly_u(mean_lunation, year, solar_unit, mean_motion)

  # 遅速差(月の中心差) / (日 / 1_0000)
  @approx_anomalistic_month_length ||= (@anomalistic_month_length / @lunar_unit) / 9
  l_lunar = mean_lunation - @year_length / 6 # 暦元を雨水に変更
  l_lunar = (l_lunar + @anomalistic_month_shift - @anomalistic_month_length * 13 *
            (l_lunar / @year_length).floor) % @approx_anomalistic_month_length
  sign, angle = (l_lunar * 9).divmod(124)
  angle = angle.floor
  lunar_anomaly = angle * (124 - angle)
  lunar_anomaly = -lunar_anomaly unless sign == 1

  # 盈縮差(太陽の中心差) / (日 / 1_0000)
  l_solar = mean_lunation % @year_length
  sign, angle = l_solar.floor.divmod(182)
  solar_anomaly = (angle * (182 - angle) * 2.0 / 9).floor
  solar_anomaly = -solar_anomaly unless sign == 1

  (solar_anomaly + lunar_anomaly) / 10000.0
end

#_initialize_risseiObject

立成の作成



674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
# File 'lib/when_exe/region/chinese.rb', line 674

def _initialize_rissei
  @year_length              =  @year_length.to_f                  # 暦元の冬至年 / 日
  @year_span                = (@year_span || 1).to_i              # 冬至年の改訂周期 / 年
  @anomalistic_year_shift   =  @anomalistic_year_shift.to_f if @anomalistic_year_shift # 暦應(暦元での冬至から近日点通過までの日数)
  @precession               = (@precession || 0.015).to_f         # 歳差
  @lunation_length          =  @lunation_length.to_f              # 朔実(朔望月)
  @lunation_shift           =  @lunation_shift.to_f               # 閏應(暦元前経朔から暦元天正冬至までの日数)
  @lunar_mean_motion        =  @lunar_mean_motion.to_f            # 月平行(恒星天に対する月の平均運動 / 日)
  @anomalistic_month_length =  @anomalistic_month_length.to_f     # 転終(近点月)
  @anomalistic_month_shift  =  @anomalistic_month_shift.to_f      # 転應(暦元前近/遠地点通過から暦元天正冬至までの日数)
  @anomaly_method           =  @anomaly_method || 'a'             # (経朔-定朔)の計算方法
  @anomaly_precision        = (@anomaly_precision || 1.0E-5).to_f # c 方式 での収束判定誤差 / 日
  @solar_weight             = (@solar_weight      || 0     ).to_i # (経朔-定朔)の計算で用いる実行差での太陽盈縮の重み(0:非考慮,1:考慮)
  @lunar_unit               =  @lunar_unit.to_f                   # 太陰遅速計算用招差法定数の時間の単位(限)
  @m                        =  _rissei_j(@m) if @m                # 太陰遅速計算用招差法定数
  @s                        =  _rissei_j(@s) if @s                # 太陽盈縮計算用招差法定数
end

#_rissei_j(table) ⇒ Object

招差法用の表の生成



693
694
695
696
697
698
699
# File 'lib/when_exe/region/chinese.rb', line 693

def _rissei_j(table)
  table.map {|range, base, coefficients|
    sign = range.last == base ? -1 : +1
    [range, base, coefficients.reverse,
     (1...coefficients.size).to_a.reverse.map {|i| sign * i * coefficients[i]}]
  }
end

#cn_to_time_(cn, time0 = nil) ⇒ Numeric

周期番号 -> 日時(定朔)

Parameters:

  • cn (Numeric)

    周期番号

  • time0 (Numeric) (defaults to: nil)

    日時の初期近似値(ダミー)

Returns:



545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
# File 'lib/when_exe/region/chinese.rb', line 545

def cn_to_time_(cn, time0=nil)
  # 暦元天正冬至から当該経朔までの日数
  mean_lunation  = cn * @lunation_length - @lunation_shift

  # 当該経朔を含む近点年の暦元からの年数
  year  = (mean_lunation / @year_length).floor
  until (_perihelion(year)..._perihelion(year+1)).include?(mean_lunation)
    year += _perihelion(year) > mean_lunation ? -1 : +1
  end

  # 定朔
  solar_unit  = (_year_length(year) + (@anomalistic_year_shift ? @precession : 0))/ @year_length
  mean_motion = (@lunar_mean_motion - @solar_weight / solar_unit) * 10000_0000
  @day_epoch + mean_lunation - send('_anomaly_' + @anomaly_method.downcase, mean_lunation, year, solar_unit, mean_motion)
end

#equation_of_centre(mean_anomaly, table, differential = 0) ⇒ Object

中心差およびその時間微分

Raises:

  • (RangeError)


662
663
664
665
666
667
668
669
670
671
# File 'lib/when_exe/region/chinese.rb', line 662

def equation_of_centre(mean_anomaly, table, differential=0)
  table.each do |range, base, *coefficients|
    if range.include?(mean_anomaly)
      diff = mean_anomaly - base
      diff = diff.abs if coefficients[0].size[0] == 0
      return coefficients[differential].inject(0) {|sum, coefficient| sum * diff + coefficient}
    end
  end
  raise RangeError, 'Mean anomaly out of range: ' + mean_anomaly.to_s
end