> show canvas only <


/* built with Studio Sketchpad: 
 *   https://sketchpad.cc
 * 
 * observe the evolution of this sketch: 
 *   https://studio.sketchpad.cc/sp/pad/view/ro.$o01q-qTb9f/rev.72
 * 
 * authors: 
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   alexsmith540
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   kr
 *   
 *   
 *   
 *   
 *   
 *   lonnen
 *   
 *   jbuck
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   
 *   

 * license (unless otherwise specified): 
 *   creative commons attribution-share alike 3.0 license.
 *   https://creativecommons.org/licenses/by-sa/3.0/ 
 */ 



/*
Solar System Model to scale
2011, Alex Smith
[email protected]
LASSSZZERSSSZZSSSSSSS!
also uploaded fullscreen with multitouch support @ 
http://8bitapp.com/solar.html
*/

/*begin pjs vars*/
int activenum = 9;
float clicked_x,clicked_y;
var camera, scene, renderer;
var sun = {name:"sun",dia:1391900};
var planets = new Array();
var solarsystem = new Object;

//SPECIAL THANKS TO http://www.exploratorium.edu/ronh/solar_system/ FOR HOOKING UP SOME DATA
var names = new Array('Mercury','Venus','Earth','Mars','Jupiter','Saturn','Uranus','Neptune','Pluto');
var bodies = new Array(4866,12106,12742,6760,142984,116438,46940,45432,2274);
var orbits = new Array(5795,10811,14857,22784,77814,142700,287030,449990,591300);//divided by 10000
var speeds = new Array(87.96,224.68,365.26,686.98,11.862*365.26,29.456*365.26,84.07*365.26,164.81*365.26,247.7*365.26);

for(int i=0;i<bodies.length;i++){
        planets.push({name:names[i],dia:bodies[i],rad:orbits[i],speed:speeds[i]});
}
solarsystem.star = sun;
solarsystem.planets = planets;

SolarSystem ss = new SolarSystem();

/*pjs time*/
void setup(){

size(1200,1200);
console.log(solarsystem);
smooth();
}
void draw(){
background(color(0,0,0));
makeButtons();
String thetext = "Scroll around like its an iPad, PCs: zoom with up/down."
text(thetext,width*0.8,height-20);
        
        ss.make();
        if(activenum !=9){
        ss.follow(activenum);
        }
        else{
        ss.nofollow();
        }
        
}
void makeButtons(){
        float perc = 0.1*width;
        int the_count = 0;
        for(int i=0;i<=width;i+=perc){
                float newperc = i+perc;
                if(the_count == activenum){fill(color(0,230,0));}
                else{
                stroke(255);
                fill(0);
                }
                rect(i,0,newperc,23);
                noFill();
                
                if(the_count<=8){
                stroke(255);
                fill(color(255,255,255));
                float tw = textWidth(names[the_count]);
                float newi = ((perc-tw)/2)+i;
                        text(names[the_count],newi,15);
                }
                
                else{
                fill(color(255,255,255));
                float tw = textWidth('off');
                float newi = ((perc-tw)/2)+i;
                        text('off',newi,15);
                }
                
                
                the_count++;
        }
        
}
void mouseClicked(){
        if(mouseY < 23){
                float buttonwid = width*0.10;
                int num = Math.floor(mouseX/buttonwid);
                ss.makeTranslation(activenum,num);
                activenum = num;
        }
        else{
                clicked_x = 0;
                clicked_y = 0;
        }
}
void mouseDragged(){
        clicked_x += mouseX-pmouseX;
        clicked_y += mouseY-pmouseY;
        ss.setBuffer(clicked_x,clicked_y);
        
}
void keyPressed(){
        if(keyCode == UP){
                console.log('up');
                        ss.zoomIn();
                }
        if(keyCode == DOWN){
                        ss.zoomOut();
                }
        
        
        
}
class SolarSystem{
        float year_speed = 365.26;
        int running_count = 0;
        int step = 0;
        int nofollowcount = 0;
        int[] fromxy, toxy;
        float nfy,nfx;
        float newx,newy; //for doTranslation
        int is_translating = 0;
        float rotation = 0;
        float the_scale = 1.0;
        float x_buffer = 0;
        float y_buffer = 0;
        float mass_multiplier = 0.00005;
        float dist_multiplier = 0.00005;
        int sundia = Math.round(solarsystem.star.dia*mass_multiplier);
        ArrayList orbits;
        SolarSystem(){
                orbits = new ArrayList;
                for(int i=0; i<solarsystem.planets.length;i++){
                        int rad = Math.round((solarsystem.planets[i].rad*1000)*dist_multiplier);
                        newCirc nc = new newCirc(rad,100+x_buffer,height/2+y_buffer-50,solarsystem.planets[i].speed);
                        ArrayList ncdata = nc.get();
                        orbits.add(ncdata);
                }
                
        }
        void multiIn(float a){
                float b = 0.05;
                the_scale += b;
        }
        void multiOut(float a){
        
                float b = 0.05;
                the_scale -= b;
        }
        void zoomIn(){
                the_scale += the_scale*1.5;
        }
        void zoomOut(){
                the_scale -= the_scale *0.5;
        }
        void setBuffer(float x, float y){
                x_buffer = the_scale <= 1.0 ? the_scale*x*2.0 : x;
                y_buffer = the_scale <= 1.0 ? the_scale*y*2.0 : y;
        }
        void makeTranslation(int activenum,int num){
                float planet_speed1 = activenum != 9 ? Math.round((solarsystem.planets[activenum].speed/year_speed)*1000) : 0;
                int frame_step1 = running_count < 1000 ? (running_count < planet_speed1 ? running_count : running_count % planet_speed1) : (running_count < planet_speed1 ? running_count : running_count % planet_speed1 );
                
                float planet_speed2 = num != 9 ? Math.round((solarsystem.planets[num].speed/year_speed)*1000) : 0;
                int frame_step2 = running_count < 1000 ? (running_count < planet_speed2 ? running_count : running_count % planet_speed2) : (running_count < planet_speed2 ? running_count : running_count % planet_speed2 );
                
                ArrayList xy1 = planet_speed1 != 0 ? orbits.get(activenum) : new ArrayList();
                int[] the_xy1 = planet_speed1 != 0 ? xy1.get(frame_step1) : new Array(0,0);
                
                ArrayList xy2 = planet_speed2 != 0 ? orbits.get(num) : new ArrayList();
                int[] the_xy2 = planet_speed2 != 0 ? xy2.get(frame_step2) : new Array(0,0);
                
                //compensate for time it takes from planet 1 to planet 2
                float dst = dist(the_xy1[0],the_xy1[1],the_xy2[0],the_xy2[1]);
                dst = Math.ceil(dst/20);
                console.log(dst);
                float planet_speed2 = num != 9 ? Math.round((solarsystem.planets[num].speed/year_speed)*1000) : 0;
                console.log(abs((running_count+dst)-1000));
                int frame_step2 = running_count+dst < 1000 ? (running_count+dst < planet_speed2 ? running_count+dst : (running_count+dst) % planet_speed2) : ((running_count+dst)-1000 < planet_speed2 ? (running_count+dst)-1000 : (running_count+dst)-1000 % planet_speed2 );
                
                ArrayList xy2 = planet_speed2 != 0 ? orbits.get(num) : new ArrayList();
                int[] the_xy2 = planet_speed2 != 0 ? xy2.get(frame_step2) : new Array(0,0);
                
                doTranslation(the_xy1,the_xy2);
        }
        void doTranslation(int[] from, int[] to){
                fromxy = from;
                toxy = to;
                newx= from[0];
                newy=from[1];
                is_translating = 1;
        }
        void follow(int planetnum){
                if(is_translating == 1){
                        if(newx < toxy[0]){
                                newx = abs(toxy[0])-abs(newx) < 20 ? toxy[0] : newx+20;
                                //newx+=20;
                                //newy++;
                                
                        }
                        else{
                                newx = abs(newx)-abs(toxy[0]) < 20 ? toxy[0] : newx-20;
                                //newx-=20;
                                //newy-=3;
                                }
                        if(newy < toxy[1]){
                                newy = abs(toxy[1])-abs(newy) < 20 ? toxy[1] : newy+20;
                                //newy+=20;
                        }
                        else{
                                newy = abs(newy)-abs(toxy[1]) < 20 ? toxy[1] : newy-20;
                                //newy-=20;
                        }
                        //float dis = solarsystem.planets[8].rad*10000;
                        //console.log(Math.floor(dist(newx,newy,toxy[0],toxy[1]))*50000*4);
                        String stuff = Math.floor(dist(newx,newy,toxy[0],toxy[1]))*50000*4+ ' miles left';
                        text(stuff,50,50);
                        scale(the_scale);
                                x_buffer = (newx*-1)+width/2;
                                y_buffer = (newy*-1);
                        
                        if(abs(newx) == abs(toxy[0]) && abs(newy) == abs(toxy[1])){
                        is_translating = 0;
                        }
                }
                else{
                float planet_speed = Math.round((solarsystem.planets[planetnum].speed/year_speed)*1000);
                int frame_step = running_count < 1000 ? (running_count < planet_speed ? running_count : running_count % planet_speed) : (running_count < planet_speed ? running_count : running_count % planet_speed );
                
                ArrayList xy = orbits.get(planetnum);
                int[] the_xy = xy.get(frame_step);
                //pushMatrix();
                        scale(the_scale);
                        x_buffer = (the_xy[0]*-1)+width/2;
                        y_buffer = (the_xy[1]*-1);
                        nfx = x_buffer;
                        nfy = y_buffer;
                        clicked_x = 0;
                        clicked_y = 0;
                        //translate(width/2+the_xy[0],height/2+the_xy[1]);
                //popMatrix();
                nofollowcount = 0;
                }//end is_translating
        }
        void nofollow(){
        if(nofollowcount == 0){
                x_buffer = 0;
                y_buffer = 0;
                nofollowcount++;
                }
        }
        void make(){
                step = step <= 1000 ? step+1 : 0;
                rotation += 0.1;
                
                noFill();
                noStroke();
                
                pushMatrix();
                noFill();
                scale(the_scale);
                translate(100+x_buffer,height/2+y_buffer);
                //suncolor
                fill(color(234,132,0));
                ellipse(0,0,sundia,sundia);
                noFill();
                popMatrix();
                
                noStroke();
                noFill();

                for(int i=0;i<solarsystem.planets.length;i++){
                float planet_speed = Math.round((solarsystem.planets[i].speed/year_speed)*1000);
                int frame_step = running_count < 1000 ? (running_count < planet_speed ? running_count : running_count % planet_speed) : (running_count < planet_speed ? running_count : running_count % planet_speed );
                        ArrayList xy = orbits.get(i);
                        int[] the_xy = xy.get(frame_step);
                        //console.log(solarsystem.planets[i]);
                        int dia = Math.round((solarsystem.planets[i].dia)*mass_multiplier);
                        int rad = Math.round((solarsystem.planets[i].rad*1000)*dist_multiplier);
                        pushMatrix();
                                scale(the_scale);
                                translate(100+x_buffer,height/2+y_buffer);
                                stroke(color(70,70,70));
                                strokeWeight(1);
                                noFill();
                                ellipse(0,0,rad*2,rad*2);
                                
                                
                        popMatrix();
                        pushMatrix();
                        scale(the_scale);
                        translate(the_xy[0]+x_buffer,the_xy[1]+height/2+y_buffer);
                        
                        fill(color(255,255,255));
                        
                        text(solarsystem.planets[i].name,45,30);
                        float tw = textWidth(solarsystem.planets[i].name)+10;
                        //fill(color(Math.round(random(0,255)),Math.round(random(0,255)),Math.round(random(0,255))));
                        stroke(color(0,255,0));
                        line(cos(20)*20,cos(20)*20,40,40);
                        line(40,40,tw+40,40);
                        noFill();
                        ellipse(0,0,dia+20,dia+20);
                        dia = dia == 0 ? 1 : dia;
                        fill(color(255,255,255));
                        stroke(color(255,255,255));
                        ellipse(0,0,dia,dia);
                        
                        //sphere(dia);
                        popMatrix();
                        //ellipse(the_xy[0],height/2+the_xy[1],30,30);
                        
                        
                }        
                running_count++;
        }
}
class newCirc{
float x, y;
float R;
ArrayList ninja = new ArrayList(); 
int the_wid;

        newCirc(float rad, float thex, float they, float speed){
        R = rad;
        x = thex;
         y = they;
        float pers=Math.round((speed/365.26)*1000);
    float sm = TWO_PI/pers;
    
 
 for(int a=0;a<pers;a++){
     float xp = x+R*cos(sm*a);
     float yp = y+R*sin(sm*a);
     int[] vals = new int[2];
     vals[0] = xp;
     vals[1] = yp; 
         ninja.add(vals);
     
     }
        
        
        }
float points(){
        return pers;
}
ArrayList get(){
        return ninja;
}
}

/*handle touch events*/
float pdist;
                document.addEventListener("touchstart", touchHandler, true);
                document.addEventListener("touchmove", touchHandler, true);
                document.addEventListener("touchend", touchHandler, true);
                document.addEventListener("touchcancel", touchHandler, true); 
                    
        function touchHandler(event)
{
                var first = event.touches[0];
                var second = event.touches[1];
         switch(event.type)
    {
        case "touchstart": 
        if(event.touches.length == 2){
                pdist = dist(first.pageX,first.pageY,second.pageX,second.pageY);
                
        }
        break;
        case "touchmove":  
        
        if(event.touches.length == 2){
                event.preventDefault();
                
                float distance = dist(first.pageX,first.pageY,second.pageX,second.pageY);
                
                if(distance > pdist){
                        
                        ss.multiIn(distance-pdist);
                }
                else{
                        
                        ss.multiOut(pdist-distance);
                }
        };
        break;        
        case "touchend":   break;
        default: return;
    }

    
}