Sphere populated with random points that are connected based on a distance threshold. Points and lines are pretty heavy in WEBGL so there is a but more code to make the points sphere and the connections low res cylinders that are rotated between two 3D points/vectors. Link to source files.
let numPts = 300;
let pts = [];
///camera varibles
let oldx;
let oldy;
let rotx = 0;
let roty = 0;
let zcam = -600;
function setup(){
createCanvas(800, 800, WEBGL);
oldx = mouseX;
oldy = mouseY;
stroke(40, 166);
strokeWeight(4.0);
for(let i = 0; i < numPts; i++){
append(pts,new spherePt(600));
}
}
function draw(){
background(0);
cam();
for(let i = 0; i < pts.length; i++){
let pt = pts[i];
for(let j = 0; j < pts.length; j++){
let pt2 = pts[j];
let dd = dist(pt.p.x,pt.p.y,pt.p.z,pt2.p.x,pt2.p.y,pt2.p.z);
if(dd < 150){
//strokeWeight(1);
//stroke(255);
//line(pt.p.x,pt.p.y,pt.p.z,pt2.p.x,pt2.p.y,pt2.p.z);
let heading = createVector(pt2.p.x-pt.p.x, pt2.p.y-pt.p.y,pt2.p.z-pt.p.z);
//line(p1.x, p1.y, p1.z, p2.x, p2.y, p2.z);
let midPoint = pt.p.copy().add(pt2.p).mult(0.5);
let currentDirection = createVector(0, 1, 0);
let newDirection = pt2.p.copy().sub(pt.p).normalize();
let rotationAxis = currentDirection.cross(newDirection).normalize();
let rotationAngle = acos(currentDirection.dot(newDirection));
push();
translate(pt.p.x,pt.p.y,pt.p.z);
rotate(rotationAngle, rotationAxis);
translate(0,dd/2,0);
fill(pt.c);
noStroke();
cylinder(1,dd);
pop();
}
}
pt.display();
}
rotx += 0.005;
}
class spherePt {
constructor(rad) {
this.r = rad;
this.rotd = random(-0.01,0.01);
this.raxis = createVector(random(1),random(1),random(1));
let a=0, b=0, c=0, d=0, k=99;
while (k >= 1.0) {
a = random (-1.0, 1.0);
b = random (-1.0, 1.0);
c = random (-1.0, 1.0);
d = random (-1.0, 1.0);
k = a*a +b*b +c*c +d*d;
}
k = k / this.r;
this.p = createVector(2*(b*d+a*c)/k,2*(c*d-a*b)/k,(a*a + d*d - b*b - c*c) / k);
this.c = color(random(255),random(255),random(255));
}
display(){
push();
noStroke();
fill(this.c);
translate(this.p.x,this.p.y,this.p.z);
sphere(5,3,3);
pop();
this.p = rotateAround(this.p,createVector(0,0,1),this.rotd);
}
}
function rotateAround(vect, axis, angle) {
// Make sure our axis is a unit vector
axis = p5.Vector.normalize(axis);
return p5.Vector.add(
p5.Vector.mult(vect, cos(angle)),
p5.Vector.add(
p5.Vector.mult(
p5.Vector.cross(axis, vect),
sin(angle)
),
p5.Vector.mult(
p5.Vector.mult(
axis,
p5.Vector.dot(axis, vect)
),
(1 - cos(angle))
)
)
);
}
///camera functions
function cam() {
let newx = mouseX;
let newy = mouseY;
translate(0, 0,zcam);
rotateY(rotx); rotateX(roty);
if (mouseIsPressed == true) {
rotx = rotx + (oldx-newx)/50.0;
roty = roty + (oldy-newy)/50.0;
}
oldx = newx;
oldy = newy;
}
function mouseWheel(event) {
let e = event.delta;
zcam = zcam - e*1;
}