xxxxxxxxxx
let m;
function setup() {
createCanvas(800, 800, WEBGL);
strokeWeight(0.2);
m = createMobius();
}
function draw() {
background(220);
orbitControl(2, 1, 0.05);
ambientLight(100);
directionalLight(255, 255, 200, sin(frameCount / 30), 0, cos(frameCount / 30));
model(m);
push();
translate(-240 * sin(frameCount / 30), 0, -240 * cos(frameCount / 30));
noStroke();
emissiveMaterial(255, 255, 0);
sphere(10);
pop();
}
const spread = 0.1;
// createMobius([radius], [stripWidth], [detailX], [detailY])
function createMobius(radius = 160, stripWidth = 80, detailX = 48, detailY = 2) {
return new p5.Geometry(
detailX,
detailY,
// This needs to be an anonymous function not an arrow expression in order
// for the binding of "this" to be correct
function() {
this.gid = `mobius|${radius}|${stripWidth}|${detailX}|${detailY}`;
// create strips of vertices
// the strip actually makes two revolutions, once for triangles facing
// out, and one for triangles facing in.
const angle = 4 * PI / detailX;
const offset = -stripWidth / 2;
const interval = stripWidth / detailY;
for (let j = 0; j <= detailY; j++) {
for (let i = 0; i <= detailX; i++) {
let u = i * angle;
let v = offset + interval * j;
let x = (radius + v * Math.cos(0.5 * u)) * Math.cos(u) - Math.sin(u / 2) * 2 * spread;
let y = (radius + v * Math.cos(0.5 * u)) * Math.sin(u);
if (u < TWO_PI) {
y += Math.sin(u) * spread;
} else {
y -= Math.sin(u) * spread;
}
let z = v * Math.sin(0.5 * u) + Math.sin(u / 4) * 4 * spread;
this.vertices.push(new p5.Vector(x, y, z));
}
}
// Because our geometry is made up of strips of vertices based on detailX
// and detailY we can use computeFaces, but in order for this to work it
// is important that the number of vertices per strip be equal to
// detailX + 1 and the number of strips be equal to detailY + 1.
this.computeFaces();
this.computeNormals();
}
);
}
// save jpg
let lapse = 0; // mouse timer
function mousePressed(){
if (millis() - lapse > 400){
save("img_" + month() + '-' + day() + '_' + hour() + '-' + minute() + '-' + second() + ".jpg");
lapse = millis();
}
}