 # Double Möbius strip

I am currently working on a mobius strip animation based on this example: Mobius Strip Animation - #6 by glv

However, I am trying to figure out a way to increase the folds and double the strip. This is my first attempt at working with 3D, and it is a tricky entry point and the math may be beyond my skill level, but I wonder if anyone has suggestions on how to increase the folds. Here is my code:

``````let rad;
let v;
let turn = 0;
let num;

function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
colorMode(HSB, 360, 100, 100, 100);
v = width*.1
num = height*.5;
frameRate(30)
}

function draw() {
//background(40, 20, 100);
background(10);
lights();
push();
rotateY(turn);
rotateX(turn);
rotateZ(turn);
//noStroke();
turn += 0.003
pop();
}

beginShape(TRIANGLE_STRIP);
fill(0);
strokeWeight(2);
stroke(255);
for (let step = 0; step < (steps + 1); step += 1) {
let u = step * TAU / steps;
let x = (rad - v * cos(0.5 * u)) * cos(u);
let y = (rad - v * cos(0.5 * u)) * sin(u);
let z = -v * sin(0.5 * u);
vertex(x, y, z);
x = (rad + v * cos(0.5 * u)) * cos(u);
y = (rad + v * cos(0.5 * u)) * sin(u);
z = v * sin(0.5 * u);
vertex(x, y, z);
}
endShape(CLOSE);
}

for (let step = 0; step < (steps + 1); step += 1) {
fill(260, random(100), 100);
stroke(0)
let u = step * TAU / steps;
let x = (rad - v * cos(0.5 * u)) * cos(u);
let y = (rad - v * cos(0.5 * u)) * sin(u);
let z = -v * sin(0.5 * u);
push();
translate(x, y, z);
//box(10)c
box(random(6,10))
pop();
x = (rad + v * cos(0.5 * u)) * cos(u);
y = (rad + v * cos(0.5 * u)) * sin(u);
z = v * sin(0.5 * u);
push();
translate(x, y, z);
box(random(6,10))
//box(10);
pop();
}
}
````````
1 Like

To understand what is going on here you need some familiarity with trigonometry, especially the trigonometric functions sin and cos.

In the `drawTrack` and `drawEdges` functions the variable `u` represents the angle around a circle in radians. The constant `TAU` represents a complete revolution around a circle (i.e. `2 * π` radians which is equivalent to 360°). So `u` is an angle that increases incrementally depending on the number of steps.

If you were simply plotting a circle you would simply leave one dimension constant (`z = 0` for example), and you would compute the two other dimensions by multiplying the radius of the circle by either to cosine or the sine of the angle for the x and y dimensions respectively. However, since you’re drawing a strip, and it is being twisted, each edge of the strip will be offset from the edge of the circle, and you can use sine/cosine again to calculate the offset based on the twist. The thing that jumps out in the code is all of the use of `0.5 * u`. We can deduce that anywhere we see this it represents the current angle of twist (since a Mobius strip has a ½ twist). So by simply multiplying by a different value instead of `0.5` we will get a different amount of twist.

Here’s an example:

``````const DefaultTwists = 0.5;

let v;
let turn = 0;
let num;

let twistSlider;

function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
twistSlider = createSlider(0, 10, DefaultTwists, 0);
twistSlider.position(10, 10);
colorMode(HSB, 360, 100, 100, 100);
v = width * 0.1;
num = height * 0.5;
frameRate(30)
}

function draw() {
//background(40, 20, 100);
orbitControl(2, 1, 0.05);
background(10);
lights();
push();
//noStroke();
turn += 0.003
pop();
}

beginShape(TRIANGLE_STRIP);
fill(0);
strokeWeight(2);
stroke(255);
let twists = twistSlider.value();
for (let step = 0; step < (steps + 1); step += 1) {
let u = step * TAU / steps;
let x = (rad - v * cos(twists * u)) * cos(u);
let y = (rad - v * cos(twists * u)) * sin(u);
let z = -v * sin(twists * u);
vertex(x, y, z);
x = (rad + v * cos(twists * u)) * cos(u);
y = (rad + v * cos(twists * u)) * sin(u);
z = v * sin(twists * u);
vertex(x, y, z);
}
endShape(CLOSE);
}

let twists = twistSlider.value();
for (let step = 0; step < (steps + 1); step += 1) {
fill(260, random(100), 100);
stroke(0)
let u = step * TAU / steps;
let x = (rad - v * cos(twists * u)) * cos(u);
let y = (rad - v * cos(twists * u)) * sin(u);
let z = -v * sin(twists * u);
push();
translate(x, y, z);
//box(10)c
box(random(6, 10))
pop();
x = (rad + v * cos(twists * u)) * cos(u);
y = (rad + v * cos(twists * u)) * sin(u);
z = v * sin(twists * u);
push();
translate(x, y, z);
box(random(6, 10))
//box(10);
pop();
}
}
``````
1 Like

Hello,

@fleshcircuit l like what you did with it!

I modified your version and provided an example:

Double Möbius strip
``````let rad;
let v;
let turn = 0;
let num;

function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
colorMode(HSB, 360, 100, 100, 100);
v = width*.1
num = height*.5;
frameRate(30)
}

function draw() {
//background(40, 20, 100);
background(10);
lights();
push();
rotateY(turn);
rotateX(turn);
rotateZ(turn);
//noStroke();
turn += 0.003
pop();
}

beginShape(TRIANGLE_STRIP);
fill(0);
strokeWeight(2);
stroke(255);
for (let step = 0; step < (2*steps + 1); step += 1) {
let u = step * TAU / steps;

let x = (rad - v * cos(0.5 * u)) * cos(u/2);
let y = (rad - v * cos(0.5 * u)) * sin(u/2);
let z = -v * sin(0.5 * u);
vertex(x, y, z);

x = (rad + v * cos(0.5 * u)) * cos(u/2);
y = (rad + v * cos(0.5 * u)) * sin(u/2);
z = v * sin(0.5 * u);
vertex(x, y, z);
}
endShape(CLOSE);
}

for (let step = 0; step < (steps + 1); step += 1) {
fill(260, random(100), 100);
stroke(0)
let u = step * TAU / steps;
let x = (rad - v * cos(0.5 * u)) * cos(u);
let y = (rad - v * cos(0.5 * u)) * sin(u);
let z = -v * sin(0.5 * u);
push();
translate(x, y, z);
//box(10)c
box(random(6,10))
pop();
x = (rad + v * cos(0.5 * u)) * cos(u);
y = (rad + v * cos(0.5 * u)) * sin(u);
z = v * sin(0.5 * u);
push();
translate(x, y, z);
box(random(6,10))
//box(10);
pop();
}
}
``
``````

Output:

`:)`