162 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			162 lines
		
	
	
	
		
			3 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
let charges = [];
 | 
						|
 | 
						|
let sphere_radius = 200;
 | 
						|
 | 
						|
let physics = false;
 | 
						|
let earth = false;
 | 
						|
let skeleton = false;
 | 
						|
 | 
						|
function preload() {
 | 
						|
  earth_image = loadImage("atlas1.jpg");
 | 
						|
}
 | 
						|
 | 
						|
function setup() {
 | 
						|
  createCanvas(600, 600, WEBGL);
 | 
						|
}
 | 
						|
 | 
						|
function draw() {
 | 
						|
  orbitControl();
 | 
						|
  background(50);
 | 
						|
 | 
						|
  make_lights();
 | 
						|
  if (physics) {
 | 
						|
    move_charges(charges);
 | 
						|
  }
 | 
						|
  if (skeleton) {
 | 
						|
    draw_skeleton(sphere_radius);
 | 
						|
  }
 | 
						|
  draw_charges(sphere_radius);
 | 
						|
  draw_sphere(sphere_radius, 25);
 | 
						|
}
 | 
						|
 | 
						|
function draw_skeleton(radius) {
 | 
						|
  push();
 | 
						|
  noStroke();
 | 
						|
  fill(0xff);
 | 
						|
  sphere(4);
 | 
						|
  stroke(0xbf);
 | 
						|
  for (let charge of charges) {
 | 
						|
    line(
 | 
						|
      0,
 | 
						|
      0,
 | 
						|
      0,
 | 
						|
      charge.position.x * radius,
 | 
						|
      charge.position.y * radius,
 | 
						|
      charge.position.z * radius,
 | 
						|
    );
 | 
						|
  }
 | 
						|
  pop();
 | 
						|
}
 | 
						|
 | 
						|
function make_charges(n) {
 | 
						|
  charges = [];
 | 
						|
  for (let i = 0; i < n; i += 1) {
 | 
						|
    let position;
 | 
						|
    if (i === 0) {
 | 
						|
      position = createVector(0, -1, 0);
 | 
						|
    } else {
 | 
						|
      const lat = random(-TAU / 4, TAU / 4);
 | 
						|
      const lon = random(0, TAU);
 | 
						|
      position = createVector(
 | 
						|
        cos(lat) * cos(lon),
 | 
						|
        sin(lat),
 | 
						|
        cos(lat) * sin(lon),
 | 
						|
      );
 | 
						|
    }
 | 
						|
    charges.push({
 | 
						|
      position: position,
 | 
						|
      velocity: createVector(),
 | 
						|
      acceleration: createVector(),
 | 
						|
    });
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function draw_charges(radius) {
 | 
						|
  push();
 | 
						|
  noStroke();
 | 
						|
  ambientMaterial(0xbf, 0x00, 0x00);
 | 
						|
  for (let charge of charges.values()) {
 | 
						|
    let position = charge.position.copy();
 | 
						|
    position.mult(radius);
 | 
						|
    push();
 | 
						|
    translate(position.x, position.y, position.z);
 | 
						|
    sphere(15);
 | 
						|
    pop();
 | 
						|
  }
 | 
						|
  pop();
 | 
						|
}
 | 
						|
 | 
						|
function draw_sphere(radius, n_axis_circles) {
 | 
						|
  stroke(0x3f);
 | 
						|
  noFill();
 | 
						|
 | 
						|
  push();
 | 
						|
  rotateX(TAU / 4);
 | 
						|
  draw_circles(
 | 
						|
    radius,
 | 
						|
    earth ? 2 : n_axis_circles,
 | 
						|
    color(0x00, 0x9f, 0xff),
 | 
						|
    color(0xff, 0x9f, 0x00),
 | 
						|
  );
 | 
						|
  pop();
 | 
						|
  push();
 | 
						|
  rotateY(TAU / 4);
 | 
						|
  draw_circles(
 | 
						|
    radius,
 | 
						|
    earth ? 2 : n_axis_circles,
 | 
						|
    color(0xff, 0x00, 0xff),
 | 
						|
    color(0x00, 0xff, 0x00),
 | 
						|
  );
 | 
						|
  pop();
 | 
						|
 | 
						|
  if (earth) {
 | 
						|
    noStroke();
 | 
						|
    noFill();
 | 
						|
    tint(0xff, 0x9f);
 | 
						|
    texture(earth_image);
 | 
						|
    push();
 | 
						|
    rotateY(TAU / 4);
 | 
						|
    sphere(radius);
 | 
						|
    pop();
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
function draw_circles(radius, n_circles, pole_1_color, pole_2_color) {
 | 
						|
  push();
 | 
						|
  stroke(pole_1_color);
 | 
						|
  translate(0, 0, -radius);
 | 
						|
  point(0, 0);
 | 
						|
  pop();
 | 
						|
  for (let i = 1; i < n_circles; i += 1) {
 | 
						|
    const angle = map(i, 0, n_circles - 1, -TAU / 4, TAU / 4);
 | 
						|
    const circle_radius = radius * cos(angle);
 | 
						|
    push();
 | 
						|
    translate(0, 0, radius * sin(angle));
 | 
						|
    circle(0, 0, circle_radius * 2);
 | 
						|
    pop();
 | 
						|
  }
 | 
						|
  push();
 | 
						|
  stroke(pole_2_color);
 | 
						|
  translate(0, 0, radius);
 | 
						|
  point(0, 0);
 | 
						|
  pop();
 | 
						|
}
 | 
						|
 | 
						|
function make_lights() {
 | 
						|
  let light = createVector(0, 1, -1);
 | 
						|
  light.normalize();
 | 
						|
  directionalLight(0x1f, 0x1f, 0x1f, light);
 | 
						|
  ambientLight(0xbf);
 | 
						|
}
 | 
						|
 | 
						|
function keyPressed() {
 | 
						|
  if (key == ' ') {
 | 
						|
    physics = !physics;
 | 
						|
  } else if (key == 'd') {
 | 
						|
    earth = !earth;
 | 
						|
  } else if (key == 'f') {
 | 
						|
    skeleton = !skeleton;
 | 
						|
  } else if (key >= '0' && key <= '9') {
 | 
						|
    make_charges(int(key));
 | 
						|
  }
 | 
						|
}
 |