< >

solorsystem.php


Quell Code


<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>MathBox 2 - Solar System</title>
  <script src="js/index.php?js&name=mathbox-bundle.min.js"></script>
  <link rel="stylesheet" href="css/index.php?css&name=mathbox.css">
  <meta name="viewport" content="initial-scale=1, maximum-scale=1">
</head>
<body>
  <script>
  
    // Unix timestamp in seconds to (floating point) day number
    var zulu = +new Date("2080-01-19T00:00Z") / 1000;
    var dayNumber = function (t) {
      return (t - zulu) / (1800);
    };

    // Orbital elements
    // Source: http://www.stjarnhimlen.se/comp/ppcomp.html
    var orbits = {
      Sun: function (d) {
        return {
          N: 0,
          i: 0,
          w: 0,
          a: 0,
          e: 0,
          M: 0,
        };
      },
      Mercury: function (d) {
        return {
          N:  48.3313 + 3.24587E-5 * d,
          i:   7.0047 + 5.00E-8 * d,
          w:  29.1241 + 1.01444E-5 * d,
          a: 0.387098,
          e: 0.205635 + 5.59E-10 * d,
          M: 168.6562 + 4.0923344368 * d,
        };
      },
      Venus: function (d) {
        return {
          N:  76.6799 + 2.46590E-5 * d,
          i:   3.3946 + 2.75E-8 * d,
          w:  54.8910 + 1.38374E-5 * d,
          a: 0.723330,
          e: 0.006773 - 1.302E-9 * d,
          M:  48.0052 + 1.6021302244 * d,
        };
      },
      Earth: function (d) {
        return {
          N: 0.0,
          i: 0.0,
          w: 282.9404 + 4.70935E-5 * d,
          a: 1.000000,
          e: 0.016709 - 1.151E-9 * d,
          M: 356.0470 + 0.9856002585 * d,
        };
      },
      Mars: function (d) {
        return {
          N:  49.5574 + 2.11081E-5 * d,
          i:   1.8497 - 1.78E-8 * d,
          w: 286.5016 + 2.92961E-5 * d,
          a: 1.523688,
          e: 0.093405 + 2.516E-9 * d,
          M:  18.6021 + 0.5240207766 * d,
        };
      },
      Jupiter: function (d) {
        return {
          N: 100.4542 + 2.76854E-5 * d,
          i:   1.3030 - 1.557E-7 * d,
          w: 273.8777 + 1.64505E-5 * d,
          a: 5.20256,
          e: 0.048498 + 4.469E-9 * d,
          M:  19.8950 + 0.0830853001 * d,
        };
      },
      Saturn: function (d) {
        return {
          N: 113.6634 + 2.38980E-5 * d,
          i:   2.4886 - 1.081E-7 * d,
          w: 339.3939 + 2.97661E-5 * d,
          a: 9.55475,
          e: 0.055546 - 9.499E-9 * d,
          M: 316.9670 + 0.0334442282 * d,
        };
      },
      Uranus: function (d) {
        return {
          N:  74.0005 + 1.3978E-5 * d,
          i:   0.7733 + 1.9E-8 * d,
          w:  96.6612 + 3.0565E-5 * d,
          a: 19.18171 - 1.55E-8 * d,
          e: 0.047318 + 7.45E-9 * d,
          M: 142.5905 + 0.011725806 * d,
        };
      },
      Neptune: function (d) {
        return {
          N: 131.7806 + 3.0173E-5 * d,
          i:   1.7700 - 2.55E-7 * d,
          w: 272.8461 - 6.027E-6 * d,
          a: 30.05826 + 3.313E-8 * d,
          e: 0.008606 + 2.15E-9 * d,
          M: 260.2471 + 0.005995147 * d,
        };
      }
    }

    // Ecliptic heliocentric (degrees)
    // (does not include perturbations for Jupiter/Saturn/Uranus)
    var dpr   = 180/3.14;
    var sin   = function (deg) { return Math.sin(deg / dpr); };
    var cos   = function (deg) { return Math.cos(deg / dpr); };
    var atan2 = function (y, x) { return Math.atan2(y, x) * dpr; }
    var sqrt  = Math.sqrt;

    // Position iteration
    var iterate = function (E, M, e) {
      return E - (E - e * dpr * sin(E) - M) / (1 - e * cos(E));
    }

    // Emit planet position
    var planet = function (emit, key, d) {
      var orbit = orbits[key];
      var p = orbit(d);

      var E = p.M + p.e * dpr * sin(p.M) * (1 + p.e * cos(p.M));

      E = iterate(E, p.M, p.e);
      E = iterate(E, p.M, p.e);
      E = iterate(E, p.M, p.e);

      var xv = p.a * (cos(E) - p.e);
      var yv = p.a * (sqrt(1.0 - p.e * p.e) * sin(E));
      var v  = atan2(yv, xv);
      var r  = sqrt(xv * xv + yv * yv);

      var xh = r * (cos(p.N) * cos(v + p.w) - sin(p.N) * sin(v + p.w) * cos(p.i));
      var yh = r * (sin(p.N) * cos(v + p.w) + cos(p.N) * sin(v + p.w) * cos(p.i));
      var zh = r * (sin(v + p.w) * sin(p.i));

      emit(xh, yh, zh);
    };

    // Calculate orbital periods
    var periods = {};
    for (key in orbits) {
      periods[key] = Math.pow(orbits[key](0).a, 1.5);
    }

    // Load mathbox with camera controls
    var mathbox = mathBox({
      plugins: ['core', 'controls', 'cursor'],
      controls: {
        klass: THREE.OrbitControls
      },
    });
    
    mathbox.three.camera.position.set(0, 1, 3);

    // Set scale
    mathbox
      .set({
        scale: 720,
      })
    
    // Absolute time w/ controlled time travel (1 second => 1 day)
    var clock = mathbox.clock({ speed: 86400 });
    var now   = clock.now();

    // Prepare labels and colors
    var view   = now.transform({ rotation: [-?/2, 0, 0] });
    var names  = ['Sun', 'Mercury', 'Venus', 'Earth', 'Mars', 'Jupiter', 'Saturn', 'Uranus', 'Neptune'];
    var colors = [
      new THREE.Color('#ffb600'),
      new THREE.Color('#ccaa72'),
      new THREE.Color('#ffe9ba'),
      new THREE.Color('#67c8ff'),
      new THREE.Color('#f87f50'),
      new THREE.Color('#cccbb7'),
      new THREE.Color('#e6db7c'),
      new THREE.Color('#c4e7e9'),
      new THREE.Color('#8eb9f3'),
    ];

    // 360 degree orbit
    view
      .matrix({
        width:    256,
        height:   names.length,
        channels: 3,
        expr: function (emit, i, j, t) {
          var key = names[j];
          planet(emit, key, dayNumber(t) - i / 256 * 366 * periods[key]);
        },
      })
      .matrix({
        width:    1,
        height:   names.length,
        channels: 4,
        expr: function (emit, i, j) {
          emit(colors[j].r * .5, colors[j].g * .5, colors[j].b * .5, 1);
        },
      })
      .line({
        color:  '#ffffff',
        points: "<<",
        colors: "<",
        width:   3,
        depth:  .5,
      });

    // up to 1 (earth) year in the past till now
    view
      .matrix({
        width:    128,
        height:   names.length,
        channels: 3,
        expr: function (emit, i, j, t) {
          var key = names[j];
          planet(emit, key, dayNumber(t) - 365 * Math.min(1, periods[key]) * i / 128);
        },
      })
      .matrix({
        width:    128,
        height:   names.length,
        channels: 4,
        expr: function (emit, i, j) {
          var key = names[j];
          emit(colors[j].r, colors[j].g, colors[j].b, 1 - i / 128 * Math.min(1, periods[key]));
        },
      })
      .line({
        color:  '#ffffff',
        points: "<<",
        colors: "<",
        width:   5,
        depth: .5,
        zBias: 20
      });
    
    // Current position
    view
      .array({
        length: names.length,
        channels: 3,
        expr: function (emit, i, t) {
          var key = names[i];
          planet(emit, key, dayNumber(t));
        },
      })
      .array({
        id: 'colors',
        length: names.length,
        channels: 4,
        expr: function (emit, i) {
          emit(colors[i].r, colors[i].g, colors[i].b, 1);
        },
      })
      .point({
        color:  '#ffffff',
        points: '<<',
        colors: '<',
        size:   15,
        depth: .5,
        zBias: 50
      })
      .format({
        data: names
      })
      .label({
        color: '#ffffff',
        points: '<<',
        colors: '<',
        background: '#000000',
        depth: .5,
        zIndex: 1
      });

    // Date
    view
      .layer()
        .array({
          length: 1,
          data: [0, -.9, 0],
        })
        .format({
          expr: function (x, y, z, w, i, j, k, l, t) {
            var d = new Date(t * 1000);
            return [d.getFullYear(), d.getMonth() + 1, d.getDate()].join('/');
          }
        })
        .label({
          color: '#ffffff',
          background: '#000000',
          zIndex: 2
        })

  </script>
      
 
  
</body>
</html>