I’m happy now! I use the cross product to calculate a local coordinate space perpendicular to the sphere. I add all vertices in setup()
to a PShape
and only call shape(dots)
to draw them all at once in draw()
.
I hope it is useful for others.
Best wishes,
Rick
float dotRadius = 4;
float sphereRadius = 250;
PShape dots;
void setup() {
size(700, 700, P3D);
dots = createShape(GROUP);
for (int i=0; i<1000; i++) {
PVector n = PVector.random3D().mult(sphereRadius);
//create an 'up' vector. it should not point in the same direction as the the normal
PVector up = abs(n.x)<.99 ? new PVector(1, 0, 0) : new PVector(0, 1, 0);
//calculate local coordinate space using the crossproduct
PVector t = n.cross(up).normalize(); //local x axis (red)
PVector b = t.cross(n).normalize(); //local y axis (green)
//draw circle perpendicular to sphere's surface
PShape dot = createShape();
dots.setStroke(false);
dot.beginShape();
for (int j=0, jj=16; j<=jj; j++) {
float a = float(j)/jj * TWO_PI;
float x = cos(a) * dotRadius;
float y = sin(a) * dotRadius;
vertex(dot, t.copy().mult(x).add(b.copy().mult(y)).add(n)); //(t*x)+(b*y)+n
}
dot.endShape();
dots.addChild(dot);
}
}
void draw() {
background(0);
translate(width/2, height/2);
rotateX(mouseY*.01);
rotateY(mouseX*.01);
fill(0, 128, 200);
noStroke();
sphere(sphereRadius);
shape(dots);
}
void vertex(PShape s, PVector p) {
s.vertex(p.x, p.y, p.z);
}