@behaver/celestial-coordinate
Version:
The package for handling celestial coordinate.
222 lines (188 loc) • 5.25 kB
JavaScript
'use strict';
const { SphericalCoordinate3D } = require('@behaver/coordinate/3d');
const { JDateRepository } = require('@behaver/jdate');
const Angle = require('@behaver/angle');
const angle = new Angle;
/**
* 坐标公共继承类
*
* 定义各系统坐标的公共方法,供子类继承。
*
* @private
* @author 董 三碗 <qianxing@yeah.net>
* @version 1.0.0
*/
class CommonCoordinate {
/**
* 构造函数
*
* @param {Object} options 坐标参数
*/
constructor(options = {}) {
// 初始化私有空间
this.private = {
sc: new SphericalCoordinate3D(1, 0, 0),
isContinuous: !! options.isContinuous,
SCContinuouslyChange: (function(sc) { // 保持数值连续性地更改sc值
let sc0 = this.private.sc,
delta_phi = angle.setRadian(sc.phi - sc0.phi).inRound(-180).getRadian(),
delta_theta = angle.setRadian(sc.theta - sc0.theta).inRound(-180).getRadian();
this.private.sc = new SphericalCoordinate3D(sc.r, sc0.theta + delta_theta, sc0.phi + delta_phi);
}).bind(this),
};
this.from(options);
}
/**
* 转换坐标至 目标历元
*
* 会将当前坐标转化成目标历元平坐标
*
* @param {JDateRepository} epoch 目标历元
*
* @return {CommonCoordinate} 返回 this 引用
*/
onEpoch(value) {
return this;
}
/**
* 设置 历元对象
*
* @param {JDateRepository} value 目标历元对象
*/
set epoch(value) {
this.onEpoch(value);
}
/**
* 获取 历元对象
*
* @return {JDateRepository} 历元对象
*/
get epoch() {
return new JDateRepository(this.private.epoch.JD);
}
/**
* 设定当前系统条件下的坐标点位置
*
* @param {SphericalCoordinate3D} options.sc 球坐标
* @param {Number} options.longitude 黄经,单位:度,值域:[0, 360)
* @param {Number} options.latitude 黄纬,单位:度,值域:[-90, 90]
* @param {Number} options.radius 距离半径,值域:[10e-8, +∞)
*
* @return {CommonCoordinate} 返回 this 引用
*/
position({
sc,
longitude,
latitude,
radius,
}) {
if (longitude !== undefined) this.longitude = longitude;
if (latitude !== undefined) this.latitude = latitude;
if (radius !== undefined) this.radius = radius;
if (sc !== undefined) this.sc = sc;
return this;
}
/**
* 获取 天球球坐标
*
* @return {SphericalCoordinate3D} 天球球坐标
*/
get sc() {
let sc = this.private.sc;
if (this.private.isContinuous) {
return new SphericalCoordinate3D(sc.r, sc.theta, sc.phi);
} else {
// 角度表达数值范围调整
let pi2 = 2 * Math.PI,
phi = (sc.phi >= 0) ? (sc.phi % pi2) : sc.phi % pi2 + pi2,
theta = sc.theta + Math.ceil((- Math.PI - sc.theta) / pi2) * pi2;
return new SphericalCoordinate3D(sc.r, theta, phi);
}
}
/**
* 设置 天球球坐标
*
* @param {SphericalCoordinate3D} value 天球球坐标
*/
set sc(value) {
if (!(value instanceof SphericalCoordinate3D)) throw Error('The param value should be a instance of SphericalCoordinate3D.');
this.private.sc = value;
// 清空缓存
if (this.cache) this.cache.clear();
}
/**
* 获取 经度 角度对象
*
* @return {Angle} 经度 角度对象
*/
get longitude() {
return new Angle(this.sc.phi, 'r');
}
/**
* 设置 经度
*
* @param {Number} value 经度。单位:°
*/
set longitude(value) {
if (typeof(value) !== 'number') throw Error('The param value should be a Number.');
this.private.sc.phi = angle.setDegrees(value).getRadian();
// 清空缓存
if (this.cache) this.cache.clear();
}
/**
* 获取 纬度 角度对象
*
* @return {Angle} 纬度 角度对象
*/
get latitude() {
return (new Angle(Math.PI / 2 - this.sc.theta, 'r'));
}
/**
* 设置 纬度
*
* @param {Number} value 纬度。单位:°
*/
set latitude(value) {
if (typeof(value) !== 'number') throw Error('The param value should be a Number.');
this.private.sc.theta = angle.setDegrees(90 - value).getRadian();
// 清空缓存
if (this.cache) this.cache.clear();
}
/**
* 获取 距离
*
* @return {Number} 距离数值
*/
get radius() {
return this.sc.r;
}
/**
* 设置 距离
*
* @param {Number} value 距离
*/
set radius(value) {
if (typeof(value) !== 'number') throw Error('The param value should be a Number.');
if (value < 10e-8) throw Error('The param value should be greater than 10e-8.');
this.private.sc.r = value;
// 清空缓存
if (this.cache) this.cache.clear();
}
/**
* 设置 结果值的连续性
*
* @param {Boolean} value 结果值的连续性
*/
set isContinuous(value) {
this.private.isContinuous = !!value;
}
/**
* 获取 结果值连续性设定
*
* @return {Boolean} 结果值连续性设定
*/
get isContinuous() {
return this.private.isContinuous;
}
}
module.exports = CommonCoordinate;