And just found & updated the spherical version too again (done for a workshop last year). The arc shape isn't perfect by any means, but shows the principle...
Code:/**
* Arc3DSphere demo: connect random points on sphere with arcs
* @author toxi
*
* Dependencies: toxiclibscore-0018, toxiclibs_p5-0001
* (or newer, available from: http://toxiclibs.org/ )
*/
import processing.opengl.*;
import toxi.geom.*;
import toxi.processing.*;
float GLOBE_RAD=200;
ToxiclibsSupport gfx;
Sphere globe;
List arcPoints;
void setup() {
size(800,600,OPENGL);
gfx=new ToxiclibsSupport(this);
globe=new Sphere(new Vec3D(),200);
// London > Auckland
arcPoints=createNewArc(new Vec3D(GLOBE_RAD,radians(-0.15),radians(51.58)),new Vec3D(GLOBE_RAD,radians(174.77),radians(-36.84)));
// arc from London > Porto
// arcPoints=createNewArc(new Vec3D(GLOBE_RAD,radians(-0.15),radians(51.58)),new Vec3D(GLOBE_RAD,radians(-8.63),radians(41.17)));
}
void draw() {
background(255);
translate(width/2,height/2,0);
rotateX(mouseY*0.01);
rotateY(mouseX*0.01);
origin(new Vec3D(),400);
stroke(0,50);
gfx.sphere(globe);
stroke(0);
gfx.lineStrip3D(arcPoints);
}
List createNewArc(Vec3D a, Vec3D b) {
Vec3D ac=a.copy().toCartesian();
Vec3D bc=b.copy().toCartesian();
// place zenith at mid point in cartesian space
// and then transfer back into spherical to
// manipulate radius
Vec3D zenith=ac.interpolateTo(bc,0.5).toSpherical();
// add half distance to radius
// (X coord of spherical vectors = radius)
zenith.x=GLOBE_RAD+ac.distanceTo(bc)*0.5;
// define 2 further helper points @ 25%, 75%
Vec3D t1=ac.interpolateTo(bc,0.25).toSpherical();
t1.x=GLOBE_RAD+ac.distanceTo(bc)*0.15;
Vec3D t2=ac.interpolateTo(bc,0.75).toSpherical();
t2.x=GLOBE_RAD+ac.distanceTo(bc)*0.15;
// put points into spline
Spline3D s=new Spline3D();
s.add(ac);
s.add(t1.toCartesian());
s.add(zenith.toCartesian());
s.add(t2.toCartesian());
s.add(bc);
// sample curve
return s.computeVertices(20);
}
void mousePressed() {
Vec3D a=new Vec3D(globe.radius,random(-PI,PI),random(-PI,PI));
Vec3D b=new Vec3D(globe.radius,random(-PI,PI),random(-PI,PI));
arcPoints=createNewArc(a,b);
}
void origin(Vec3D o, float len) {
stroke(255, 0, 0);
line(o.x, o.y, o.z, o.x + len, o.y, o.z);
stroke(0, 255, 0);
line(o.x, o.y, o.z, o.x, o.y + len, o.z);
stroke(0, 0, 255);
line(o.x, o.y, o.z, o.x, o.y, o.z + len);
}