日常の進捗

主に自分のための,行為とその習慣化の記録

Mod:Coding Challenge #8: Solar System in Processing - Part 2 (3D)

3D版はPeasyCamという3Dの視点移動のライブラリが使われてたりして改変しづらい。OpenProcessingだと動作しないし。仕方ないのでGIF貼る。

via GIPHY

import peasy.*;
import peasy.org.apache.commons.math.*;
import peasy.org.apache.commons.math.geometry.*;

Planet sun;
PeasyCam cam;

// setup関数 : 初回1度だけ実行される
void setup() {
  size(960, 540, P3D); // ウィンドウサイズを960px,540pxに
  colorMode(HSB, 360, 100, 100, 100); // HSBでの色指定にする
  cam = new PeasyCam(this, 500);
  sun = new Planet(100, 0, 0);
  sun.spawnMoons(10, 1);
}

// draw関数 : setup関数実行後繰り返し実行される
void draw() {
  background(0, 0, 0);
  lights();
  sun.draw();
  sun.orbit();
}

class Planet {
  float radius;
  float distance;
  Planet[] planets;
  float angle;
  float orbitSpeed;
  PVector v;
  PShape grobe;
  color c;

  Planet(float r, float _d, float o) {
    v = PVector.random3D();
    radius = r;
    angle = random(TWO_PI);
    distance  = _d;
    v.mult(distance);
    orbitSpeed = o;
    c = color(random(360),80,100);
  }

  void spawnMoons(int total, int level) {
    planets = new Planet[total];
    for (int i = 0; i < planets.length; i++) {
      float r = radius/(level*2);
      float d = random((radius + r), (radius+r)*4);
      float o = random(-0.01, 0.01);
      planets[i] = new Planet(r, d, o);
      if (level < 2) {
        int num = int(random(0, 3));
        planets[i].spawnMoons(num, level+1);
      }
    }
  }
  void orbit() {
    angle = angle + orbitSpeed;
    if (planets != null) {
      for (int i = 0; i < planets.length; i++) {
        planets[i].orbit();
      }
    }
  }

  void draw() {
    pushMatrix();
    PVector v2 = new PVector(1, 0, 1);
    PVector p = v.cross(v2);
    rotate(angle, p.x, p.y, p.z);
    translate(v.x, v.y, v.z);
    noStroke();
    fill(c);
    sphere(radius);
    if (planets != null) {
      for (int i = 0; i < planets.length; i++) {
        planets[i].draw();
      }
    }
    popMatrix();
  }
}