G-coordinator python g-codeプログラミング example解説 – lamp_shade.py -

pythonを書いてg-codeを出力するためには、まずはexampleのサンプルコードを理解するのが重要かと思います。
前回の基本編で説明しましたが、G-coordinatorには、しっかりとしたexampleコードがありますので、サンプルコードを眺めていきましょう。

今回説明するのは、lamp_shade.pyになります。

サンプルコードをブロック毎に確認します。

import numpy as np
import gcoordinator as gc

最初は、必ず必要になるnumpyとgoordinatorをインポートします。(mathが必要になるケースもあります)
numpyは数式を扱うのに必要なライブラリーです。sinやcosは必ず出てきますので、必要になります。
gcoordinatorはg-codeを出力するためのライブラリです。
それぞれ、npとgcと定義し、頭にnp.とかgc.で各関数をロードできるようになります。(例 np.pi πの180degを使う、gc.gui_export()など)

LAYER = 400

def rotation_calc(height):
    rad = np.sqrt(50**2 - (height * 0.2-35)**2)
    return height*0.004

def print_polar(arg, rad, height):
    rotation = rotation_calc(height)
    x = rad*np.cos(arg + rotation)
    y = rad*np.sin(arg + rotation)
    z = np.full_like(arg, height*0.2+0.2)
    layer = gc.Path(x,y,z)
    return layer

LAYER = 400は固定値ですが、Z方向の積み上げの層(レイヤー)の数を表しています。
まるく(曲線)の波打った(凸)の外壁を400層で表現しています。
次にdef で、独自の関数を作っています。def rotation_calc(height)は、先に説明すると外壁の凸部の模様が層毎にちょっとずつズレていくズレ量を定義しています。rotation_calcにはheight x 0.004の値が返ってきます。なので、実は2行目のradの式はタイポです。なくても動作します。

print_polar(arg, rad, height)は丸い凸部の外形を描写するための関数です。
シンプルに説明すると直径radの円が0.2の刻み幅でZ方向に積み合わせていく関数になります。円を積み重ねていくと円柱になるということです。
ただ、実際のプログラムは複雑な形をしていますね。これは、直径を示すradがheight毎で値が変わるからです。また(arg + rotation)でrotation=rotaion_calc(height)なので、先ほど説明したちょっとずつ位相をheight毎に変えることで、ねじれを表現しています。
radには直径を変化させる値が入っており、arg+rotaionでねじれを表現しているということになります。
rad値は後に出てきますので、後ほど説明します。
と先にprint_polar関数を説明しましたが、その内容がわかれば、pythonのそれぞれのコードの意味は難しくないかと思います。np.full_likeはnumpyの関数で、argの個数分の全ての値をheight*0.2+0.2にする関数です。

full_object=[]
R = 50
layer_thick = 0.2
for height in range(LAYER):
    arg = np.linspace(0, np.pi*2,801)
    rad = np.sqrt(R**2 - (height * layer_thick-35)**2)
    rad += 1.5 * np.floor(1.05 * abs( np.sin(arg * 20)))
    wall = print_polar(arg, rad, height)
    full_object.append(wall)

full_objectという配列を定義し、ここに全ての情報を入れます。
R = 50は外壁のベースの直径です。layer_thickは各層の厚み0.2
forからは繰り返し処理で(いわゆるfor loop)でheightが range(LAYER)まで繰り返し処理がされます。つまりheight = 0,1,2,3,….400(LAYER=400)
argはnp.linspace(0, np.pi*2,801)となっていますが、linspaceは補完関数で、0~pi*2までの数字を801分割した数列を生成します。角度で表すと0°から360°(2π)を801個の分割した数字が入ります。ただここで、数字は度でなくラジアンです。
radの式は一見複雑ですが、簡単に表現すると ルートの(X^2 – a Y^2)です。みたことあるかもしれませんが、円を表す式ですね。どんな値になるエクセルで計算します(各項目を分解してみてみます)

これをみると円の一部を使って外壁の丸みを表現していることになりますね。250(50^2)あたりに盛り上がりが来る感じです。試しに-35を変えてみましょう。おそらくもりあがりの位置が変わるはずです。

変わりましたね。

次はradに以下を足し合わせています。
rad += 1.5 * np.floor(1.05 * abs( np.sin(arg * 20)))
これも計算をみてみます。

一番右がその値を示していますが、定期的に3の数字が出てますね。つまりこれが外壁のシマシマを表現していることになります。
一層目をみるとわかりやすいです。

試しにこのシマシマをもう少し外に出してみましょう。頭の3を6に変更するとどうなるか。

外に出てきましたね。

またabsは絶対値を返す関数ですが、これで正方向しか凸(しましま)が出ないようにしていますが、absをなくすとマイナス方向(凹)に行くはずですね。やってみます。

できましたね。

最後の方は難しくないので、一気に行きますね。

for height in range(400, 426):
arg = np.linspace(0, np.pi*2,401)
rad = np.sqrt(R**2 - (399 * layer_thick-35)**2)
top_wall = print_polar(arg, rad, height)
full_object.append(top_wall)
full_object.append(gc.Transform.offset(top_wall, -0.4))


gc.gui_export(full_object)

またfor文が出てきましたが、今度は400~426層を追加しています。今までは400層まででしたが、その上に26層分追加しています。
何を追加しているかは今度はシンプルで、円柱を追加しているだけです。復習になりますので、式から考えてみてください。

最後にgc.gui_export関数でfull_objectに入れていた値をg-codeで表示します。

以上、lamp_shade.pyのコードの説明でした。
これがわかるとねじれや凹凸を追加できて、より美しく複雑かつシンプルな図形が使えるようになるかと思いますので、色々と試してみてください。

1件のコメント »

  1. [...] lamp_shade.py [...]

    ピンバック by G-coordinator python g-codeプログラミングと3Dプリント -Generative Art, 3D printing- | Analogfeeder — 2025/03/13 @ 12:08

この投稿へのコメントの RSS フィード。 TrackBack URL

コメントする