分析太阳的绘制,对绘制赤道和其它天体有很大的启发。
太阳的定义在文件sun.js 中
function Sun() {
/**
* Determines if the sun will be shown.
*
* @type {Boolean}
* @default true
*/
this.show = true;
this._drawCommand = new DrawCommand({
primitiveType: PrimitiveType.TRIANGLES,
boundingVolume: new BoundingSphere(),
owner: this,
});
this._commands = {
drawCommand: this._drawCommand,
computeCommand: undefined,
};
this._boundingVolume = new BoundingSphere();
this._boundingVolume2D = new BoundingSphere();
this._texture = undefined;
this._drawingBufferWidth = undefined;
this._drawingBufferHeight = undefined;
this._radiusTS = undefined;
this._size = undefined;
this.glowFactor = 1.0;
this._glowFactorDirty = false;
this._useHdr = undefined;
var that = this;
this._uniformMap = {
u_texture: function () {
return that._texture;
},
u_size: function () {
return that._size;
},
};
}
在这个文件中,定义了它的_drawCommand, DrawCommand类在cesium中有举足轻重的地位,在场景中绘制的任何对象,最后都会转换为具体的DrawCommand。
sun对象的创建时机,我们跟踪代码发现在cesiumWidget的构造函数里面,创建了sun对象,并把它作为场景的一个成员。
if (skyBox !== false) {
scene.skyBox = skyBox;
scene.sun = new Sun();
scene.moon = new Moon();
}
Shader在文件sunVS.js ,需要进一步分析。
下面仿照太阳的渲染方式,我们实现了赤道平面的绘制。
太阳位置的计算,对卫星的任务分析很重要,在对地观测任务中,我们应当充分考虑太阳的照射情况。在涉及太阳位置计算时,应该弄清楚几种天球坐标系和地球坐标的概念。
天球坐标系
然后需要了解,天极、天轴等概念
我们知道,坐标轴确定了,坐标系也就确定了。 如果三个轴中的两个轴确定了,那么另外一个轴根据右手规则也相应确定了。地球质心到春分点的方向为X轴,地球自转轴指向北极的方向为Z轴正向,由于地球自转过程中,由于月球和其它因素的干扰,会产生章动现象,所有它的自转轴并不固定,看起来就像个摇摇晃晃的陀螺:
这样运动中不断变化的坐标系当然不利于描述其它天体的位置,解决方案有两个,取某一瞬时的天球三轴为坐标系,就像给运动过程在的汽车,很难讲它的精确为位置,但我可以给它拍照,以相片上汽车当时的位置为准。另一种方案,大家约定一个具体的时间,以该具体时间为准,将天球的三个轴固定下来。
上面这个划分就更细了,又增加了“改动”与“不改动”的区别。所以在碰到描述太阳位置的地方,需要仔细区别当时采用的坐标系。下面来说说地球坐标系。
地心惯性坐标系(ECI×J2000历元坐标系)
地心惯性坐标系是太阳系内的一个惯性坐标系,不随地球而转动,也不受地球、太阳运行的章动和岁差的影响。其坐标原点位于地心0e;OeX轴位于赤道平面内,指向特定某一年(历元时刻)的太阳春分点位置;Oez轴指向某一年(历元时刻)地球北极的平均位置处;Ocy轴位于赤道平面内,与0eX轴垂直,且与0cX、9ez构成满足右手定则的笛卡儿直角坐标系。由于采用的历元时间不同,可以有各种不同的地心惯性坐标系,目前国际上通用的地心惯性坐标系J2000历元坐标系,它是以公元2000年的春分点为基准的历元坐标系。
地心固定坐标系(ECF)
地心固定坐标系的坐标原点位于地心0c,Oez轴指向地球北极,Oe凭轴位于赤道平面内指向地理经度的零点,Oey轴根据右手定则确定。地心固定坐标系为笛卡尔直角坐标系,该坐标系在宇宙空间中相对地球静止,伴随地球自转和公转。
很多人弄不懂这两种坐标系的区别,其实很简单能区分, 地心地固坐标系ECF的特点是, 地球背着这个坐标系在跑.
ICRF(International Celestial Reference Frame).
ICRF坐标系为惯性坐标系(无旋转)。ICRF坐标系是目前为止最理想的惯性坐标系,对J2000坐标系进行了改进。ICRF和J2000坐标系非常接近,但并不相同。与ICRF坐标系相比,J2000坐标系随时间缓慢旋转。最新的星历大部分都在ICRF坐标系中定义。对地球固定坐标系利用算法进行转换从而得到ICRF坐标系。最新的算法使用了P03进动模型、IAU2000A章动模型(进行了调整)和地球自转角(以UT1时间的线性函数来表示),该算法始于2009年1月1日。写作该文档时(2009年1月),IERS(the International Earth rotation and Reference systems Service)没有提供这些模型的可用文档,AGI使用的是SOFA(Standards of Fundamental Astronomy)代码,这些代码可用于计算天文年历。IAU2000A章动模型和地球自转角见IERS技术文档IERS Conventions 2003,文档编号Technical Note No. 32。
(https://blog.csdn.net/stk10/article/details/103263324) 可以简单理解为, ICRF是J2000的升级版本.
ITRF坐标系
协议地球坐标系(CTS)又称为地球参考系统(ITRS),国际地球参考框架(ITRF)是ITRS的具体实现。ITRS与ITRF由地球自转与参考系统服务(IERS)组织维持与更新,通过IERS分布于全球的跟踪站的坐标和速度场来维持并提供用户使用。现已发布的ITRF系列有ITRF88、ITRF89、ITRF90、ITRF91、ITRF92、ITRF93、ITRF94、ITRF96、ITRF2000、ITRF2005、ITRF2008等全球参考框架。就是我们常说的地固坐标系,其原点在地球质心(包含大气海洋等质量),坐标系xy平面为地球赤道面,z轴指向北极CIO处,x轴指向格林威治子午线与赤道面交点处。可以简单理解为,ITRF是ECF坐标的一种。
下面我看看跟太阳位置相关的几个函数
/**
* Computes a rotation matrix to transform a point or vector from the International Celestial
* Reference Frame (GCRF/ICRF) inertial frame axes to the Earth-Fixed frame axes (ITRF)
* at a given time. This function may return undefined if the data necessary to
* do the transformation is not yet loaded.
*
* @param {JulianDate} date The time at which to compute the rotation matrix.
* @param {Matrix3} [result] The object onto which to store the result. If this parameter is
* not specified, a new instance is created and returned.
* @returns {Matrix3} The rotation matrix, or undefined if the data necessary to do the
* transformation is not yet loaded.
*
*
* @example
* scene.postUpdate.addEventListener(function(scene, time) {
* // View in ICRF.
* var icrfToFixed = Cesium.Transforms.computeIcrfToFixedMatrix(time);
* if (Cesium.defined(icrfToFixed)) {
* var offset = Cesium.Cartesian3.clone(camera.position);
* var transform = Cesium.Matrix4.fromRotationTranslation(icrfToFixed);
* camera.lookAtTransform(transform, offset);
* }
* });
*
* @see Transforms.preloadIcrfFixed
*/
Transforms.computeIcrfToFixedMatrix = function (date, result) {
//>>includeStart('debug', pragmas.debug);
if (!defined(date)) {
throw new DeveloperError("date is required.");
}
//>>includeEnd('debug');
if (!defined(result)) {
result = new Matrix3();
}
var fixedToIcrfMtx = Transforms.computeFixedToIcrfMatrix(date, result);
if (!defined(fixedToIcrfMtx)) {
return undefined;
}
return Matrix3.transpose(fixedToIcrfMtx, result);
};
上面函数的说明中,明确指出,它计算的是一个从ICRF坐标系到ITRF坐标系的变换矩阵。根据上面的概念的理解,可以认为这个函数得到的矩阵是一个从惯性系到地心地固系的转换矩阵。
function setSunAndMoonDirections(uniformState, frameState) {
if (
!defined(
Transforms.computeIcrfToFixedMatrix(frameState.time, transformMatrix)
)
) {
transformMatrix = Transforms.computeTemeToPseudoFixedMatrix(
frameState.time,
transformMatrix
);
}
var position = Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame(
frameState.time,
uniformState._sunPositionWC
);
Matrix3.multiplyByVector(transformMatrix, position, position);
Cartesian3.normalize(position, uniformState._sunDirectionWC);
position = Matrix3.multiplyByVector(
uniformState.viewRotation3D,
position,
uniformState._sunDirectionEC
);
Cartesian3.normalize(position, position);
position = Simon1994PlanetaryPositions.computeMoonPositionInEarthInertialFrame(
frameState.time,
uniformState._moonDirectionEC
);
Matrix3.multiplyByVector(transformMatrix, position, position);
Matrix3.multiplyByVector(uniformState.viewRotation3D, position, position);
Cartesian3.normalize(position, position);
var projection = frameState.mapProjection;
var ellipsoid = projection.ellipsoid;
var sunCartographic = ellipsoid.cartesianToCartographic(
uniformState._sunPositionWC,
sunCartographicScratch
);
projection.project(sunCartographic, uniformState._sunPositionColumbusView);
}
上面函数,先计算太阳在地球惯性系上的坐标,然后乘上一个矩阵,得到地心地固坐标下面的位置,具体代码如下:
var position = Simon1994PlanetaryPositions.computeSunPositionInEarthInertialFrame(
frameState.time,
uniformState._sunPositionWC
);
Matrix3.multiplyByVector(transformMatrix, position, position);
好勒,本贴就分析到此处,以后准备讨论如何在cesium上画出日照线。毕竟日照对卫星对地观测任务是一个关键因素。 累了,休息。 2021.5.3 五一快乐。