Skip to content
Please note that GitHub no longer supports Internet Explorer.

We recommend upgrading to the latest Microsoft Edge, Google Chrome, or Firefox.

Learn more

Instantly share code, notes, and snippets.

@jn3008 jn3008/torus_updated.pde
Last active Nov 20, 2019

Embed
What would you like to do?
revisited the donut sphere gif to improve the lighting.
//by Jo
//newer version: https://dribbble.com/shots/6882529-Tori-Spheres
//original version: https://twitter.com/jn3008/status/1145009502426730498
float t, tt;
void setup() {
size(800, 600, P3D);
smooth(8);
ortho();
noStroke();
fill(255);
sphereDetail(40);
}
void draw() {
t = mouseX*1.0/width;
translate(width/2, height/2);
if (2*t<1) {
tt = 2*t;
background(20);
float pct = map(cos(TWO_PI*ease(tt, 0.8)), 1, -1, 1, 0);
lights_(100+150*pct, 150*(1-pct));
} else {
tt = 2*t-1;
background(250);
float pct = map(cos(TWO_PI*ease(tt, 0.8)), 1, -1, 1, 0);
lights_(20*pct, 40*(1-pct));
}
torus();
}
void torus() {
//torus made by revolving a circle of radius r along the circumference of a larger circle of radius R
float R = 155;
float r = R*0.4;
float R_=R*pow((R+r)/(R-r), tt);
float r_=R_*0.4;
float sphere_radius = sq(R_-r_)/(R_+r_);
donut(R_, r_);
if (2*tt > 1) //sphere appears after the donut has completed a 1/4 revolution about the x-axis
sphere(sphere_radius);
noLights();
}
void donut(float R, float r) {
int nR = 50; //number of slices on the circle R.
int nr = 50; //number of slices on the circle r. Increasing these will improve quality but run slower
for (int i = 0; i < nR; i++) {
//angles on the circle R
float a1_R = i*TWO_PI/nR;
float a2_R = (i+1)*TWO_PI/nR;
for (int j = 0; j < nr; j++) {
//angles on the circle r
float a1_r = j*TWO_PI/nr;
float a2_r = (j+1)*TWO_PI/nr;
float R1 = R-r*cos(a1_r);
float R2 = R-r*cos(a2_r);
//squares on the surface of the torus
//stroke(255, 0, 0); //un-comment this to see the squares
beginShape();
vert(R1*cos(a1_R), R1*sin(a1_R), r*sin(a1_r));
vert(R1*cos(a2_R), R1*sin(a2_R), r*sin(a1_r));
vert(R2*cos(a2_R), R2*sin(a2_R), r*sin(a2_r));
vert(R2*cos(a1_R), R2*sin(a1_R), r*sin(a2_r));
endShape(CLOSE);
}
}
}
void vert(float x, float y, float z) { //transforms and colours the vertex
PVector v = new PVector(x, y, z);
v = rotX(v, PI*ease(tt, 2)*(t>0.5?-1:1));
vertex(v.x, v.y, v.z);
}
void lights_(float C1, float C2) {
ambientLight(C1, C1, C1);
directionalLight(C2, C2, C2, 0, 0, -1);
lightFalloff(1, 0, 0);
lightSpecular(0, 0, 0);
}
float ease(float p, float g) {
if (p < 0.5)
return 0.5 * pow(2*p, g);
else
return 1 - 0.5 * pow(2*(1 - p), g);
}
float softplus(float q, float p) {
float qq = q+p;
if (qq<=0) {
return 0;
}
if (qq>=2*p) {
return qq-p;
}
return 1/(4*p)*qq*qq;
}
PVector rotY(PVector v, float th) { //matrix rotation about y-axis
return new PVector(v.x*cos(th)+v.z*sin(th), v.y, v.z*cos(th)-v.x*sin(th));
}
PVector rotX(PVector v, float th) {
return new PVector(v.x, v.y*cos(th)-v.z*sin(th), v.y*sin(th)+v.z*cos(th));
}
void push() {
pushMatrix();
pushStyle();
}
void pop() {
popStyle();
popMatrix();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.