set parametric # 媒介変数モード set urange[0:2*pi] # uの範囲を設定 set vrange[0:2*pi] # vの範囲を設定 set ticslevel 0 set hidden3d set isosample 50 set view equal xyz splot cos(u/2.0)*cos(v),sin(u/2.0)*cos(v),sin(v) w lこのようなものを3Dモデルとして出力したいということで、 pythonで(u, v)の関数をSTL形式にして出力するスクリプトを書いてみました。 ほかの言語で書き換えて遊ぶのにも、ちょうどよい内容と長さかと思います。
import math
def Sphere(u, v):
x = math.cos(u/2.0)*math.cos(v)
y = math.sin(u/2.0)*math.cos(v)
z = math.sin(v)
return x, y, z
def VectorSub(v1, v2):
return [e1-e2 for e1, e2 in zip(v1, v2)]
def VectorDiv(v, a):
return [e/a for e in v]
def VectorCross(v1, v2):
x1, y1, z1 = v1
x2, y2, z2 = v2
return [y1*z2-z1*y2, z1*x2-x1*z2, x1*y2-y1*x2]
def VectorAbs(v):
return math.sqrt(sum([e**2 for e in v]))
def NormalVector(p1, p2, p3):
v1 = VectorSub(p2, p1)
v2 = VectorSub(p3, p2)
vc = VectorCross(v1, v2)
a = VectorAbs(vc)
v = VectorDiv(vc, a) if a!=0.0 else False
return v
def STLfacet(apolygon, inverse=False):
if inverse:
points = apolygon[::-1]
else:
points = apolygon[:]
nv = NormalVector(*points)
if not nv:
return ""
l = "facet normal %g %g %g\n" % tuple(nv)
l = l + "outer loop\n"
for p in points:
l = l + "vertex %g %g %g\n" % tuple(p)
l = l + "endloop\n"
l = l + "endfacet\n"
return l
def PolygonsToSTL(name, polygons, inverse=False):
l = "solid %s\n" % name
for p in polygons:
l = l + STLfacet(p, inverse)
l = l+"endsolid\n"
return l
def Polygons_of_Function_UV(func):
nu = 90
nv = 90
du = 2.0 * math.pi / nu
dv = 2.0 * math.pi / nv
u = [du * i for i in range(nu+1)]
v = [dv * i for i in range(nv+1)]
polygons = []
for i in range(nu):
for j in range(nv):
p1 = func(u[i], v[j])
p2 = func(u[i+1], v[j])
p3 = func(u[i+1], v[j+1])
p4 = func(u[i], v[j+1])
polygons.append((p1, p2, p4))
polygons.append((p4, p2, p3))
return polygons
def OutputSTL(name, polygons):
with open('%s.stl' % name, "w") as fp:
fp.write(PolygonsToSTL(name, polygons, False))
if __name__ == '__main__':
OutputSTL("Sphere", Polygons_of_Function_UV(Sphere))
出力されたSTLデータを見るには、GLC Playerが便利ですね。また、Windows10には、3D Builderがついているので、そのままでSTLデータを見ることができます。GLC Playerでスナップショットを取ったものが下の図です。
関数を次のものにしてみます。
def Dounut(u, v):
x = math.cos(u)*(1+0.5*math.cos(v))
y = math.sin(u)*(1+0.5*math.cos(v))
z = 0.5*math.sin(v)
return x, y, z
ドーナツの形になりました。
def Helical(u, v):
n = 10.0
a = 0.6
b = 0.3
rm = (lambda v: a*b/math.sqrt(b*b*math.cos(v)**2 + a*a*math.sin(v)**2))
r = (lambda u, v: 1 + rm(v)*math.cos(v+n*u/2.0))
x = r(u, v) * math.cos(u)
y = r(u, v) * math.sin(u)
z = rm(v) * math.sin(v + n*u/2.0)
return x, y, z
楕円をぐるぐる回転させていくと、ねじれた形状になりました。




1 件のコメント:
このプログラムやった見たけと働かないですね。何かフィードバックを与えることができますか?
コメントを投稿