@behaver/celestial-coordinate
Version:
The package for handling celestial coordinate.
206 lines (173 loc) • 5.56 kB
JavaScript
'use strict';
const CommonCoordinate = require('./CommonCoordinate');
const EquinoctialCoordinate = require('./EquinoctialCoordinate');
const { JDateRepository } = require('@behaver/jdate');
const SiderealTime = require('@behaver/sidereal-time');
const Angle = require('@behaver/angle');
const angle = new Angle;
/**
* HourAngleCoordinate
*
* 天球时角坐标对象
*
* @author 董 三碗 <qianxing@yeah.net>
*/
class HourAngleCoordinate extends CommonCoordinate {
/**
* 设定起始天球时角坐标
*
* @param {JDateRepository} options.epoch 观测历元
* @param {Number} options.obGeoLong 观测点地理经度,单位:度,值域:[180, 180]
* @param {SphericalCoordinate3D} options.sc 球坐标
* @param {Number} options.longitude 时角,单位:度,值域:[0, 360)
* @param {Number} options.latitude 赤纬,单位:度,值域:[-90, 90]
* @param {Number} options.radius 坐标距离半径,值域:[10e-8, +∞)
*
* @return {HourAngleCoordinate} 返回 this 引用
*/
from({
epoch,
obGeoLong,
sc,
longitude,
latitude,
radius,
}) {
if (!(epoch instanceof JDateRepository)) throw Error('The param epoch should be a JDateRepository.');
if (typeof(obGeoLong) !== 'number') throw Error('The param obGeoLong should be a Number.');
else if (obGeoLong < -180 || obGeoLong > 180) throw Error('The param obGeoLong should be in [-180, 180]');
this.SiderealTime = new SiderealTime(epoch, obGeoLong);
this.private = {
...this.private,
epoch,
obGeoLong,
};
this.position({
sc,
longitude,
latitude,
radius,
});
return this;
}
/**
* 转换当前坐标的系统参数
*
* @param {JDateRepository} options.epoch 观测历元
* @param {Number} options.obGeoLong 观测点地理经度
*
* @return {HourAngleCoordinate} 返回 this 引用
*/
on({
epoch,
obGeoLong,
}) {
let changeEpoch = false;
if (epoch === undefined) {
epoch = this.private.epoch;
changeEpoch = true;
} else if (!(epoch instanceof JDateRepository)) throw Error('The param epoch should be a JDateRepository.');
if (obGeoLong === undefined) obGeoLong = this.private.obGeoLong;
else if (typeof(obGeoLong) !== 'number') throw Error('The param obGeoLong should be a Number');
else if (obGeoLong < -180 || obGeoLong > 180) throw Error('The param obGeoLong should be in [-180, 180]');
// 将时角球坐标转换至瞬时赤道球坐标
let sc1 = this.sc
.inverse('y')
.rotateZ(angle.setSeconds(this.SiderealTime.trueVal).getRadian());
// 保持球坐标值连续性的值更改
this.private.SCContinuouslyChange(sc1);
if (changeEpoch) { // 针对观测时间改变的情况,引入赤道坐标对象处理
let ec = new EquinoctialCoordinate({
sc: this.sc,
epoch: this.epoch,
withNutation: true,
withAnnualAberration: true,
withGravitationalDeflection: true,
onFK5: true,
isContinuous: true,
});
this.private.sc = ec.get({
epoch: epoch,
}).sc;
this.private.epoch = epoch;
}
// 更新恒星时对象、观测经度、观测纬度
this.SiderealTime = new SiderealTime(epoch, obGeoLong);
this.private.obGeoLong = obGeoLong;
// 将瞬时赤道坐标转换至时角球坐标
let sc2 = this.sc
.rotateZ(- angle.setSeconds(this.SiderealTime.trueVal).getRadian())
.inverse('y');
// 保持球坐标值连续性的值更改
this.private.SCContinuouslyChange(sc2);
return this;
}
/**
* 获取指定系统参数的坐标结果
*
* @param {JDateRepository} options.epoch 观测历元
* @param {Number} options.obGeoLong 观测点地理经度
*
* @return {Object} 坐标结果对象
*/
get(options) {
if (options == undefined) {
return {
sc: this.sc,
epoch: this.epoch,
obGeoLong: this.obGeoLong,
};
} else {
// 记录原坐标和条件,输出目标坐标后恢复
let sc_0 = this.sc;
let epoch_0 = this.epoch;
let obGeoLong_0 = this.obGeoLong;
this.on(options);
// 记录新坐标和条件
let sc = this.sc;
let epoch = this.epoch;
let obGeoLong = this.obGeoLong.getDegrees();
// 还原为初始坐标和条件
this.private.sc = sc_0;
this.private.epoch = epoch_0;
this.private.obGeoLong = obGeoLong_0.getDegrees();
this.SiderealTime = new SiderealTime(epoch_0, obGeoLong_0.getDegrees());
return {
sc,
epoch,
obGeoLong,
}
}
}
/**
* 转换坐标至目标历元
*
* @param {JDateRepository} epoch 目标历元
*
* @return {HorizontalCoordinate} 返回 this 引用
*/
onEpoch(value) {
return this.on({
epoch: value,
});
}
/**
* 获取 观测经度 角度对象
*
* @return {Angle} 观测经度 角度对象
*/
get obGeoLong() {
return new Angle(this.private.obGeoLong, 'd');
}
/**
* 设置 观测经度 角度对象
*
* @param {Angle} value 观测经度 角度对象
*/
set obGeoLong(value) {
this.on({
obGeoLong: value
});
}
}
module.exports = HourAngleCoordinate;