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

#[], #^, _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:



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

def alt
  @alt
end

#formulaString, Hash (readonly)

計算対象 - 公式の指定

Returns:



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

def formula
  @formula
end

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

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

Returns:



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

def graha
  @graha
end

#is_dynamicalBoolean (readonly)

時刻系が dynamical か

Returns:

  • (Boolean)


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

def is_dynamical
  @is_dynamical
end

#latNumeric (readonly)

観測地の基準緯度 / 度

Returns:



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

def lat
  @lat
end

#locationWhen::Coordinates::Spatial (readonly)

観測地



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

def location
  @location
end

#longNumeric (readonly)

観測地の基準経度 / 度

Returns:



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

def long
  @long
end

#time_standardString (readonly)

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

Returns:



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

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:



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

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)


1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
# File 'lib/when_exe/ephemeris.rb', line 1533

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:



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

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


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

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

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

月の南中の日時

Parameters:

Returns:

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

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



1473
1474
1475
# File 'lib/when_exe/ephemeris.rb', line 1473

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



1419
1420
1421
# File 'lib/when_exe/ephemeris.rb', line 1419

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



1461
1462
1463
# File 'lib/when_exe/ephemeris.rb', line 1461

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

#moon_visibility(t) ⇒ Numeric

Note:

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

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

Parameters:

Returns:

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


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

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



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

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



1449
1450
1451
# File 'lib/when_exe/ephemeris.rb', line 1449

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:



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

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

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



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

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



1408
1409
1410
# File 'lib/when_exe/ephemeris.rb', line 1408

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



1382
1383
1384
# File 'lib/when_exe/ephemeris.rb', line 1382

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



1397
1398
1399
# File 'lib/when_exe/ephemeris.rb', line 1397

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

#time_to_cn(t) ⇒ Numeric

日時 -> 周期番号

Parameters:

Returns:



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

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



1492
1493
1494
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
# File 'lib/when_exe/ephemeris.rb', line 1492

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