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::IRIDecode, Parts::Resource::IRIDecodeTable, Parts::Resource::IRIEncode, Parts::Resource::IRIEncodeTable, 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:



1188
1189
1190
# File 'lib/when_exe/ephemeris.rb', line 1188

def alt
  @alt
end

#formulaString, Hash (readonly)

計算対象 - 公式の指定

Returns:



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

def formula
  @formula
end

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

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

Returns:



1200
1201
1202
# File 'lib/when_exe/ephemeris.rb', line 1200

def graha
  @graha
end

#is_dynamicalBoolean (readonly)

時刻系が dynamical か

Returns:

  • (Boolean)


1196
1197
1198
# File 'lib/when_exe/ephemeris.rb', line 1196

def is_dynamical
  @is_dynamical
end

#latNumeric (readonly)

観測地の基準緯度 / 度

Returns:



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

def lat
  @lat
end

#locationWhen::Coordinates::Spatial (readonly)

観測地



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

def location
  @location
end

#longNumeric (readonly)

観測地の基準経度 / 度

Returns:



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

def long
  @long
end

#time_standardString (readonly)

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

Returns:



1192
1193
1194
# File 'lib/when_exe/ephemeris.rb', line 1192

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:



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

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)


1567
1568
1569
1570
1571
1572
1573
1574
1575
1576
1577
1578
# File 'lib/when_exe/ephemeris.rb', line 1567

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:



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

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


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
1373
1374
# File 'lib/when_exe/ephemeris.rb', line 1343

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

#lunar_eclipse(date, &block) ⇒ Array<String, Numeric, Array<Array<Numeric or When::TM::TemporalPosition, String>>>

月食の情報

Parameters:

Returns:



1505
1506
1507
# File 'lib/when_exe/ephemeris.rb', line 1505

def lunar_eclipse(date, &block)
  location.lunar_eclipse(date, &block)
end

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

月の南中の日時

Parameters:

Returns:

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

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



1478
1479
1480
# File 'lib/when_exe/ephemeris.rb', line 1478

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



1424
1425
1426
# File 'lib/when_exe/ephemeris.rb', line 1424

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



1466
1467
1468
# File 'lib/when_exe/ephemeris.rb', line 1466

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

#moon_visibility(t) ⇒ Numeric

Note:

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

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

Parameters:

Returns:

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


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

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



1439
1440
1441
# File 'lib/when_exe/ephemeris.rb', line 1439

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



1454
1455
1456
# File 'lib/when_exe/ephemeris.rb', line 1454

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:



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

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>)

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



1246
1247
1248
1249
1250
1251
# File 'lib/when_exe/ephemeris.rb', line 1246

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

#solar_eclipse(date, &block) ⇒ Array<String, Numeric, Array<Array<Numeric or When::TM::TemporalPosition, String>>>

日食の情報

Parameters:

Returns:



1491
1492
1493
# File 'lib/when_exe/ephemeris.rb', line 1491

def solar_eclipse(date, &block)
  location.solar_eclipse(date, &block)
end

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

太陽の最大高度の日時

Parameters:

Returns:

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

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



1413
1414
1415
# File 'lib/when_exe/ephemeris.rb', line 1413

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



1387
1388
1389
# File 'lib/when_exe/ephemeris.rb', line 1387

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



1402
1403
1404
# File 'lib/when_exe/ephemeris.rb', line 1402

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

#time_to_cn(t) ⇒ Numeric

日時 -> 周期番号

Parameters:

Returns:



1225
1226
1227
# File 'lib/when_exe/ephemeris.rb', line 1225

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



1524
1525
1526
1527
1528
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
# File 'lib/when_exe/ephemeris.rb', line 1524

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