Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Visualise JSON elements using some math

EDIT: I'm still not there yet. I have placed a bounty on this question because I could really do with the answer. I have made do with the idea of elements that represent the planets that don't revolve around the center. Because of this, you can skip steps 1 & 2 and go straight to 3 to try to help me out.

ORIGINAL: I am working on a fun little project. It's a solar system in which planets revolve around the sun. I consider it a simulation that's consistent of 3 big steps.

First step: create a functional revolving Solar system with the 8 planets.

Second step: create a function that adds new planets revolving around the same sun, with the click of a button with its specifics being based randomly (ie: distance from the sun, color of the planet, size of the planet, etc.)

I'm on the third step, and I don't want things to be random anymore. The third step is for me by far the hardest one for me because I have little experience with JSON. I have data from all the exoplanets beyond our solar system from the NASA website, and I want to add these individal objects (planets) into the simulation with the function that adds the objects.

My question to you is: How would my code need to look to have each individual record you see here in the JSON array in my code, as an element that's placed away from the black speck on the center of the screen (see the fiddle) in a random angle, this so it's not all aligned the same. In the end, I wish to have thousands of small specks that represent planets shown on the screen, where the black speck currently only visible, is to be the sun.

This is because there are thousands of planets like this in my JSON file, and I want to see them all revolve with their respective distance from the sun "Distance [pc]", their respective size "Planet Radius [Jupiter radii]". Of course, the science wouldn't need to be accurate, but it should somewhat be. For example, the planet with the greatest Distance [pc] (distance in parsec) needs to be the farthest away, but still be able to be seen on the screen, even if it's just a little speck.

Now I am aware that some math is involved to appropiately position each planet based on the distance property, because they are listed as distance in parsec, some conversion method would be in order to place them all on the same screen, while they're still visible.

This is my code, but not all of it. To see all of it, click the link posted under this code.

        //this is an array that holds all of the json data
           var arr=   [
                 {
                   "rowid": 1,
               "Host name": "11 Com",
               "Number of Planets in System": 1,
               "Planet Mass or M*sin(i)[Jupiter mass]": 19.4,
               "Planet Radius [Jupiter radii]": null,
               "Planet Density [g": {
                  "cm**3]": null
               },
               "Distance [pc]": 110.62,
               "Effective Temperature [K]": 4742,
               "Date of Last Update": "5/14/2014"
            },
             {
               "rowid": 2,
               "Host name": "11 UMi",
               "Number of Planets in System": 1,
               "Planet Mass or M*sin(i)[Jupiter mass]": 10.5,
               "Planet Radius [Jupiter radii]": null,
               "Planet Density [g": {
                  "cm**3]": null
               },
               "Distance [pc]": 119.47,
               "Effective Temperature [K]": 4340,
               "Date of Last Update": "5/14/2014"
            },
             {
               "rowid": 3,
               "Host name": "14 And",
               "Number of Planets in System": 1,
               "Planet Mass or M*sin(i)[Jupiter mass]": 4.8,
               "Planet Radius [Jupiter radii]": null,
               "Planet Density [g": {
                  "cm**3]": null
               },
               "Distance [pc]": 76.39,
               "Effective Temperature [K]": 4813,
               "Date of Last Update": "5/14/2014"
            },
             {
               "rowid": 4,
               "Host name": "14 Her",
               "Number of Planets in System": 1,
               "Planet Mass or M*sin(i)[Jupiter mass]": 4.64,
               "Planet Radius [Jupiter radii]": null,
               "Planet Density [g": {
                  "cm**3]": null
               },
               "Distance [pc]": 18.15,
               "Effective Temperature [K]": 5311,
               "Date of Last Update": "5/14/2014"
            }];

//these variables hold specific properties
    var distance;
    var planetRadius;
    var rowid;
    var hostName;

    for(var i=0;i<arr.length;i++){

       rowid= arr[i]["rowid"];
       distance= arr[i]["Distance [pc]"];
       hostName= arr[i]["Host name"];
       planetRadius=arr[i]["Planet Radius [Jupiter radii]"];//This is the idea how we should access the json objects, as your operations are not clear to us just I'm giving the idea
      // Do what ever you want with  individual object
           if(planetRadius !== null){
               // If planet radius not null do whatever you want.
            }
    }

This fiddle holds the essential code. Note: this link has all of the 3000+ planets in the code, so it might act up on you in terms of loading. Simply type in 1 instead of 2 in the URL to go to the draft in which there are just a few examples of hte planets, if your browser is acting up on you.

like image 425
JohnMichael Avatar asked Aug 30 '16 16:08

JohnMichael


Video Answer


1 Answers

Let me give this a try:

See this fiddle. Distance is logarithmic so that all the planets fit on the screen.

var arr=   [
     {
       "rowid": 1,
       "Host name": "11 Com",
       "Number of Planets in System": 1,
       "Planet Mass or M*sin(i)[Jupiter mass]": 19.4,
       "Planet Radius [Jupiter radii]": null,
       "Planet Density [g": {
          "cm**3]": null
       },
       "Distance [pc]": 110.62,
       "Effective Temperature [K]": 4742,
       "Date of Last Update": "5/14/2014"
    },
     {
       "rowid": 2,
       "Host name": "11 UMi",
       "Number of Planets in System": 1,
       "Planet Mass or M*sin(i)[Jupiter mass]": 10.5,
       "Planet Radius [Jupiter radii]": null,
       "Planet Density [g": {
          "cm**3]": null
       },
       "Distance [pc]": 119.47,
       "Effective Temperature [K]": 4340,
       "Date of Last Update": "5/14/2014"
    },
     {
       "rowid": 3,
       "Host name": "14 And",
       "Number of Planets in System": 1,
       "Planet Mass or M*sin(i)[Jupiter mass]": 4.8,
       "Planet Radius [Jupiter radii]": null,
       "Planet Density [g": {
          "cm**3]": null
       },
       "Distance [pc]": 76.39,
       "Effective Temperature [K]": 4813,
       "Date of Last Update": "5/14/2014"
    },
     {
       "rowid": 4,
       "Host name": "14 Her",
       "Number of Planets in System": 1,
       "Planet Mass or M*sin(i)[Jupiter mass]": 4.64,
       "Planet Radius [Jupiter radii]": null,
       "Planet Density [g": {
          "cm**3]": null
       },
       "Distance [pc]": 18.15,
       "Effective Temperature [K]": 5311,
       "Date of Last Update": "5/14/2014"
    }];
var distance;
var planetRadius;
var rowid;
var hostName;


var svg=document.getElementById("Layer_1");
for(var i=0;i<arr.length;i++){

   rowid= arr[i]["rowid"];
   distance= arr[i]["Distance [pc]"];
   hostName= arr[i]["Host name"];
   planetRadius=arr[i]["Planet Radius [Jupiter radii]"];//This is the idea how we should access the json objects, as your operations are not clear to us just I'm giving the idea
  // Do what ever you want with  individual object
       if(planetRadius !== null){
           // If planet radius not null do whatever you want.
           var circle=document.createElementNS("http://www.w3.org/2000/svg","circle");
           circle.setAttribute("class","fillblack");
           circle.setAttribute("cx","0");
           circle.setAttribute("cy","0");
           circle.setAttribute("r",planetRadius.toString());
           var logDist=Math.log(distance+1)*50;
           var angle=0; // change this based on the current time, if you would like an animation
           circle.setAttribute("transform","translate(500 300.8) rotate("+angle+") translate("+logDist+")");
           svg.appendChild(circle);
        }
}
window.requestAnimationFrame(function(){
    // do your animations here
});

If you want, you can add an animation by changing the angle variable in the transform based on the current time. SVG transforms make the math pretty simple as you can concatenate transforms.

However, I doubt that 3000+ planets can be animated at 60 fps with <svg> with current computers. If you want a smooth animation, you might want to look at <canvas>.

EDIT: It is decently smooth, but doesn't look like 60 fps to me. fiddle.

like image 141
Bernard Avatar answered Oct 05 '22 22:10

Bernard