Nice!! Thank you! Processing is great by itself, but indeed the greatest thing is the community around it.
So... I think I found an expression that can generate control points for a visually acceptable bezier edge between any two points on a sphere. The code is below.
But I still can't draw an arc between the two points that's on the sphere itself; like representing the shortest path between them. I'm trying to use the "arc()" function but I still didn't manage to position both points at the XY plane at the same time to draw the arc (since the function only accepts 2d coordinates). I'm still trying so, if anyone have ideas, I'm open.
Thank you very much!!
Note: changing "debug" to "true" shows some details.
Code:
/* bezier edges on a sphere */
/* author: rafael.messias */
import processing.opengl.*;
import javax.media.opengl.*;
// main parameters
color sphereColor = color(10, 10, 10);
int sphereAlpha = 200;
int sphereRadius = 200;
boolean debug = false;
int vsize = 10;
int esize = 5;
// global variables
float cx, cy, cz;
float mx, my;
float dx, dy;
float anglex = 0, angley = 0;
float values[][] = new float[vsize][6];
float edges[][] = new float[esize][8];
void setup() {
size(600, 600, P3D);
cx = width/2;
cy = height/2;
cz = 0.0f;
float fi, theta;
for (int i = 0; i < vsize; i++) {
// nodes' random positions
fi = random(0, 360);
theta = random(0, 360);
values[i][0] = sphereRadius * sin(radians(fi)) * cos(radians(theta));
values[i][1] = sphereRadius * sin(radians(fi)) * sin(radians(theta));
values[i][2] = sphereRadius * cos(radians(fi));
}
for (int i = 0; i < esize; i++) {
// edges' random nodes
int v1 = int(random(0, vsize));
int v2 = int(random(0, vsize));
edges[i][0] = v1;
edges[i][1] = v2;
// calculating control points
float x1 = values[v1][0];
float y1 = values[v1][1];
float z1 = values[v1][2];
float x2 = values[v2][0];
float y2 = values[v2][1];
float z2 = values[v2][2];
float dist1 = dist(x1, y1, z1, x2, y2, z2);
float u = x2 - x1;
float v = y2 - y1;
float w = z2 - z1;
float t = 0.5;
float ax = (x1 + (t * u));
float ay = (y1 + (t * v));
float az = (z1 + (t * w));
float dist2 = dist(0, 0, 0, ax, ay, az);
t = (dist1 / dist2) / 1.5f; // play with this constant
float cx1 = (x1 + (t * ax));
float cy1 = (y1 + (t * ay));
float cz1 = (z1 + (t * az));
edges[i][2] = cx1;
edges[i][3] = cy1;
edges[i][4] = cz1;
float cx2 = (x2 + (t * ax));
float cy2 = (y2 + (t * ay));
float cz2 = (z2 + (t * az));
edges[i][5] = cx2;
edges[i][6] = cy2;
edges[i][7] = cz2;
}
}
void draw() {
background(0);
translate(cx, cy, cz);
rotateX(-mouseY*0.02);
rotateY(mouseX*0.02);
pushMatrix();
noStroke();
for (int i = 0; i < vsize; i++) {
pushMatrix();
fill(255, 0, 0, 255);
translate(values[i][0], values[i][1], values[i][2]);
sphere(5);
popMatrix();
}
int v1, v2;
float x1, y1, z1, x2, y2, z2;
float cx1, cy1, cz1, cx2, cy2, cz2;
for (int i = 0; i < esize; i++) {
pushMatrix();
v1 = (int) edges[i][0];
v2 = (int) edges[i][1];
x1 = values[v1][0];
y1 = values[v1][1];
z1 = values[v1][2];
x2 = values[v2][0];
y2 = values[v2][1];
z2 = values[v2][2];
cx1 = edges[i][2];
cy1 = edges[i][3];
cz1 = edges[i][4];
cx2 = edges[i][5];
cy2 = edges[i][6];
cz2 = edges[i][7];
noFill();
stroke(255, 255, 255);
bezier(x1, y1, z1, cx1, cy1, cz1, cx2, cy2, cz2, x2, y2, z2);
if (debug) {
stroke(0, 0, 255);
line(x1, y1, z1, x2, y2, z2);
float t = 0.5;
float u = x2 - x1;
float v = y2 - y1;
float w = z2 - z1;
float ax = (x1 + (t * u));
float ay = (y1 + (t * v));
float az = (z1 + (t * w));
stroke(255, 255, 0);
line(0, 0, 0, ax, ay, az);
stroke(0, 255, 0);
line(x1, y1, z1, cx1, cy1, cz1);
line(x2, y2, z2, cx2, cy2, cz2);
}
popMatrix();
}
noStroke();
fill(sphereColor, sphereAlpha);
popMatrix();
sphere(sphereRadius);
}