找回密码
 注册成为果猿

QQ登录

只需一步,快速开始

微信登录

微信扫一扫,快速登录

搜索
  • 红岸基地

三体问题

三体问题

三体问题


三体问题可解吗?可否用JavaScript模拟一个三体系统?

是的,你没有听错,就是那个三体, 刘慈欣的《三体》,这篇文章就是教你怎么用JS模拟一个三体系统(绝对高大上,大刘都惊叹)。

考虑到是二维绘图,本文只考虑了在同一平面内运动的三体问题(程序演示效果见文末)

值得注意的是,三体问题本身是混沌的,受计算机浮点精度的限制,即使是细微的差别,也会导致一段时间过后天体的运动状态有极大的不同,为了尽量保证精度,在求解微分方程的过程中容差(Tolerance)也会设置得非常低,但是即便如此,也不能保证绝对精确,一旦时间线比较长,就可能会出现误差,正所谓“失之毫厘谬以千里”,看来即使是掌握了规律,未来也不见得就是可预测的啊!

所以,三体问题最终不可解

但是无解不代表不能做演示、不能对其进行最大可能的模拟预测、不能用来做果壳式高端教学


言归正传,三体问题的本质其实还是万有引力定律和牛顿第二定律,它的方程式如下:

三体问题

三体问题

由于是同一平面内,每个向量有两个维度,在考虑到降阶的问题,上述方程组可以用12个一阶ODE表达(分别代表三个天体各自单位质量上受到的力的作用):

三体问题

三体问题

实际编程中需要将极坐标转化成笛卡尔坐标来简化向量运算,以下为一些效果图:

三体问题

三体问题


三体问题

三体问题


JS部分动画就不作过多解释了,重点是ODE方程的程序化表达:

const ODE_DIM = 12;
    const TOLERANCE = 1e-12;

    class Vector2D {

        constructor(a) {
            this.a = a;
        }

        static fromPolar(radius, angle) {
            const a = new Float64Array(3);
            a[0] = radius * Math.cos(angle);
            a[1] = radius * Math.sin(angle);
            a[2] = radius;
            return new Vector2D(a);
        }

        static fromCartesian(x, y) {
            const a = new Float64Array(3);
            a[0] = x;
            a[1] = y;
            a[2] = Math.hypot(x, y);
            return new Vector2D(a);
        }

        add(v) {
            return Vector2D.fromCartesian(this.a[0] + v.a[0], this.a[1] + v.a[1]);
        }

        sub(v) {
            return Vector2D.fromCartesian(this.a[0] - v.a[0], this.a[1] - v.a[1]);
        }

        len() {
            return this.a[2];
        }

        dot(v) {
            return this.a[0] * v.a[0] + this.a[1] * v.a[1];
        }

        gravity(m) {
            const l = this.a[2];
            const k = m / (l * l * l);
            const a = new Float64Array(3);
            a[0] = this.a[0] * k;
            a[1] = this.a[1] * k;
            a[2] = this.a[2] * k;
            return new Vector2D(a);
        }

        projectOn(v) {
            return this.dot(v) / v.len();
        }

        toString() {
            return this.a.join(',');
        }

    }

    const threeBodySystem = function (m1, m2, m3) {
        const PI_2 = Math.PI / 2;
        return function (t, u) {
            const r1 = Vector2D.fromPolar(u[0], u[1]),
                r2 = Vector2D.fromPolar(u[4], u[5]),
                r3 = Vector2D.fromPolar(u[8], u[9]);
            const a1 = Vector2D.fromPolar(1, u[1] + PI_2),
                a2 = Vector2D.fromPolar(1, u[5] + PI_2),
                a3 = Vector2D.fromPolar(1, u[9] + PI_2);
            const r12 = r1.sub(r2), r23 = r2.sub(r3), r31 = r3.sub(r1);
            const F12 = r12.gravity(m1 * m2), F23 = r23.gravity(m2 * m3), F31 = r31.gravity(m3 * m1);
            const F1 = F31.sub(F12), F2 = F12.sub(F23), F3 = F23.sub(F31);
            const v = new Array(ODE_DIM);
            v[0] = u[2];
            v[1] = u[3];
            v[2] = u[0] * u[3] * u[3] + F1.projectOn(r1) / m1;
            v[3] = -(2 * u[2] * u[3] - F1.projectOn(a1) / m1) / u[0];
            v[4] = u[6];
            v[5] = u[7];
            v[6] = u[4] * u[7] * u[7] + F2.projectOn(r2) / m2;
            v[7] = -(2 * u[6] * u[7] - F2.projectOn(a2) / m2) / u[4];
            v[8] = u[10];
            v[9] = u[11];
            v[10] = u[8] * u[11] * u[11] + F3.projectOn(r3) / m3;
            v[11] = -(2 * u[10] * u[11] - F3.projectOn(a3) / m3) / u[8];
            return v;
        };
    };


三体系统演示程序演示证明三体问题不能精确求解):

三体问题

三体问题

测试链接:https://elasticdogs.com/three-body/index.html


三体人所在的三体星系拥有三个太阳
由于三体运动的混沌状态带来了三体星系气候的不稳定性
导致三体文明一次又一次的夭折在文明发展的初级阶段
在历经200多次残酷而痛苦的轮回之后终于进化到了航天时代
由于三体问题不能精确求解,最终三体行星一定会与恒星相撞……


唯有——向地球进军!





0人点赞
即便把我关在果壳中,我仍然是无限空间之王!
您需要登录后才可以回帖 登录 | 注册成为果猿 微信登录

返回顶部