I’m thinking of starting a new series where I write code for ten minutes at a time in bite sized pieces, usually to answer a question online. Welcome to the first one!
Reddit user u/doc415 asked how to draw a 3D moebius strip in Processing.
I built it in several stages so that
- I could test each step and
- I wouldn’t lose the code from one step while making the next step.
- All without having to start a git repository, etc etc.
// moebius is built around a circle. the circle has this radius.
float radius = 150;
// the strip has this thickness.
float thickness = 50;
// click a mouse button to change mode and see each step of development.
int mode=0;
void setup() {
size(500,500,P3D);
}
void mouseReleased() {
mode = (mode+1)%3;
}
void draw() {
background(0,0,0);
// move to center of screen
translate(width/2,height/2,0);
// rotate shape based on mouse movements
rotateX(mouseX*0.05f);
rotateY(mouseY*0.05f);
switch(mode) {
default: drawPointsInACircle(); break;
case 1: drawLinesAroundACircle(); break;
case 2: drawMoebiusStrip(); break;
}
}
void drawPointsInACircle() {
for(float a=0;a<360;a+=10) {
// c is unit vector from center to point on circle
float x = cos(radians(a));
float y = sin(radians(a));
float z = 0;
// color and draw
stroke(abs(x)*255f,abs(y)*255f,a*255f/360f);
point(x * radius,y * radius,z);
}
}
void drawLinesAroundACircle() {
for(float a=0;a<360;a+=10) {
// c is unit vector from center to point on circle
float cx = cos(radians(a));
float cy = sin(radians(a));
float cz = 0;
PVector c0 = new PVector(cx,cy,cz);
PVector c1 = new PVector(0,0,1);
// a unit vector along the plane of the strip
PVector d = PVector.add(
PVector.mult(c0,cos(radians(a/2))),
PVector.mult(c1,sin(radians(a/2)))
);
// scale vectors
PVector e = PVector.mult(c0,radius);
PVector f = PVector.mult(d,thickness/2f);
// put it all together
PVector p0 = PVector.add(e,f);
PVector p1 = PVector.sub(e,f);
// color and draw
stroke(abs(cx)*255f,abs(cy)*255f,a*255f/360f);
line(
p0.x,p0.y,p0.z,
p1.x,p1.y,p1.z);
}
}
void drawMoebiusStrip() {
beginShape(TRIANGLE_STRIP);
for(float a=0;a<=360;a+=10) {
// c is unit vector from center to point on circle
float cx = cos(radians(a));
float cy = sin(radians(a));
float cz = 0;
PVector c0 = new PVector(cx,cy,cz);
PVector c1 = new PVector(0,0,1);
// a unit vector along the plane of the strip
PVector d = PVector.add(
PVector.mult(c0,cos(radians(a/2))),
PVector.mult(c1,sin(radians(a/2)))
);
// scale vectors
PVector e = PVector.mult(c0,radius);
PVector f = PVector.mult(d,thickness/2f);
// put it all together
PVector p0 = PVector.add(e,f);
PVector p1 = PVector.sub(e,f);
// color and draw
stroke(255,255,255);
fill(abs(cx)*255f,abs(cy)*255f,a*255f/360f);
vertex(p0.x,p0.y,p0.z);
vertex(p1.x,p1.y,p1.z);
}
endShape();
}
Most of the work was copy/paste. Your time may vary.