Processing math: 100%

Sunday, 14 July 2019

Mobius strip parametrization

Recently I thought about a way to parametrize the Mobius strip embedded in 3D.

The intuition was the following:

If someone were to look "down" along the circle of the strip, they would see a circle rotating by 180 degrees.  A circle of this kind in 2D is very simply parameterized by:

xc(r,ψ)=rcos(ψ)yc(r,ψ)=rsin(ψ)

Now we need to wrap this around a circle.  This would mean that the plane the half-circle sits in should be normal to the tangent vector of the circle in 3D.

I choose to wrap my Mobius strip around the axis z with overall radius $R$.  So I have the parameterization

x=Rcos(ϕ)y=Rsin(ϕ)z=0

It's not hard to see that at every point on this circle, two basis vector for the plane normal to the tangent vector is given by:

ˆe1=(cosϕ,sinϕ,0)ˆe2=(0,0,1)

With offset
(Rcosϕ,Rsinϕ)

Together, using the equations for (xc,yc), I get the overall parametrization:

xc(r,ϕ)ˆe1(2ϕ)+yc(r,ϕ)ˆe2(2ϕ)+(Rcosϕ,Rsinϕ,0)

Using matplotlib, I have something like:



import numpy as np
from mpl_toolkits.mplot3d import Axes3D
import matplotlib.pyplot as plt
from matplotlib import interactive
import math
import matplotlib
matplotlib.use('Qt5Agg')

R = 4

def mobius(r, phi):
    x_ = r * math.cos(phi)
    e1 = np.array([math.cos(2*phi), math.sin(2*phi), 0])
    y_ = r * math.sin(phi)
    e2 = np.array([0, 0, 1])
    return x_*e1 + y_*e2 + np.array([R*math.cos(2*phi), R*math.sin(2*phi),0])


# Generate torus mesh
phi = np.linspace(-0.5*np.pi, 0.5*np.pi, 50)
r = np.linspace(-1, 1, 50)
r, phi = np.meshgrid(r, phi)
X = np.ndarray(r.shape)
Y = np.ndarray(r.shape)
Z = np.ndarray(r.shape)
for (x,y) , r_scalar in np.ndenumerate(r):
    phi_scalar = phi[x,y]
    result = mobius(r_scalar, phi_scalar)
    X[x,y] = result[0];
    Y[x,y] = result[1];
    Z[x,y] = result[2];

# Display the mesh
# plt.switch_backend('Qt5Agg')
# %matplotlib qt5
fig = plt.figure()
ax = fig.gca(projection = '3d')
ax.set_xlim3d(-5, 5)
ax.set_ylim3d(-5, 5)
ax.set_zlim3d(-1, 1)
ax.plot_surface(X, Y, Z, color = 'w', rstride = 1, cstride = 1)
plt.show()
Output looks like: