I’m looking for a way to draw a couple of thousands of points on the surface of a sphere. beginShape/endShape feels like an efficient way to draw them. For example as POINTS with strokeWeight(10). However, this makes them always face the camera instead of being perpendicular to the sphere. I was hoping setting the normal before the vertex would help but it seems not to.
I can think of two other ways to do it. But I was wondering if it can be done differently.
using polar coordinates: rotate(…) followed by a translate(0,0,z)
manually calculating the 4 corners of a quad perpendicular to the sphere (using crossproduct for this ?)
What do you think would be the best way to have the points perpendicular to the sphere’s surface?
Thanks for your response. I think your code is quite identical to my approach. Please see me screenshot and source code. I am already using the PVector functions you suggest. My problem is (as well as in your code) that all the dots point in the same direction (towards the screen) instead of ‘facing outwards from the center’.
And what about QUADS? I really would like to use beginShape/endShape so I can calculate my vertices up-front and render them in batch. That should be much faster than orienting and drawing thousands of circles.
I’m now trying to figure out how to calculate the 4 four corners of a quad using the cross-product. I’ll keep you posted.
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().
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);
}