xxxxxxxxxx
var sphereA;
var sphereB;
function setup() {
createCanvas( 600, 400 );
sphereA = {};
sphereA.pos = [ 120, 200 ];
sphereA.radius = 100;
sphereB = {};
sphereB.pos = [ 400, 200 ];
sphereB.radius = 100;
}
function draw() {
sphereB.pos[0] = mouseX;
sphereB.pos[1] = mouseY;
sphereB.radius = 150 + sin( frameCount * 0.03 ) * 20;
// computation of direction from sphereA center to sphereB center
var dirAB = [
sphereB.pos[0] - sphereA.pos[0],
sphereB.pos[1] - sphereA.pos[1]
];
// computation of the vecto length
var l = sqrt( pow(dirAB[0],2) + pow(dirAB[1],2) );
// and normalizing the vector
dirAB[0] /= l;
dirAB[1] /= l;
if ( l < sphereA.radius && l < sphereB.radius ) {
dirAB[0] *= -1;
dirAB[1] *= -1;
}
// computation of the angle of the direction
var angle = atan2( dirAB[1], dirAB[0] ) + PI * 0.5;
// rendering the normal of the direction
var normal = [ cos(angle), sin(angle) ];
// computation of the radius of the spheres intersection
// http://mathworld.wolfram.com/Sphere-SphereIntersection.html
var a =
( 1.0 / ( 2.0 * l ) ) *
sqrt(
( 4 * pow(l,2) * pow(sphereA.radius,2) ) -
pow( pow(l,2) - pow(sphereB.radius,2) + pow(sphereA.radius,2), 2 )
);
// computation of the distance to find the center of the intersection circle
// hypo² = basis² + opposite²
var basis_length = sqrt( pow(sphereA.radius,2) - pow(a,2) );
// absolute position of the intersection center
var middot = [
sphereA.pos[0] + dirAB[0] * basis_length,
sphereA.pos[1] + dirAB[1] * basis_length
];
// display of values
background(0);
strokeWeight( 1 );
noFill();
stroke( 255 );
ellipse( sphereA.pos[0], sphereA.pos[1], sphereA.radius * 2, sphereA.radius * 2 );
ellipse( sphereB.pos[0], sphereB.pos[1], sphereB.radius * 2, sphereB.radius * 2 );
noStroke();
fill( 255,0,0 );
ellipse( middot[0], middot[1], 5, 5 );
fill( 0,255,255 );
ellipse( middot[0] + normal[0] * a, middot[1] + normal[1] * a, 10, 10 );
strokeWeight( 2 );
stroke( 0,255,0 );
line(
sphereA.pos[0], sphereA.pos[1],
middot[0], middot[1]
);
stroke( 0,255,255 );
line(
middot[0], middot[1],
middot[0] + normal[0] * a, middot[1] + normal[1] * a
);
noStroke();
fill(255);
text( "intersection radius: " + a, 10, 25 );
}