2
$\begingroup$

I am very new to Blender, so perhaps my question is so elementary. My background is mathematics and so as my first experimentation I would like to make a Mobius Strip. In mathematics we start with a square (rectangle ) and rotate one edge and attach it to its opposite edge. I tried to do the same (by merging the vertices) in Blender and I noticed that Blender respects the orientation (or maybe I am wrong), that is it defers between front and back sides of a plane. So I was wondering if there is another way to start from a plane and make a Mobius Strip?

$\endgroup$
2
$\begingroup$

Since I like blender's embedded python interpreter I use python code to construct any mathematical thing I dream up.

For a möbius strip I wrote http://web.purplefrog.com/~thoth/blender/python-cookbook/mobius-strip.html which I include here:

import bpy
from math import *
from mathutils import *


def mobius_mesh(resolution, major_radius, minor_radius, thick):

    verts = []
    faces = []

    for i in range(resolution):

        theta = 2*pi * i/resolution
        phi = pi * i/resolution

        rot1 = Matrix.Rotation(phi, 3, [0,1,0])
        rot2 = Matrix.Rotation(theta, 3, [0,0,1])
        c1 = Vector([major_radius, 0, 0])
        v1 = rot2*(c1 + rot1 * Vector([-thick / 2, 0, minor_radius]) )
        v2 = rot2*(c1 + rot1 * Vector([thick / 2, 0, minor_radius]) )
        v3 = rot2*(c1 + rot1 * Vector([thick / 2, 0, -minor_radius]) )
        v4 = rot2*(c1 + rot1 * Vector([-thick / 2, 0, -minor_radius]) )

        i1 = len(verts)
        verts.extend([v1,v2,v3,v4])

        if i+1<resolution:
            ia = i1+4
            ib = i1+5
            ic = i1+6
            id = i1+7
        else:
            ia = 2
            ib = 3
            ic = 0
            id = 1

        # faces.append( [i1+j for j in range(4) ])
        faces.append( [i1,i1+1,ib,ia])
        faces.append( [i1+1,i1+2,ic,ib])
        faces.append( [i1+2,i1+3,id,ic])
        faces.append( [i1+3,i1,ia,id])

    #print (verts)
    #print (faces)
    mesh = bpy.data.meshes.new("mobius")
    mesh.from_pydata(verts, [], faces)
    mesh.validate(True)

    for p in mesh.polygons:
        p.use_smooth=True

    return mesh

def mission1(scn, resolution, major_radius, minor_radius, thick):

    mesh = mobius_mesh(resolution, major_radius, minor_radius, thick)

    obj = bpy.data.objects.new("mobius strip", mesh)
    scn.objects.link(obj)

    mod = obj.modifiers.new("edge split", 'EDGE_SPLIT')


mission1(bpy.context.scene, 36, 5, 1, 0.1)

You will notice that the special case where ! (i+1<resolution) which binds the end of the strip to the start has a little twist to cope with the möbiusness. This twist would not be necessary for a torus.

mobius strip in edit mode

With some practice you can write python to construct any mesh you like out of whatever mathematical structure you want.

|improve this answer|||||
$\endgroup$
2
$\begingroup$

I tried to use Bob's script on Blender 2.80, but since a lot of stuff in the Python API changed the script doesn't work anymore.

I adapted it to the new version, you may check it here: https://github.com/ArthurHDRodrigues/mobius-strip-blender-script

'''
This is a adaptation(to run in Blender 2.80) of Bob's 
script to generate a mobius strip

You may find the original one here:
https://blender.stackexchange.com/questions/82480/how-to-make-a-mobius-strip
'''
import bpy
from math import *
from mathutils import *


def mobius_mesh(resolution, major_radius, minor_radius, thick):

    verts = []
    faces = []

    for i in range(resolution):

        theta = 2*pi * i/resolution
        phi = pi * i/resolution

        rot1 = Matrix.Rotation(phi, 3, [0,1,0])
        rot2 = Matrix.Rotation(theta, 3, [0,0,1])
        c1 = Vector([major_radius, 0, 0])

        V_0 = Vector((-thick / 2, 0, minor_radius)) @ rot1[0]
        print(V_0)
        v1 = apply(rot2,c1 +  apply(rot1,Vector((-thick / 2, 0, minor_radius))))
        v2 = apply(rot2,(c1 + apply(rot1,Vector((thick / 2, 0, minor_radius)))))
        v3 = apply(rot2,(c1 + apply(rot1,Vector((thick / 2, 0, -minor_radius)))))
        v4 = apply(rot2,(c1 + apply(rot1,Vector((-thick / 2, 0, -minor_radius)))))

        i1 = len(verts)
        verts.extend([v1,v2,v3,v4])

        if i+1<resolution:
            ia = i1+4
            ib = i1+5
            ic = i1+6
            id = i1+7
        else:
            ia = 2
            ib = 3
            ic = 0
            id = 1

        # faces.append( [i1+j for j in range(4) ])
        faces.append( [i1,i1+1,ib,ia])
        faces.append( [i1+1,i1+2,ic,ib])
        faces.append( [i1+2,i1+3,id,ic])
        faces.append( [i1+3,i1,ia,id])

    mesh = bpy.data.meshes.new("mobius")
    mesh.from_pydata(verts, [], faces)

    for p in mesh.polygons:
        p.use_smooth=True

    return mesh

def apply(matrix,vector):
    '''
    matrix,vector -> vector

    this function receives a matrix and a vector and returns
    the vector obtained by multipling both of them
    '''
    V_0 = vector @ matrix[0]
    V_1 = vector @ matrix[1]
    V_2 = vector @ matrix[2]

    return Vector((V_0,V_1,V_2))

def mission1(scn, resolution, major_radius, minor_radius, thick):

    me = mobius_mesh(resolution, major_radius, minor_radius, thick)

    ob = bpy.data.objects.new("Mesh", me)

    #me.from_pydata(vertex_list, edge_list, [])
    #me.update()
    bpy.context.collection.objects.link(ob)



mission1(bpy.context.scene, 36, 5, 3, 0.1)
|improve this answer|||||
$\endgroup$
1
$\begingroup$

The Mobius strip as a 2D object will run into the conflict with normals, and while it can be achieved geometry it will restrict usage. In the example below the solidify modifier 'breaks' at the connection.

Mobius Strip Normals

Depending on what your final output is, it seems it is more flexible to have a ring, essentially creating an inner and outer surface.

Mobius Ring Normals

In the comments to your original post there are some examples as to how to create both rings and strips, but for simplicity I have added another which involves rotating one split edge 180 degrees with proportional editing set to connected.

enter image description here

enter image description here

|improve this answer|||||
$\endgroup$
  • 1
    $\begingroup$ From your answer, I understand that we can merge two vertices only if their normals have the same direction. In other words, two vertices with opposite direction can't be merged. Is this a valid conclusion? So, mathematically speaking, we can only produce orientable 2D manifolds in Blender. $\endgroup$ – user40661 Jun 30 '17 at 19:21
  • 1
    $\begingroup$ As far as I know a vertex cannot be bi-directional. Vertices can be merged, but only one direction is chosen. $\endgroup$ – Patdog Jun 30 '17 at 19:34

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy