Le ruban de Möbius

Le ruban de Möbius est la "surface de révolution tordue" d'un segment obtenue en faisant tourner le segment autour de son centre au même temps que de le faire tourner autour de l'axe de révolution.

Commençons par le début et dessinons d'abord le segment $[(-1,0),(1,0)]$ dans le plan:

In [1]:
line([(-1,0),(1,0)],thickness=2,aspect_ratio=1)
Out[1]:

Faisons le tourner un demi-tour autour de son centre:

In [2]:
var('phi')          # angle de rotation
def r(phi):         # matrice de rotation d'angle phi
    return matrix([[cos(phi),-sin(phi)],[sin(phi),cos(phi)]])

a=vector([-1,0]); b=vector([1,0])     # sommets du segment en vecteur pour pouvoir les multiplier par r(phi)

n=40                                  # le nombre de segments dessinés, -1

segment_tournant=[line([r(phi)*a,r(phi)*b], thickness=2) for phi in xsrange(0,pi,pi/n,include_endpoint=True)]

for g in segment_tournant: g.set_axes_range(-1.1,1.1,-1.1,1.1); g.set_aspect_ratio(1)
    
animation=animate(segment_tournant)
animation.show(delay=20)

On effectue une translation par le vecteur $(2,0)$:

In [3]:
t=vector([2,0])
segment_tournant=[line([r(phi)*a+t,r(phi)*b+t], thickness=2) for phi in xsrange(0,pi,pi/n,include_endpoint=True)]

for g in segment_tournant: g.set_axes_range(-1.1,3.1,-1.1,1.1); g.set_aspect_ratio(1)
    
animation=animate(segment_tournant)
animation.show(delay=20)

On le plonge dans $\mathbf R^3$:

In [4]:
axes=arrow3d((-3.5,0,0),(3.5,0,0),color='black',frame=False,figsize=8)+arrow3d((0,-3.5,0),(0,3.5,0),color='black')+arrow3d((0,0,-3.5),(0,0,3.5),color='black')

p=matrix([[1,0],[0,1],[0,0]])         # matrice de plongement

segment_tournant=[line([p*(r(phi)*a+t),p*(r(phi)*b+t)], thickness=2)+axes
                  for phi in xsrange(0,pi,pi/n,include_endpoint=True)]

animation=animate(segment_tournant)
animation.show(delay=20)

Puis, on fait tourner un tour complet au même temps autour de l'axe des $y$:

In [5]:
def r3d(theta):               # matrice de rotation 3d
    return matrix([[cos(theta),0,-sin(theta)],[0,1,0],[sin(theta),0,cos(theta)]])
    
segment_tournant=[line([r3d(2*phi)*(p*(r(phi)*a+t)),r3d(2*phi)*(p*(r(phi)*b+t))], thickness=2)+axes
                  for phi in xsrange(0,pi,pi/n,include_endpoint=True)]

animation=animate(segment_tournant)
animation.show(delay=20)

Ou encore en gardant les segments dessinés précédents:

In [6]:
s=axes
segment_tournant=[]
for phi in xsrange(0,pi,pi/n,include_endpoint=True):
    s+=line([r3d(2*phi)*(p*(r(phi)*a+t)),r3d(2*phi)*(p*(r(phi)*b+t))], thickness=2)
    segment_tournant.append(s)

animation=animate(segment_tournant)
animation.show(delay=20)