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

Defined Under Namespace

Modules: ForwardedFormula

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::MethodCash

Parts::MethodCash::Escape

Constants included from Parts::Resource

Parts::Resource::ConstList, Parts::Resource::ConstTypes, Parts::Resource::IRIHeader, 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

_adjust, _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

_setup_, _setup_info, escape, #method_missing, #method_missing_

Methods included from Parts::Resource

#[], #^, _abbreviation_to_iri, _decode, _encode, _extract_prefix, _instance, _instantiate, _parse, _path_with_prefix, _replace_tags, _setup_, _setup_info, _simplify_path, base_uri, #each, #enum_for, #hierarchy, #include?, #included?, #iri, #leaf?, #m17n, #map, #next, #parent, #prev, #registered?, root_dir

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

#altNumeric (readonly)

観測地の高度 / m

Returns:



1186
1187
1188
# File 'lib/when_exe/ephemeris.rb', line 1186

def alt
  @alt
end

#formulaString, Hash (readonly)

計算対象 - 公式の指定

Returns:



1170
1171
1172
# File 'lib/when_exe/ephemeris.rb', line 1170

def formula
  @formula
end

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

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

Returns:



1198
1199
1200
# File 'lib/when_exe/ephemeris.rb', line 1198

def graha
  @graha
end

#is_dynamicalBoolean (readonly)

時刻系が dynamical か

Returns:

  • (Boolean)


1194
1195
1196
# File 'lib/when_exe/ephemeris.rb', line 1194

def is_dynamical
  @is_dynamical
end

#latNumeric (readonly)

観測地の基準緯度 / 度

Returns:



1182
1183
1184
# File 'lib/when_exe/ephemeris.rb', line 1182

def lat
  @lat
end

#locationWhen::Coordinates::Spatial (readonly)

観測地



1174
1175
1176
# File 'lib/when_exe/ephemeris.rb', line 1174

def location
  @location
end

#longNumeric (readonly)

観測地の基準経度 / 度

Returns:



1178
1179
1180
# File 'lib/when_exe/ephemeris.rb', line 1178

def long
  @long
end

#time_standardString (readonly)

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

Returns:



1190
1191
1192
# File 'lib/when_exe/ephemeris.rb', line 1190

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::EQUATORIAL_HA ]

    3 - 地平座標 When::Coordinates::Spatial::HORIZONTAL
  • target (When::Ephemeris::CelestialObject)

    対象星

Returns:



1283
1284
1285
1286
1287
1288
1289
# File 'lib/when_exe/ephemeris.rb', line 1283

def _coords(t, system, target)
  pos = target.coords(t, @location)
  pos = pos.y_to_r(t, @location)  if system >= When::Coordinates::Spatial::EQUATORIAL
  pos = pos.r_to_rh(t, @location) if system >= When::Coordinates::Spatial::EQUATORIAL_HA
  pos = pos.rh_to_h(t, @location) if system >= When::Coordinates::Spatial::HORIZONTAL
  return pos
end

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

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

Parameters:

Returns:

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


1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
# File 'lib/when_exe/ephemeris.rb', line 1538

def _to_seed_type(d, seed)
  case seed
  when Numeric         ; return d
  when When::TimeValue ; seed = seed._attr
  else                 ; seed = seed.dup
  end
  seed[:precision] = nil
  seed[:clock]   ||= When::TM::Clock.local_time
  t = When::TM::JulianDate._d_to_t(d)
  seed[:frame].jul_trans(@is_dynamical ? When::TM::JulianDate.dynamical_time(t) :
                                         When::TM::JulianDate.universal_time(t), seed)
end

#cn_to_time_(cn, time0 = nil) ⇒ Numeric

周期番号 -> 日時

Parameters:

Returns:



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

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


1341
1342
1343
1344
1345
1346
1347
1348
1349
1350
1351
1352
1353
1354
1355
1356
1357
1358
1359
1360
1361
1362
1363
1364
1365
1366
1367
1368
1369
1370
1371
1372
# File 'lib/when_exe/ephemeris.rb', line 1341

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

  # 天体の地平座標での高度または方位角
  case event
  when 0
    meridian = _coords(t0, When::Coordinates::Spatial::EQUATORIAL_HA, 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, 1) {|t1| _coords(t1, When::Coordinates::Spatial::EQUATORIAL_HA, target).phi}) :
                 (root(t0, height     ) {|t1| _coords(t1, When::Coordinates::Spatial::HORIZONTAL, target).theta }),
   t)
rescue RangeError
  nil
end

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

月の南中の日時

Parameters:

Returns:

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

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



1476
1477
1478
# File 'lib/when_exe/ephemeris.rb', line 1476

def meridian_passage_of_moon(t)
  day_event_in_the_day(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



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

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



1464
1465
1466
# File 'lib/when_exe/ephemeris.rb', line 1464

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

#moon_visibility(t) ⇒ Numeric

Note:

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

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

Parameters:

Returns:

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


1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
# File 'lib/when_exe/ephemeris.rb', line 1302

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

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

月の出の日時

Parameters:

Returns:

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

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



1437
1438
1439
# File 'lib/when_exe/ephemeris.rb', line 1437

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

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

月の入りの日時

Parameters:

Returns:

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

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



1452
1453
1454
# File 'lib/when_exe/ephemeris.rb', line 1452

def moonset(t, height='A')
  day_event_in_the_day(t, +1, When.Resource('_ep:Moon'), height)
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:



1260
1261
1262
1263
1264
1265
1266
# File 'lib/when_exe/ephemeris.rb', line 1260

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

#phase_range(date) ⇒ Array<Numeric>

当該日付の月の位相の変化範囲

Parameters:

Returns:

  • (Array<Numeric>)

    当該日付の月の位相の変化範囲



1244
1245
1246
1247
1248
1249
# File 'lib/when_exe/ephemeris.rb', line 1244

def phase_range(date)
  date = date.floor
  [date, date.succ].map {|d|
    time_to_cn(d)
  }
end

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

太陽の最大高度の日時

Parameters:

Returns:

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

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



1411
1412
1413
# File 'lib/when_exe/ephemeris.rb', line 1411

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

#sunrise(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



1385
1386
1387
# File 'lib/when_exe/ephemeris.rb', line 1385

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

#sunset(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



1400
1401
1402
# File 'lib/when_exe/ephemeris.rb', line 1400

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

#time_to_cn(t) ⇒ Numeric

日時 -> 周期番号

Parameters:

Returns:



1223
1224
1225
# File 'lib/when_exe/ephemeris.rb', line 1223

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



1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526
1527
# File 'lib/when_exe/ephemeris.rb', line 1495

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.round+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+long/360.0).round, Sgn[event][0], When.Resource('_ep:Sun'), bs), t)
rescue RangeError
  nil
end