Class: When::Ephemeris::Formula

Inherits:
BasicTypes::Object show all
Includes:
When::Ephemeris, Parts::MethodCash
Defined in:
lib/when_exe/ephemeris.rb

Overview

暦法オブジェクトに天体暦機能を提供する

Direct Known Subclasses

Hindu, MeanLunation, VariableYearLengthMethod

Defined Under Namespace

Modules: Methods

Constant Summary collapse

CYCLE_0M =

Seed

0
CYCLE_1M =
1000000
Sgn =

Year Event

[[-1,+1],[-1,-1],[+1,-1],[+1,+1]]
Bs =
[[11.0,  7.0, 11.0,  7.0],
[11.0,  7.0, 11.0,  7.0],
[11.0,  7.0, 11.0,  7.0],
[14.0,  8.5, 14.0,  8.5],
[16.0, 10.0, 16.0, 10.0],
[17.0, 14.0, 17.0, 14.0],
[17.0, 17.0, 17.0, 17.0]]

Constants included from When::Ephemeris

AU, AcS, BCENT, C0, CIRCLE, COS, COSL, COSLT, COST, DAY, DEG, EPOCH1800, EPOCH1900, EPOCH1975, EPOCH2000, FARAWAY, JCENT, JYEAR, Jupiter, LIN, Mars, Mercury, Neptune, P0B, P0L, P0P, P0dB, P0dL, P1B, P1L, P1R, P2B, P2L, P2Q, P2dL, P3L, P3Q, P4B, P4L, P4Q, P4dL, P5B, P5L, P5Q, P5dL, P5l, P5n, P5r, P5t, P6B, P6L, P6Q, P6dL, P6l, P6n, P6r, P6t, P7B, P7L, P7R, P8B, P8L, P8R, P9B, P9L, P9R, PSEC, Pluto, SIN, SINL, SINLT, SINT, Saturn, Uranus, Venus

Constants included from Parts::Resource

Parts::Resource::LabelProperty

Instance Attribute Summary collapse

Attributes inherited from BasicTypes::Object

#label

Attributes included from Parts::Resource

#_pool, #child, #keys, #locale, #namespace

Instance Method Summary collapse

Methods included from When::Ephemeris

_rot, _to_p2, _to_p3, _to_r3, acos, asin, cosc, cosd, delta_e, delta_p, julian_century_from_2000, julian_year_from_1975, obl, polynomial, root, sinc, sind, tanc, tand, trigonometric

Methods included from Parts::MethodCash

#method_missing, #method_missing_

Methods inherited from BasicTypes::Object

#tap

Methods included from Parts::Resource

#[], #^, _extract_prefix, _instance, _parse, _path_with_prefix, _setup_, #each, #enum_for, #hierarchy, #include?, #included?, #iri, #leaf?, #m17n, #map, #next, #parent, #prev, #registered?

Methods included from Parts::Resource::Pool

#[], #[]=, #_pool, #_setup_, #pool_keys

Methods included from Parts::Resource::Synchronize

#synchronize

Dynamic Method Handling

This class handles dynamic methods through the method_missing method in the class When::Parts::MethodCash

Instance Attribute Details

#formulaString, Hash (readonly)

計算対象 - 公式の指定

Returns:



1160
1161
1162
# File 'lib/when_exe/ephemeris.rb', line 1160

def formula
  @formula
end

#grahaHash<Symbol=>When::Ephemeris::Datum> (readonly)

天体オブジェクトを保持するハッシュ

Returns:



1184
1185
1186
# File 'lib/when_exe/ephemeris.rb', line 1184

def graha
  @graha
end

#is_dynamicalBoolean (readonly)

時刻系が dynamical か

Returns:

  • (Boolean)


1180
1181
1182
# File 'lib/when_exe/ephemeris.rb', line 1180

def is_dynamical
  @is_dynamical
end

#latNumeric (readonly)

観測地の基準緯度 / 度

Returns:



1172
1173
1174
# File 'lib/when_exe/ephemeris.rb', line 1172

def lat
  @lat
end

#locationWhen::Coordinates::Spatial (readonly)

観測地



1164
1165
1166
# File 'lib/when_exe/ephemeris.rb', line 1164

def location
  @location
end

#longNumeric (readonly)

観測地の基準経度 / 度

Returns:



1168
1169
1170
# File 'lib/when_exe/ephemeris.rb', line 1168

def long
  @long
end

#time_standardString (readonly)

時刻系(‘universal’ or ‘dynamical’)

Returns:



1176
1177
1178
# File 'lib/when_exe/ephemeris.rb', line 1176

def time_standard
  @time_standard
end

Instance Method Details

#_coords(t, system, target) ⇒ When::Ephemeris::Coords

天体の位置情報

Parameters:

  • t (Numeric)

    ユリウス日(Terrestrial Time)

  • t (When::TM::TemporalPosition)
  • system (Integer)

    座標系

    0 - When::Coordinates::Spatial::ECLIPTIC (黄道座標)
    1 - When::Coordinates::Spatial::EQUATORIAL (赤道座標)
    2 - When::Coordinates::Spatial::HORIZONTAL (地平座標)
  • target (When::Ephemeris::CelestialObject)

    対象星

Returns:



1255
1256
1257
1258
1259
1260
# File 'lib/when_exe/ephemeris.rb', line 1255

def _coords(t, system, target)
  pos = target.coords(t, @location)
  pos = pos.y_to_r(t, @location) if system >= 1
  pos = pos.r_to_h(t, @location) if system >= 2
  return pos
end

#_to_seed_type(d, seed) ⇒ Numeric, When::TM::TemporalPosotion

ユリウス日(Numeric)を seed と同じ型に変換して返します。

Parameters:

Returns:

  • (Numeric, When::TM::TemporalPosotion)


1504
1505
1506
1507
1508
1509
1510
1511
1512
# File 'lib/when_exe/ephemeris.rb', line 1504

def _to_seed_type(d, seed)
  return d if seed.kind_of?(Numeric)
  options = seed._attr
  options[:precision] = nil
  options[:clock]   ||= When::TM::Clock.local_time || When.utc
  t = When::TM::JulianDate._d_to_t(d)
  options[:frame].jul_trans(@is_dynamical ? When::TM::JulianDate.dynamical_time(t) :
                                            When::TM::JulianDate.universal_time(t), options)
end

#cn_to_time_(cn, time0 = nil) ⇒ Numeric

周期番号 -> 日時

Parameters:

Returns:



1219
1220
1221
1222
# File 'lib/when_exe/ephemeris.rb', line 1219

def cn_to_time_(cn, time0=nil)
  time0 ||= (cn - @cycle_number_0m) / @cycle_number_1m
  root(time0, cn) {|t| time_to_cn(t)}
end

#day_event(t, event, target = When.Resource('_ep:Sun'), height = nil) ⇒ Numeric, When::TM::TemporalPosotion

天体の出没最大高度日時

Parameters:

  • t (Numeric)

    ユリウス日(Terrestrial Time)

  • t (When::TM::TemporalPosition)
  • event (Integer)
    -1 - 出
    0 - 南中
    +1 - 没
    nil - 最大高度
  • target (When::Ephemeris::CelestialObject) (defaults to: When.Resource('_ep:Sun'))

    対象星(デフォルトは太陽)

  • height (Numeric) (defaults to: nil)

    閾値高度/度

  • height (String) (defaults to: nil)
    ‘0’ - 太陽の上端が地平線(大気差考慮) - 太陽のデフォルト
    ‘A’ - 天体の中心が地平線(大気差考慮) - 太陽以外のデフォルト
    ‘T’ - 夜明け/日暮れ

Returns:

  • (Numeric, When::TM::TemporalPosotion)

    計算結果

    t が ユリウス日(Terrestrial Time) => ユリウス日(Terrestrial Time)
    t が その他 => When::TM::DateAndTime


1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
# File 'lib/when_exe/ephemeris.rb', line 1312

def day_event(t, event, target=When.Resource('_ep:Sun'), height=nil)
  # 時刻の初期値
  dl  = @location.long / (360.0 * When::Coordinates::Spatial::DEGREE)
  t0  = (+t + 0.5 + dl).floor - dl
  dt  = _coords(t0, When::Coordinates::Spatial::EQUATORIAL, target).phi -
        @location.local_sidereal_time(t0) / 24.0 + 0.25 * (event||0)
  t0 += dt - (dt+0.5).floor

  # 天体の地平座標での高度または方位角
  case event
  when 0
    meridian = _coords(t0, When::Coordinates::Spatial::HORIZONTAL, target).phi.round
  when +1, -1
    height ||= target.instance_of?(When::Ephemeris::Sun) ? '0' : 'A'
    if height.kind_of?(String)
      height = @location.datum.zeros[height.upcase]
      raise ArgumentError, 'invalid height string' unless height
    end
    height = height / 360.0 - (0.25 - @location.horizon) +
           [@location.alt / (1000.0 * @location.datum.air[0]), 1].min * @location.datum.zeros['A'] / 360.0
  else
    height = nil # 極値検索のため
  end

  # イベントの時刻
  _to_seed_type(
    event == 0 ? (root(t0, meridian) {|t1| _coords(t1, When::Coordinates::Spatial::HORIZONTAL, target).phi   }) :
                 (root(t0, height  ) {|t1| _coords(t1, When::Coordinates::Spatial::HORIZONTAL, target).theta }),
   t)
end

#meridian_passage_of_moon(t) ⇒ Numeric, When::TM::TemporalPosotion

月の南中の日時

Parameters:

Returns:

  • (Numeric, When::TM::TemporalPosotion)

    月の南中の日時(ユリウス日(Terrestrial Time)またはWhen::TM::DateAndTime 該当時刻がなければ nil



1445
1446
1447
# File 'lib/when_exe/ephemeris.rb', line 1445

def meridian_passage_of_moon(t)
  _day_event(t, 0, When.Resource('_ep:Moon'))
end

#meridian_passage_of_sun(t) ⇒ Numeric, When::TM::TemporalPosotion

太陽の南中の日時

Parameters:

Returns:

  • (Numeric, When::TM::TemporalPosotion)

    太陽の南中の日時(ユリウス日(Terrestrial Time)またはWhen::TM::DateAndTime



1391
1392
1393
# File 'lib/when_exe/ephemeris.rb', line 1391

def meridian_passage_of_sun(t)
  day_event(t, 0, When.Resource('_ep:Sun'))
end

#moon_noon(t) ⇒ Numeric, When::TM::TemporalPosotion

月の最大高度の日時

Parameters:

Returns:

  • (Numeric, When::TM::TemporalPosotion)

    月の最大高度の日時(ユリウス日(Terrestrial Time)またはWhen::TM::DateAndTime 該当時刻がなければ nil



1433
1434
1435
# File 'lib/when_exe/ephemeris.rb', line 1433

def moon_noon(t)
  _day_event(t, nil, When.Resource('_ep:Moon'))
end

#moon_rise(t, height = 'A') ⇒ Numeric, When::TM::TemporalPosotion

月の出の日時

Parameters:

Returns:

  • (Numeric, When::TM::TemporalPosotion)

    月の出の日時(ユリウス日(Terrestrial Time)またはWhen::TM::DateAndTime 該当時刻がなければ nil



1406
1407
1408
# File 'lib/when_exe/ephemeris.rb', line 1406

def moon_rise(t, height='A')
  _day_event(t, -1, When.Resource('_ep:Moon'), height)
end

#moon_set(t, height = 'A') ⇒ Numeric, When::TM::TemporalPosotion

月の入りの日時

Parameters:

Returns:

  • (Numeric, When::TM::TemporalPosotion)

    月の入りの日時(ユリウス日(Terrestrial Time)またはWhen::TM::DateAndTime 該当時刻がなければ nil



1421
1422
1423
# File 'lib/when_exe/ephemeris.rb', line 1421

def moon_set(t, height='A')
  _day_event(t, +1, When.Resource('_ep:Moon'), height)
end

#moon_visibility(t) ⇒ Numeric

Note:

満月に近い場合は考慮されていません。主に新月の初見の確認に用います。

日没時に月が見えるか否か

Parameters:

Returns:

  • (Numeric)
    正 - 見える
    負 - 見えない


1273
1274
1275
1276
1277
1278
1279
1280
1281
1282
1283
1284
1285
1286
1287
1288
1289
1290
# File 'lib/when_exe/ephemeris.rb', line 1273

def moon_visibility(t)
  sun  = When.Resource('_ep:Sun')
  moon = When.Resource('_ep:Moon')

  # 日没時刻
  t = day_event(+t, +1, sun, 'Z')

  # 月の地平線からの高度
  h = _coords(t, When::Coordinates::Spatial::HORIZONTAL, moon).theta * 360.0

  # 月と太陽の離角
  p = moon.elongation(t, sun, @location) * 360.0

  # 指標の計算
  n = 4.0 - 0.1*p
  f = p < 40.0 ? 4.0 + n*(n+1)/2 : 4.0
  return (h / f - 1.0)
end

#nearest_past(date, n = 0, d = 1) ⇒ Numeric, When::TM::TemporalPosition

指定の周期番号パターンになる最も近い過去の日時

Parameters:

  • date (Numeric)

    ユリウス日(Terrestrial Time)

  • date (When::TM::TemporalPosition)
  • n (Numeric) (defaults to: 0)

    相対周期番号(n=0 なら date または date の直前が基準)

  • d (Numeric) (defaults to: 1)

    単位周期数

Returns:



1233
1234
1235
1236
1237
1238
1239
# File 'lib/when_exe/ephemeris.rb', line 1233

def nearest_past(date, n=0, d=1)
  i, f = n.divmod(d)
  t0   = @is_dynamical ? +date : date.to_f
  cn   = time_to_cn(date).divmod(d)[0] * d + f
  cn  -= d while (t1 = cn_to_time(cn)) > t0
  _to_seed_type((i == 0) ? t1 : cn_to_time(cn+i*d), date)
end

#sun_noon(t) ⇒ Numeric, When::TM::TemporalPosotion

太陽の最大高度の日時

Parameters:

Returns:

  • (Numeric, When::TM::TemporalPosotion)

    太陽の最大高度の日時(ユリウス日(Terrestrial Time)またはWhen::TM::DateAndTime



1380
1381
1382
# File 'lib/when_exe/ephemeris.rb', line 1380

def sun_noon(t)
  day_event(t, nil, When.Resource('_ep:Sun'))
end

#sun_rise(t, height = '0') ⇒ Numeric, When::TM::TemporalPosotion

日の出の日時

Parameters:

  • t (Numeric)

    ユリウス日(Terrestrial Time)

  • t (When::TM::TemporalPosition)
  • height (Numeric) (defaults to: '0')

    閾値高度/度

  • height (String) (defaults to: '0')
    ‘0’ - 太陽の上端が地平線(大気差考慮) - 太陽のデフォルト
    ‘T’ - 夜明け

Returns:

  • (Numeric, When::TM::TemporalPosotion)

    日の出の日時(ユリウス日(Terrestrial Time)またはWhen::TM::DateAndTime



1354
1355
1356
# File 'lib/when_exe/ephemeris.rb', line 1354

def sun_rise(t, height='0')
  day_event(t, -1, When.Resource('_ep:Sun'), height)
end

#sun_set(t, height = '0') ⇒ Numeric, When::TM::TemporalPosotion

日の入りの日時

Parameters:

  • t (Numeric)

    ユリウス日(Terrestrial Time)

  • t (When::TM::TemporalPosition)
  • height (Numeric) (defaults to: '0')

    閾値高度/度

  • height (String) (defaults to: '0')
    ‘0’ - 太陽の上端が地平線(大気差考慮) - 太陽のデフォルト
    ‘T’ - 日暮れ

Returns:

  • (Numeric, When::TM::TemporalPosotion)

    日の入りの日時(ユリウス日(Terrestrial Time)またはWhen::TM::DateAndTime



1369
1370
1371
# File 'lib/when_exe/ephemeris.rb', line 1369

def sun_set(t, height='0')
  day_event(t, +1, When.Resource('_ep:Sun'), height)
end

#time_to_cn(t) ⇒ Numeric

日時 -> 周期番号

Parameters:

Returns:



1209
1210
1211
# File 'lib/when_exe/ephemeris.rb', line 1209

def time_to_cn(t)
  @proc.call(t)
end

#year_event(t, event, target, hs = , bs = nil) ⇒ Numeric, When::TM::TemporalPosotion

恒星の出没と太陽の位置関係に関するイベントの日時

Parameters:

  • t (Numeric)

    ユリウス日(Terrestrial Time)

  • t (When::TM::TemporalPosition)
  • event (Integer)
    0 - first visible rising (=ヘリアカル・ライジング)
    1 - last visible rising
    2 - last visible setting
    3 - first visible setting
  • target (When::Ephemeris::CelestialObject)

    対象の恒星

  • hs (Numeric) (defaults to: )

    恒星の高度/度(地平線上が正)

  • bs (Numeric) (defaults to: nil)

    太陽の伏角/度(地平線上が負, よって通常は正です, デフォルトは Bs表引き)

Returns:

  • (Numeric, When::TM::TemporalPosotion)

    イベントの日時(ユリウス日(Terrestrial Time)またはWhen::TM::DateAndTime



1464
1465
1466
1467
1468
1469
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491
1492
1493
1494
# File 'lib/when_exe/ephemeris.rb', line 1464

def year_event(t, event, target, hs= @location.datum.zeros['A'], bs=nil)
  # difference of ecliptic longitude between zenith and target star 
  # when the event happens
  pos  = _coords(+t, When::Coordinates::Spatial::EQUATORIAL, target)
  long = @location.long / When::Coordinates::Spatial::DEGREE
  lat  = @location.lat  / When::Coordinates::Spatial::DEGREE
  dp   = (sind(hs) - sind(lat) * sinc(pos.theta)) / 
                    (cosd(lat) * cosc(pos.theta))

  return nil if dp.abs >= 1
  dp  = acos(dp) / CIRCLE

  # The Sun's height when the event happens
  unless bs
    mag = target.luminosity
    bs  = Bs[mag<-0.5 ?  0 : (mag<4.5 ? (mag+0.5).floor+1 : 6)][event]
  end

  # イベントの時刻
  zenith = Coords.polar(pos.phi+Sgn[event][0]*dp, lat/360.0).r_to_y(+t, @location)
  s   = sind(bs)/cosc(zenith.theta)
  arc = asin(s) / CIRCLE + 0.25
  lam = _true_sun(+t).floor+(zenith.phi+Sgn[event][1]*arc).divmod(1)[1]
  tt  = nil
  loop do
    tt = root(+t, lam) {|t1| _true_sun(t1)}
    break if tt >= +t
    lam += 1
  end
  _to_seed_type(day_event((tt+0.5+long/360.0).floor, Sgn[event][0], When.Resource('_ep:Sun'), bs), t)
end