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

FormulaWithTable, 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

Constants included from Namespace

Namespace::DC, Namespace::DCQ, Namespace::DCT, Namespace::FOAF, Namespace::OWL, Namespace::RDF, Namespace::RDFC, Namespace::RDFS, Namespace::RSS, Namespace::XSD

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, #parent, #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:



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

def alt
  @alt
end

#formulaString, Hash (readonly)

計算対象 - 公式の指定

Returns:



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

def formula
  @formula
end

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

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

Returns:



1203
1204
1205
# File 'lib/when_exe/ephemeris.rb', line 1203

def graha
  @graha
end

#is_dynamicalBoolean (readonly)

時刻系が dynamical か

Returns:

  • (Boolean)


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

def is_dynamical
  @is_dynamical
end

#latNumeric (readonly)

観測地の基準緯度 / 度

Returns:



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

def lat
  @lat
end

#locationWhen::Coordinates::Spatial (readonly)

観測地



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

def location
  @location
end

#longNumeric (readonly)

観測地の基準経度 / 度

Returns:



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

def long
  @long
end

#time_standardString (readonly)

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

Returns:



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

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:



1288
1289
1290
1291
1292
1293
1294
# File 'lib/when_exe/ephemeris.rb', line 1288

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)


1571
1572
1573
1574
1575
1576
1577
1578
1579
1580
1581
1582
# File 'lib/when_exe/ephemeris.rb', line 1571

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, {:time_standard=>seed[:time_standard]}) :
                                         When::TM::JulianDate.universal_time(t), seed)
end

#cn_to_time_(cn, time0 = nil) ⇒ Numeric

周期番号 -> 日時

Parameters:

Returns:



1238
1239
1240
1241
# File 'lib/when_exe/ephemeris.rb', line 1238

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


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
1375
1376
1377
# File 'lib/when_exe/ephemeris.rb', line 1346

def day_event(t, event, target=When.Resource('_ep:Sun'), height=nil)
  # 時刻の初期値
  dl  = @location.long / (360.0 * @location.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, margin = When::PT6H, &block) ⇒ Array<String, Numeric, Array<Array<Numeric or When::TM::TemporalPosition, String>>>

月食の情報

Parameters:

Returns:



1509
1510
1511
# File 'lib/when_exe/ephemeris.rb', line 1509

def lunar_eclipse(date, margin=When::PT6H, &block)
  location.lunar_eclipse(date, margin, &block)
end

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

月の南中の日時

Parameters:

Returns:

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

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



1481
1482
1483
# File 'lib/when_exe/ephemeris.rb', line 1481

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



1427
1428
1429
# File 'lib/when_exe/ephemeris.rb', line 1427

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



1469
1470
1471
# File 'lib/when_exe/ephemeris.rb', line 1469

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

#moon_visibility(t) ⇒ Numeric

Note:

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

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

Parameters:

Returns:

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


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

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



1442
1443
1444
# File 'lib/when_exe/ephemeris.rb', line 1442

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



1457
1458
1459
# File 'lib/when_exe/ephemeris.rb', line 1457

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:



1265
1266
1267
1268
1269
1270
1271
# File 'lib/when_exe/ephemeris.rb', line 1265

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

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



1249
1250
1251
1252
1253
1254
# File 'lib/when_exe/ephemeris.rb', line 1249

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:



1494
1495
1496
# File 'lib/when_exe/ephemeris.rb', line 1494

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



1416
1417
1418
# File 'lib/when_exe/ephemeris.rb', line 1416

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



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

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



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

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

#time_to_cn(t) ⇒ Numeric

日時 -> 周期番号

Parameters:

Returns:



1228
1229
1230
# File 'lib/when_exe/ephemeris.rb', line 1228

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



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
1557
1558
1559
1560
# File 'lib/when_exe/ephemeris.rb', line 1528

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 / @location.degree
  lat  = @location.lat  / @location.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