尝试在 Javascript 中从维基百科写一些数学(太阳位置计算)

Trying to write some maths from Wikipedia in Javascript (sun position computation)

我正在尝试为 threejs 项目估算太阳在 XYZ 中的位置。

我按照这里的数学计算:http://en.wikipedia.org/wiki/Position_of_the_Sun

根据以上内容,我编写了以下Javascript代码:

    var n = ((2440587.5 + (this.datemillis / 8.64E7)) - 2451545);
    var L = 280.460 + 0.9856474 * n;
    var g = 357.528 + 0.9856003 * n;
    L = (L + 360) % 360;
    g = (g + 360) % 60;
    var lambda = L + 1.915 * Math.sin(g) + 0.0020 * Math.sin(2 * g);
    var r = 1.00014 - 0.01671 * Math.cos(g) - 0.00014 * Math.cos(2 * g);
    var e = 23.439 - 0.0000004 * n;

    var x = (r * this.constants.EARTH_RADIUS * 2) * Math.cos(lambda);
    var y = (r * this.constants.EARTH_RADIUS * 2) * Math.cos(e) * Math.sin(lambda);
    var z = (r * this.constants.EARTH_RADIUS * 2) * Math.sin(e) * Math.sin(lambda);

this.datemillis 由 Javascript 日期对象的 getMillisecond 函数返回。它每帧更新一次,因此时间每 2 秒前进约 1 小时。

然而,有些事情一定是不正确的,因为这不会产生预期的结果。当我在我的 threejs 项目中将计算出的 x y z 坐标应用于我的太阳时,我可以看到太阳围绕地球旋转(位于 0,0,0)但速度非常慢(地球在几天内旋转而不是 24小时)。

我想这可能与我没有正确计算角度有关(degrees/radians?)但我数学不是很好所以我真的不知道我在做什么,也许我只是误解了维基计算。

如果有人能发现我做错的明显问题并帮助我解决这个问题,将不胜感激!

谢谢

编辑:所以我的太阳目前没有以连续的方式围绕地球旋转 - 它交替旋转 clockwise/counterclockwise 并且有时会跳跃位置...

我无法回答你的问题,但我知道这是 threejs 中已解决的问题。 Github 上关于此主题的 architecture/engineering 工作流程中有一个示例 运行。太阳位置代码在这里 https://github.com/radio412/viewer/blob/gh-pages/sun-position.js

您可以在第 108 行的 threejs 中看到它被用于定向光:https://github.com/radio412/viewer/blob/gh-pages/va3c-viewer.js

我建议从 Calculating Jday(Julian Day) in javascript

获取 Julian Date
var today = Date();
var JD = Math.floor((today / 86400000) - (today.getTimezoneOffset()/1440) + 2440587.5);

将所需的天数添加到 JD,并以所需的速度递增该值。请注意,如果每毫秒增加 1 天,您将得到每秒 1000 天,而不是每 2 秒增加 1 小时。

JD += offset;

然后继续使用维基百科食谱:

var n = JD - 2451545;

 //...

要将 Lg 放在 0-360 范围内(这里有错误)使用

L = L % 360 + ( L < 0 ? 360 : 0 );
g = g % 360 + ( g < 0 ? 360 : 0 );

维基百科公式以度数表示角度。但是 JavaScript 三角函数 cossin 需要弧度。

只需写一个 "degrees" 版本:

function cosD( deg ) {
    return Math.cos( deg * Math.PI / 180.0 );
}

function sinD( deg ) {
    return Math.sin( deg * Math.PI / 180.0 );
}

然后在后续计算中使用sinD()cosD()

var r = 1.00014 - 0.01671 * cosD(g) - 0.00014 * cosD(2 * g);
var e = 23.439 - 0.0000004 * n;

var x = (r * this.constants.EARTH_RADIUS * 2) * cosD(lambda);
var y = (r * this.constants.EARTH_RADIUS * 2) * cosD(e) * sinD(lambda);
var z = (r * this.constants.EARTH_RADIUS * 2) * sinD(e) * sinD(lambda);