Fly Me to the Moon! (and the sun, planets, and a stray spacestation)

Brain Baby

I love cosmology and astrophysics. The idea that there is something out there that is more than life on Earth astounds me. Given the opportunity to base my project on any theme, I bounced on the opportunity to explore space.

I wanted to create something that is simple to navigate and would make people fall in love with cosmology as well. I thought the easiest thing for me to do so was to create an adventure type thing where people could fly a rocketship around to visit different “landmarks” in outer space. I initially wanted to have an Arduino x Processing project where essentially I would have a rocketship that is actually a magnet or something that would close the circuit and each planet/location in the solar system would be the switch, where when the rocket lands on it, the switch would close. When this happens, depending on which object the rocket lands on, a video/animation would play.

During our class discussing, Aaron brought up the idea of having a camera that tracks the location of the rocketship. He brought up something called TUIO, which of course I had no idea what it was but was immediately drawn to it because who doesn’t love cool technology right? I, therefore, decided I wanted to learn how this tracking thing worked and so abandoned my previous idea to do this new cool thing.

Resurging Regret

A few days later, I regretted my decision. When Aaron installed the projector and camera to the ceiling, I knew that I couldn’t back out anymore. (Abdullah took a video of my expression during the exact moment I realised how hard my life was going to be for the next two weeks, it was actually really funny but for my own appearances sake, I shall not post the video here.) Thankfully, Aaron worked with me for many hours to help me figure out how projection mapping worked, and how the PS3 Eye worked, how to calibrate the camera, and essentially explained to me every bit of the code that would allow me to proceed with the actual body of my project (i.e. the easy part). It took me a while of experimenting and looking at the code that Aaron had just explained to me for me to digest what exactly I needed to do to proceed with my project.

After teaching myself some code functions that I needed to successfully use OpenCV (sending my sketch to the projection), the rest of the project was easier. Knowing exactly what I wanted to do, the next part of my project was the easiest part. Utilising the coding knowledge that I already know, I completed the first “draft” of my project which I shared in my last blog post here.

(Please read that one before reading the next part of this reflection.)

Stressful Situations

Implementing the suggestions were hard. The part about the flashing Aaron fixed in a heartbeat but man, that first suggestion about being able to explore the planets really angered me. I couldn’t figure out why putting an if statement in my already existing if statement didn’t work, and why the while function basically made my whole sketch crash. NOTHING WAS MAKING SENSE! It was until I spoke to Aaron and he told me what was wrong and wrote the first part of the code for me and everything made sense again and nothing was wrong with the world. (Really though I still don’t understand how Aaron’s brain works and functions so fast and was able to solve my problem so quickly like honestly I was stuck on that part for at least a day, no joke. Ask someone who was in the lab then.) Implementing the switch mode/cases function that Aaron taught me, I was able to improve my project by allowing people to “explore” the planets/sun as much as they wanted and then going to the main page by moving the rocket to the exit at the right top corner. I also couldn’t figure out the playing of rocketship moving music when the rocketship was moving, but Aaron also helped me with this coding part and taught me the logic behind the code.

I also managed to print a rocketship as well, however, I didn’t use it during my first user-testing experience.

In the following class, I then got more feedback on how to improve. 1) Have another exit button so that it would be easier for people to navigate, 2) Have some text on top of the animations so that people could actually learn about the solar system like I originally wanted people to do. Kristopher jokingly said to get my facts from the first paragraph of each planets’ respective Wikipedia page; however, little did he know that it was exactly what I did. Thanks for the idea Kristopher!

I decided that instead of generating text directly onto the sketch, it would be easier to generate text boxes elsewhere and put them onto the animations as images. It took me a while to adjust the positions of the text boxes and the amount of text within each box so that the words would be legible but nothing was specifically hard about this process, it just took a lot of time.

The next step – which I thought was going to be the easiest step – actually took me a long time as well. I wanted to make the rocketship as mobile as possible and not situating it on top of the breadboard with the battery pack sitting just below the rocket. I wanted it to look professional and cool and ready to blast off any second. The original idea was to use coin batteries. But after multiple hours of soldering and experimenting with it, I realised that it didn’t have enough power to power the IR LED for long. Especially because the camera was even further away in the exhibition room, it was impossible to even track the light. Therefore, I had to resort back to using 4 double A batteries.

I don’t know how I even came up with the idea but I realised that the power strip part of the breadboard could be separated from the rest of the breadboard and it fit perfectly in the body of my rocket. I realised that I just needed to attach the LED on one end while having the battery pack plugged in the other end and that was all that was needed. After almost giving up on making my rocket look somewhat pretty, this idea worked! To not expose the batteries, I decided to cover it with a layer of aluminium foil and stick fire like images on all four sides of the battery so that it would like the rocket is blasting off.

With the completion of the rocket, I WAS DONE WITH MY PROJECT! HOORAY!

I forgot to mention that during the times I got stuck on my main project, I was coding this other makeshift computer generated solar system that has a sun in the middle with planets orbiting it. But wanting to make it unorthodox,  I had planets orbit the planets. The generated solar system was what would be seen when people land on the space station. An example of a generated solar system is seen here:

Showcase Shenanigans!

On the day of the showcase, I was geared and ready to go. I was excited that other people would be able to rekindle with their elementary school astronomy days and/or learn about our solar system.

The first 20 minutes of the showcase went by fast and really well. Everything was working, people were having fun. HOWEVER, 5 mins later while a person who looked pretty important was testing out my project, MY PROJECT STOPPED WORKING. A chill literally ran through me. My computer informed me that it had run out of RAM and before I could force quit my sketch and rerun it again, it literally froze. I had to resort to restarting my laptop, which was fine except for the fact that it takes around a billion years for my sketch to load. Approximately 7 minutes later, everything was back up and running again. Phew.

Anticipating that the same situation again, I made a mental note that in 20 mins, I would restart the sketch again so that my computer wouldn’t crash. I did so and everything was fine, except that 5 mins later after the sketch restarted again, SOMEONE PICKED UP MY ROCKET AND SHOOK THE WHOLE THING. The wires, unfortunately, came loose and so in front of everyone, I had to disect my rocket and reveal the anatomy of the poor thing. Man was I stressed. Fixing took a max 10 mins, but everything worked fine again. Everything was fine again until some little kid literally took my rocket apart and pulled the wires out but ya know, everything was cool. I tried to fix it but the clock stroke 8:30 and I abandoned my mission to fix my broken rocketship.

A compilation of people playing/learning with my project is here:

Despite my computer system crashing and the breaking of my rocketship, I think that the showcase went well. I got some super amazing feedback and some really interesting constructive criticism. Reflecting now, I learned a whole lot since 14 weeks ago when I literally knew NOTHING about coding. Though the past 14 weeks have been stressful, looking back, everything was really really worthwhile.

HERE’S A REALLY BIG THANK YOU TO THOSE WHO HAVE HELPED ME ALONG THE WAY AND BEEN PATIENT WITH ME, ESPECIALLY AARON, AND WHO HAVE TOLERATED ME THROUGHOUT THE PAST 14 WEEKS BECAUSE I PROBABLY HAVE ANNOYED EVERYONE WITH MY WEEKLY LOUD “WHY ISN’T THIS WORKING?!??!”‘S IN THE LAB. On top of learning some really cool and useful coding skills, I have met some really amazing people and have found a new interest that I hope I can pursue in the future. Surviving Intro to IM is probably the greatest highlight of this school year. 🙂

Here is the code for my final project:

Mainpage –

// import json file from mappingtackedspace 
import processing.sound.*;
import gab.opencv.*;
import org.opencv.imgproc.Imgproc;
import org.opencv.core.MatOfPoint2f;
import org.opencv.core.Point;
import org.opencv.core.Size;
import org.opencv.core.Mat;
import org.opencv.core.CvType;
import processing.video.*;
import com.thomasdiewald.ps3eye.PS3EyeP5;
import java.awt.Rectangle;
import codeanticode.syphon.*;
int posX, posY;


SoundFile rocketship;
PS3EyeP5 ps3eye;
Capture video;
OpenCV opencv;
JSONObject json;
PImage warped;
PImage irImage;
int videoWidth = 640;
int videoHeight = 480;
Mat transform;
ArrayList<PVector> vectors = new ArrayList<PVector>();
int blobSizeThreshold = 1;
SyphonServer server;

PGraphics canvas;

Movie sun, mercury, venus, earth, moon, mars, jupiter, saturn, uranus, neptune;
Movie generation1, generation2, generation3;

//String[] generation = {"generation1.mov", "generation2.mov", "generation3.mov"};

PFont title;
//PFont landing;

//String message1 = "Our Solar System";

PImage bg;
PImage ex, ex2;
PImage sun1, sun2, sun3, mercury1, mercury2, venus1, venus2, venus3, earth1, earth2, earth3, moon1, moon2, mars1, mars2, jupiter1, jupiter2, saturn1, saturn2, saturn3, uranus1, uranus2, neptune1, neptune2;

//int i=3;


void setup() {

  size(640, 480, P3D);
  //size(1440, 900, P3D);
  canvas = createGraphics(640, 480, P3D);

  bg = loadImage ("solarsystembackground2.jpg");
  ex = loadImage ("x.png");
  ex2 = loadImage("x2.png");
  sun1 = loadImage("sun1.png");
  sun2 = loadImage("sun2.png");
  sun3 = loadImage("sun3.png");
  mercury1 = loadImage("mercury1.png");
  mercury2 = loadImage("mercury2.png");
  venus1 = loadImage("venus1.png");
  venus2 = loadImage("venus2.png");
  venus3 = loadImage("venus3.png");
  earth1 = loadImage("earth1.png");
  earth2 = loadImage("earth2.png");
  earth3 = loadImage("earth3.png");
  moon1 = loadImage("moon1.png");
  moon2 = loadImage("moon2.png");
  mars1 = loadImage("mars1.png");
  mars2 = loadImage("mars2.png");
  jupiter1 = loadImage("jupiter1.png");
  jupiter2 = loadImage("jupiter2.png");
  saturn1 = loadImage("saturn1.png");
  saturn2 = loadImage("saturn2.png");
  saturn3 = loadImage("saturn3.png");
  uranus1 = loadImage("uranus1.png");
  uranus2 = loadImage("uranus2.png");
  neptune1 = loadImage("neptune1.png");
  neptune2 = loadImage("neptune2.png");


  posX=posY=0;
  warped = createImage(videoWidth, videoHeight, ARGB); 
  irImage = createImage(videoWidth, videoHeight, ARGB); 
  loadData();

  ps3eye = PS3EyeP5.getDevice(this);
  ps3eye.start();
  opencv = new OpenCV(this, irImage);


  //landing = createFont("Nasalization", 25);
  //textFont(landing, 25);

  //generations = new Movie[generations.length];
  //for (int i = 0; i < generation.length; i++) {
  //generation[i] = new Movie(this, generations[i]);
  //}

  rocketship = new SoundFile(this, "rocketship_mono.wav");
  rocketship.loop();
  rocketship.amp(0.0);

  sun = new Movie(this, "sun2.mp4");
  sun.loop();

  mercury = new Movie(this, "mercury2.mp4");
  mercury.loop();

  venus = new Movie(this, "venus2.mp4");
  venus.loop();

  earth = new Movie(this, "earth2.mp4");
  earth.loop();

  moon = new Movie(this, "moon2.mp4");
  moon.loop();

  mars = new Movie(this, "mars2.mp4");
  mars.loop();

  jupiter = new Movie(this, "jupiter2.mp4");
  jupiter.loop();

  saturn = new Movie(this, "saturn2.mp4");
  saturn.loop();

  uranus = new Movie(this, "uranus2.mp4");
  uranus.loop();

  neptune = new Movie(this, "neptune2.mp4");
  neptune.loop();

  generation1 = new Movie(this, "generation3.mov");
  generation1.loop();


  server = new SyphonServer(this, "Final Start");
}

void movieEvent (Movie m) {
  m.read();
}

void draw() {
  //background(0);
  //println(mouseX, mouseY);
  canvas.beginDraw();
  canvas.background (bg);
  title = createFont("Nasalization", 20);
  canvas.textFont(title, 20);
  canvas.textAlign(CENTER);
  canvas.text("Our Solar System", 480, 30);

  cv();
  fill(255, 0, 0);
  ellipse(posX, posY, 30, 30);

  canvas.endDraw();
  image(canvas, 0, 0);
  //image(warped,0,0);
  //server.sendImage(canvas);
  server.sendScreen();
}

Computer vision page –

int curX, curY = 0;
boolean isPlaying = false;
boolean available = true;
int mode = 0;
float volume = 0;
Movie gen;


void cv() {
  if (ps3eye.isAvailable()) {
    irImage = ps3eye.getFrame();
    opencv.loadImage(irImage);
    opencv.threshold(30);
    //changes the video feed to our mapped coords

    opencv.setGray(warpPerspective(vectors, videoWidth, videoHeight));
  }

  //image(irImage,0,0);
  //image(opencv.getOutput(), 0, 0);
  //image(warped,0,0);
  noFill();
  //stroke(255, 0, 0);
  //strokeWeight(3);
  noStroke();

  int prevX = curX;
  int prevY = curY;

  curX = posX;
  curY = posY;
  //print("These are my values : ");
  //println(curX, curY);
  //print("These were my values : ");
  //println(prevX, prevY);
  //println(mouseX, mouseY);


  for (Contour contour : opencv.findContours()) {

    Rectangle r = contour.getBoundingBox();

    //if (r.width > blobSizeThreshold || r.height > blobSizeThreshold) {
    //contour.draw();

    //stroke(255, 0, 0);
    //noFill();
    //strokeWeight(2);
    //rect(r.x, r.y, r.width, r.height);
    posX=(int)r.getCenterX();
    posY=(int)r.getCenterY();
    //ellipse((float)r.getCenterX(), (float)r.getCenterY(), 5, 5);


    if (((posX >0) && (posX<107)) && ((posY>0) && (posY<159)) && available) {
      mode = 1;
      available = false;
    }
    if (((posX > 128)  && (posX<153)) && ((posY >79) && (posY<108)) && available) {
      mode = 2;
      available = false;
    }
    if (((posX > 156) && (posX < 188)) && ((posY > 85) && (posY < 126)) && available) {
      mode = 3;
      available = false;
    }
    if (((posX > 193) && (posX<229)) && ((posY>99) && (posY<146)) && available) {
      mode = 4;
      available = false;
    }
    if (((posX > 230) && (posX<242)) && ((posY>80) && (posY<95)) && available) {
      mode = 5;
      available = false;
    }
    if (((posX > 234) && (posX<272)) && ((posY>124) && (posY<165)) && available) {
      mode = 6;
      available = false;
    }
    if (((posX > 274) && (posX<382)) && ((posY>121) && (posY<249)) && available) {
      mode = 7;
      available = false;
    }
    if (((posX > 327) && (posX<518)) && ((posY>223) && (posY<314)) && available) {
      mode = 8;
      available = false;
    }
    if (((posX > 467) && (posX<535)) && ((posY>306) && (posY<379)) && available) {
      mode = 9;
      available = false;
    }
    if (((posX > 558) && (posX<612)) && ((posY>359) && (posY<425)) && available) {
      mode = 10;
      available = false;
    }
    if (((posX > 72) && (posX<119)) && ((posY>399) && (posY<450)) && available) {
      //int i = int(random(generations.length));
      mode = 11;
      available = false;
    }
    if (((posX > 590) && (posX <width) && (posY < 30)&& (posY > 0)) || ((posX < 40) && (posX > 0) && (posY > 450) && (posY < height))) { 
      mode = 0;
      available = true;
    }
  }
  switch (mode) {
  case 0:
    canvas.background(bg);
    canvas.image(bg, 0, 0, width, height);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Our Solar System", 480, 30);
    break;
  case 1:
    canvas.image(sun, 0, 0, width, height);
    canvas.image(ex, 610, 13, 20, 20);
    canvas.image(ex2, 20, 447, 20, 20);
    canvas.image(sun1, 450, 60, 165, 120);
    canvas.image(sun2, 30, 250, 160, 120);
    canvas.image(sun3, 440, 350, 180, 120);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Sun", width/2, 30);
    break;
  case 2:
    canvas.image(mercury, 0, 0, width, height);
    canvas.image(ex, 610, 15, 20, 20);
    canvas.image(ex2, 20, 447, 20, 20);
    canvas.image(mercury1, 440, 60, 180, 120);
    canvas.image(mercury2, 20, 240, 160, 120);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Mercury", width/2, 30);
    break;
  case 3:
    canvas.image(venus, 0, 0, width, height);
    canvas.image(ex, 610, 15, 20, 20);
    canvas.image(ex2, 20, 447, 20, 20);
    canvas.image(venus1, 445, 60, 160, 120);
    canvas.image(venus2, 15, 280, 160, 120);
    canvas.image(venus3, 445, 350, 180, 120);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Venus", width/2, 30);
    break;
  case 4:
    canvas.image (earth, 0, 0, width, height);
    canvas.image(ex, 610, 15, 20, 20);
    canvas.image(ex2, 20, 447, 20, 20);
    canvas.image(earth1, 485, 60, 150, 120);
    canvas.image(earth2, 13, 260, 180, 120);
    canvas.image(earth3, 470, 350, 172, 120);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Earth", width/2, 30);
    break;
  case 5:
    canvas.image(moon, 0, 0, width, height);
    canvas.image(ex, 610, 15, 20, 20);
    canvas.image(ex2, 20, 447, 20, 20);
    canvas.image(moon1, 480, 55, 157, 120);
    canvas.image(moon2, 10, 260, 180, 120);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Moon", width/2, 30);
    break;
  case 6:
    canvas.image(mars, 0, 0, width, height);
    canvas.image(ex, 610, 15, 20, 20);
    canvas.image(ex2, 20, 447, 20, 20);
    canvas.image(mars1, 440, 60, 188, 120);
    canvas.image(mars2, 45, 260, 180, 120);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Mars", width/2, 30);
    break;
  case 7:
    canvas.image(jupiter, 0, 0, width, height);
    canvas.image(ex, 610, 15, 20, 20);
    canvas.image(ex2, 20, 447, 20, 20);
    canvas.image(jupiter1, 465, 60, 170, 120);
    canvas.image(jupiter2, 25, 260, 180, 120);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Jupiter", width/2, 30);
    break;
  case 8:
    canvas.image(saturn, 0, 0, width, height);
    canvas.image(ex, 610, 15, 20, 20);
    canvas.image(ex2, 20, 447, 20, 20);
    canvas.image(saturn1, 425, 50, 210, 130);
    canvas.image(saturn3, 55, 310, 180, 110);
    canvas.image(saturn2, 405, 345, 225, 100);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Saturn", width/2, 30);
    break;
  case 9:
    canvas.image(uranus, 0, 0, width, height);
    canvas.image(ex, 610, 15, 20, 20);
    canvas.image(ex2, 20, 447, 20, 20);
    canvas.image(uranus1, 455, 60, 180, 100);
    canvas.image(uranus2, 5, 320, 200, 120);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Uranus", width/2, 30);
    break;
  case 10:
    canvas.image(neptune, 0, 0, width, height);
    canvas.image(ex, 610, 15, 20, 20);
    canvas.image(ex2, 20, 447, 20, 20);
    canvas.image(neptune1, 465, 50, 170, 140);
    canvas.image(neptune2, 40, 350, 200, 120);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Neptune", width/2, 30);
    break;
  case 11:
    canvas.image(generation1, 0, 0, width, height);
    canvas.image(ex, 610, 15, 20, 20);
    canvas.image(ex2, 20, 447, 20, 20);
    canvas.textFont(title, 20);
    canvas.textAlign(CENTER);
    canvas.text("Generated Solar System", width/2, 30);
    break;
  }
  if ((curX != prevX) && (curY != prevY) && (!isPlaying)) {
    volume+=.1;
  } else volume-=.1;
  volume = constrain(volume, 0., 1.);
  println(volume);
  rocketship.amp(volume);
}

IR tracking page –

Mat getPerspectiveTransformation(ArrayList<PVector> inputPoints, int w, int h) {
  Point[] canonicalPoints = new Point[4];
  canonicalPoints[0] = new Point(w, 0);
  canonicalPoints[1] = new Point(0, 0);
  canonicalPoints[2] = new Point(0, h);
  canonicalPoints[3] = new Point(w, h);

  MatOfPoint2f canonicalMarker = new MatOfPoint2f();
  canonicalMarker.fromArray(canonicalPoints);

  Point[] points = new Point[4];
  for (int i = 0; i < 4; i++) {
    points[i] = new Point(inputPoints.get(i).x, inputPoints.get(i).y);
  }
  MatOfPoint2f marker = new MatOfPoint2f(points);
  return Imgproc.getPerspectiveTransform(marker, canonicalMarker);
}

Mat warpPerspective(ArrayList<PVector> inputPoints, int w, int h) {
  Mat transform = getPerspectiveTransformation(inputPoints, w, h);
  Mat unWarpedMarker = new Mat(w, h, CvType.CV_8UC1);    
  Imgproc.warpPerspective(opencv.getGray(), unWarpedMarker, transform, new Size(w, h));
  return unWarpedMarker;
}

void loadData() {
  json = loadJSONObject("coords.json");
  JSONArray coordsData = json.getJSONArray("coords");
  for (int i = 0; i < coordsData.size(); i++) {
    // Get each object in the array
    JSONObject coord = coordsData.getJSONObject(i); 
    // Get a position object
    JSONObject position = coord.getJSONObject("position");
    // Get x,y from position
    int x = position.getInt("x");
    int y = position.getInt("y");
    vectors.add(new PVector(x, y, 0.0));
  }
}

 

And here is the code to make the computer generated solar system:

Mainpage –

import peasy.*;
Planet sun;

PeasyCam cam;

PImage bg;
//PImage starfield;

PImage sunTexture;
PImage[] textures = new PImage[9];

void setup() {
  //size(600, 600, P3D);
  //size (1280, 720, P3D); //starfield 2
  size (1280, 720, P3D); //starfield 1
  //fullScreen(P3D);
  
  bg = loadImage("starfield1.jpg");
  //starfield = loadImage("starfield1.jpg");

  
  sunTexture = loadImage("sun.jpg");
  textures[0] = loadImage("earth.jpg");
  textures[1] = loadImage("jupiter.jpg");
  textures[2] = loadImage("saturn.jpg");
  textures[3] = loadImage("mercury.jpg");
  textures[4] = loadImage("venus.jpg");
  textures[5] = loadImage("mars.jpg");
  textures[6] = loadImage("uranus.jpg");
  textures[7] = loadImage("neptune.jpg");
  textures[8] = loadImage("moon.jpg");
  
  cam = new PeasyCam(this, 500);
  sun = new Planet(50, 0, 0, sunTexture);
  sun.spawnMoons(5, 1);
}

void draw() {
  background(bg);
  //background(0);
  
  
  ambientLight(255,255,255);
  pointLight(255, 255, 255, 0, 0, 0);
  sun.show();
  sun.orbit();
  //image(starfield, 0, 0, width, height);


}

void keyPressed(){
  if(key==CODED&&keyCode==DOWN){
    setup();
  }
}

Planets class page –

class Planet {
  float radius;
  float distance;
  Planet[] planets;
  float angle;
  float orbitspeed;
  PVector v;

  PShape globe;

  Planet(float r, float d, float o, PImage img) {

    v = PVector.random3D();

    radius = r;
    distance = d;
    v.mult(distance);
    angle = random(TWO_PI);
    orbitspeed = o;

    noStroke();
    noFill();
    globe = createShape(SPHERE, radius);
    globe.setTexture(img);
  }

  void orbit() {
    angle = angle + orbitspeed;
    if (planets != null) {
      for (int i = 0; i < planets.length; i++) {
        planets[i].orbit();
      }
    }
  }

  void spawnMoons(int total, int level) {
    planets = new Planet[total];
    for (int i = 0; i < planets.length; i++) {
      float r = radius/(level*2.5);
      float d = random((radius*2), (radius+(r*1.5))*2.75);
      float o = random(-0.05, 0.05);
      int index = int(random(0,textures.length));
      planets[i] = new Planet(r, d, o, textures[index]);
      if (level < 2) {
        int num = int(random(0,3));
        planets[i].spawnMoons(num, level+1);
      }
    }
  }

  void show() {
    pushMatrix();
    noStroke();
    PVector v2 = new PVector(1, 0, 1);
    PVector p = v.cross(v2);
    rotate(angle, p.x, p.y, p.z);
    stroke(255);
    //line(0, 0, 0, v.x, v.y, v.z);
    //line(0, 0, 0, p.x, p.y, p.z);
    translate(v.x, v.y, v.z);
    noStroke();
    fill(255);
    shape(globe);
    //sphere(radius);
    //ellipse(0, 0, radius*2, radius*2);
    if (planets != null) {
      for (int i = 0; i < planets.length; i++) {
        planets[i].show();
      }
    }
    popMatrix();
  }
}

Here’s to the 567 lines of code that worked to create my final project!

To improve my project:

  • Move the spacestation further away from the “x” at the bottom left corner so that people don’t accidentally go over it.
  • Rather than have video animations, have images that would just loop to look like animations, perhaps this would take up less RAM and wouldn’t lead to my computer crashing.
  • Glue the rocketship to the battery so people won’t be able to pull it apart and somehow stick the wires so that it wouldn’t loosen and pop out.

Leave a Reply

Your email address will not be published. Required fields are marked *