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?
-
1$\begingroup$ blender.stackexchange.com/questions/14822/… $\endgroup$– user1853Jun 30, 2017 at 16:25
-
$\begingroup$ @cegaton Mobius Strip is a 2D object, but Mobius Ring is 3D. I am not sure making a Mobius Ring is the same as Mobius Strip. In fact, I am trying to change the orientation of a surface . And I was wondering if it is possible in Blender. $\endgroup$– user40661Jun 30, 2017 at 16:33
-
1$\begingroup$ How can I create a Mobius ring? and How to bridge edge loops with a twist of .5? $\endgroup$– DavidJun 30, 2017 at 18:41
4 Answers
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/collection_blender_script/blob/master/mobius.py
'''
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)
-
1$\begingroup$ This works nice, but I get some weird artifacts on it. $\endgroup$– dawnMar 5, 2021 at 4:00
-
$\begingroup$ Hi, can you post the parameters that resulted the artifacts, please? Or maybe a screenshot? So I can see the artifects. $\endgroup$ Mar 13, 2021 at 19:05
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.
Depending on what your final output is, it seems it is more flexible to have a ring, essentially creating an inner and outer surface.
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.
-
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$– user40661Jun 30, 2017 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$– PatdogJun 30, 2017 at 19:34
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 (for version 2.79):
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)
For blender 2.8 you will have to replace scn.objects.link
with scn.collection.objects.link
. For blender 2.9 you will have to replace the rotn *
with rotn @
because of (TypeError: Element-wise multiplication: not supported between 'Matrix' and 'Vector')
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.
With some practice you can write python to construct any mesh you like out of whatever mathematical structure you want.
-
$\begingroup$ For some reason I´m getting an error in line 21. I´m using the latest Blender version. $\endgroup$– dawnMar 5, 2021 at 4:05
This is an old question-- which makes it pretty surprising that during this time nobody ever gave a curve-based solution?
I think that curves are the easiest way to do this:
Careful: that's not a cyclic curve. That's a non-cylic curve with 5 different control points, two of which have the exact same location (and handles), but which have a twist that is offset by 180 degrees. That lets us interpolate the curve smoothly across the entire structure. In order, the tilts of the controls are 0, 45, 90, 135, 180 degrees.
I've added a weld modifier to the curve to join the end and the beginning. And I'm showing it with face orientation overlay so that you can see the normals are all pointing outwards (after giving the curve object a bevel and extrusion.)
The simplest way to make this particular object: make a bezier circle. Enter edit. Change all handles to free. Duplicate one segment of the curve. Toggle cyclic on the curve. Fill the hole created by toggling cyclic with the duplicated segment: rotate as needed; connect two coincident controls; dissolve the segment between those coincident controls. Enter tilts manually for all controls. Edit curve geometry settings as desired.
This is not a one-sided 'thin' mesh. The bevel property, generated by curve, makes it a solidified mesh, solidified about the center of the curve. Just as there is no such thing as a one-sided surface in reality (even a paper moebius strip is a volume, not a surface), one-sided surfaces in Blender or almost any other rendering engine are going to give you undesirable results (but if you want, just disable the bevel on the curve and play with it!)