/* 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;
}
}