xxxxxxxxxx
142
let vec_origin, vec_result;
let polar_angle = 0;
let azimuth_angle = 0;
let delta_angle = 0;
let fsRadius = 50;
let msRadius = 30;
function setup() {
createCanvas(600, 600, WEBGL);
ortho(-width / 2, width / 2, -height / 2, height / 2, 0, 900);
vec_origin = createVector(0, 0, 0);
}
function draw() {
background(255);
scale(3);
strokeWeight(1);
noFill();
line(-width / 2, 0, width / 2, 0);
line(0, -height / 2, 0, 0, height / 2, 0);
line(0, 0, 300, 0, 0, -300);
// Draw stationary sphere with coordinate centre highlighted
sphere(2);
strokeWeight(0.3);
sphere(fsRadius);
// Draw moving sphere
tangentSphere();
// ################################################################
// Draw two shapes relative to moving sphere
// Over right red spot
otherShapeCartesian(msRadius, 0, 0);
// Hovering above left red spot
otherShapePolar(PI / 2, (3 * PI) / 2, msRadius + 10);
// ################################################################
}
function tangentSphere() {
push();
vec_result = p5.Vector.fromAngles(polar_angle, azimuth_angle, fsRadius);
strokeWeight(3);
stroke("yellow");
line(
vec_origin.x,
vec_origin.y,
vec_origin.z,
vec_result.x,
vec_result.y,
vec_result.z
);
// Draw centre location for moving sphere
fill(vec_result.z < 0 ? 180 : 0);
stroke(vec_result.z < 0 ? 180 : 0);
// Move and rotate the drawing coordinates for the moving sphere
translate(vec_result.x, vec_result.y, vec_result.z);
rotateY(azimuth_angle);
rotateX(-polar_angle);
rotateY(delta_angle);
drawCoordinateAxesForMovingSphere();
// draw moving sphere
fill(vec_result.z < 0 ? 180 : 0);
noFill();
stroke(vec_result.z < 0 ? 180 : 0);
strokeWeight(0.8);
sphere(msRadius);
// red points on sides of the sphere
push();
noStroke();
fill("red");
translate(-msRadius, 0, 0); // Polar 90 : azimuth 270
sphere(2);
translate(2 * msRadius, 0, 0); // Polar 90 : azimuth 90
sphere(2);
pop();
pop();
}
// This will draw the X (red), Y (green) and Z (blue)
// coordinate axis for the current translation and rotation
function drawCoordinateAxesForMovingSphere() {
push();
strokeWeight(3);
stroke("red");
line(0, 0, 0, 100, 0, 0); // X axis
stroke("green");
line(0, 0, 0, 0, 100, 0); // Y axis
stroke("blue");
line(0, 0, 0, 0, 0, 100); // Z axis
pop();
}
// Given a [x, y, z] position in the coordinate system of the moving sphere
function otherShapeCartesian(x, y, z) {
push();
// Translate translate to moving sphere coordinates
translate(vec_result.x, vec_result.y, vec_result.z);
rotateY(azimuth_angle);
rotateX(-polar_angle);
rotateY(delta_angle);
// Now translate to cartesian position of other shape
translate(x, y, z);
fill(255, 0, 255, 40);
stroke("purple");
strokeWeight(2);
box(8);
pop();
}
function otherShapePolar(pa, aa, mag) {
let pc = cartesionPosition(pa, aa, mag);
otherShapeCartesian(pc.x, pc.y, pc.z);
}
// Get cartesian coordinates from polar coordinates
function cartesionPosition(polar_angle, azimuth_angle, magnitude) {
let z = -magnitude * sin(polar_angle) * cos(azimuth_angle);
let x = magnitude * sin(polar_angle) * sin(azimuth_angle);
let y = -magnitude * cos(polar_angle);
return createVector(x, y, z);
}
// Get polar coordinates from cartesian coordinates
// Although this function is not used I would keep it just in case :-)
function polarPosition(x, y, z) {
let magnitude = sqrt(x * x + y * y + z * z);
x /= magnitude;
y /= -magnitude; // y = cos(pa)
z /= -magnitude;
return createVector(acos(y), atan2(x, z), magnitude);
}
function mouseDragged() {
let x_drag_amount = (mouseX - pmouseX) * 0.004;
let y_drag_amount = (mouseY - pmouseY) * 0.004;
polar_angle += y_drag_amount;
azimuth_angle += x_drag_amount;
}