※ 当ページには【広告/PR】を含む場合があります。
2024/03/25
【FreeCAD初心者ガイド】FreeCAD付属のmatplotlibを使って3次元モデリングに便利なプロトタイプ関数を思索する
以前の記事で、を簡単に使ってみる方法を紹介したことがあります。これにより、FreeCADユーザーはわざわざmatlibplot専用のPython環境を整えてあげなくても、FreeCADを立ち上げる感覚そのままにnumpyやscipyから提供される高度な関数をある程度利用することが可能です。【FreeCAD初心者ガイド】FreeCAD付属のmatplotlibを使って3次元モデリングに便利なプロトタイプ関数を思索するFreeCADに標準で組込まれているPython製高機能プロッター・matplotlibの基本的な使い方を紹介
今回の記事では、matplotlibを使ったPythonコードの活用の一例として、以下の記事で紹介していた「Gyroid関数」の解析解を導いて3次プロットしてみるまでを紹介します。【pythonで動くG-codeビルダー】G-coordinator/gcoordinatorをLinuxにインストール&動作確認してみるPythonソースコードで3Dプリンター向けのgcodeが生成できる・『G-coordinator』をLinuxへ導入します。
基礎からのFreeCAD 三訂版 (I/O BOOKS) FreeCAD入門 FreeCADの使い方 いろんな物を作りながら3DCADを学ぼう!: 3Dプリンターでの印刷も掲載 図面の描き方がやさしくわかる本 Gyroid関数の解析解
まずGyroid関数は以下のような陰関数で与えられます。sin(x)cos(y)+sin(y)cos(z)+sin(z)cos(x)=0Eq. (gyroid-1) Gyroidは陰関数で書くとサイクリックな項の和として表せるため、綺麗な見た目をしています。ただし、このまま3次元グラフを描く際に、Mathematicaのような高度な数学的な処理が可能なソフトウェアが必要になります。今回はmatplotlibから3次元プロットを試みたいのですが、数値解的な手法を使うと、ソルバをどう設定すれば精度が良いか...など他に考慮しなければならない点が多くなります。こういったことから、matplotlibで3次元グラフ化するためには、解析解(陽関数)を得ることが出来ないかを最初に考えると良いでしょう。式変形した結果だけを示しますが、Gyroid関数は以下のような2変数関数として解析解を持ちます。z=arcsin{sin2x+cos2y−cosxsinycosy±sinxsin2x+cos2y−cos2xsin2y}Eq. (gyroid-2) 陰関数形とは違い割と綺麗ではないですが、計算としてはより単純です。注意が必要なのは、分子の中にある平方根の取り扱いで、ルートの中身が負の値をとるとき、zは実数解を持ちません。また、二次方程式由来の±からも分かる通り、Gyroid関数の解析解は「2枚張り」の対で存在しています。matplotlibで3次元描画する際にはこの点を注意してスクリプトを書いていきましょう。
基礎からのFreeCAD 三訂版 (I/O BOOKS) FreeCAD入門 FreeCADの使い方 いろんな物を作りながら3DCADを学ぼう!: 3Dプリンターでの印刷も掲載 図面の描き方がやさしくわかる本 matplotlibでの描画
では先程の解析解の考え方を基にして、Pythonコードに落とし込んでいきます。 import numpy as np
import matplotlib.pyplot as plt
from mpl_toolkits.mplot3d import Axes3D
N = 1000
R1 = -np.pi/2
R2 = np.pi/2
x = np.linspace(R1, R2, N)
y = np.linspace(R1, R2, N)
X, Y = np.meshgrid(x, y)
A1 = np.sin(X)**2 + np.cos(Y)**2
A2 = np.cos(X)*np.sin(Y)
Z0 = A1 - A2**2
X,Y = np.where(Z0 >= 0, X, np.nan), np.where(Z0 >= 0, Y, np.nan)
A1 = np.sin(X)**2 + np.cos(Y)**2
A2 = np.cos(X)*np.sin(Y)
A3 = (-A2*np.cos(Y) - np.sin(X)*np.sqrt(A1 - A2**2))/A1
A4 = (-A2*np.cos(Y) + np.sin(X)*np.sqrt(A1 - A2**2))/A1
Z1 = np.arcsin(A3)
Z2 = np.arcsin(A4)
fig = plt.figure()
ax = fig.add_subplot(111, projection='3d')
ax.plot_wireframe(X,Y,Z1)
ax.plot_wireframe(X,Y,Z2)
plt.show()
このスクリプトのポイントだけ掻い摘むと、matplotlibのワイヤーフレーム描画には、局面表示させるためのメッシュグリッドが必要になりますが、先程の節でも述べたように、実数解を持たない領域は避ける必要があります。ということで、2回目のメッシュグリッド生成のときに、np.where
を使って、有効なワイヤーフレームに矯正しています。なおここでは、matplotlibではデータ点にnan
がある場合には描画をスキップしてくれるを期待して、np.nan
をワイヤーフレーム座標に入れています。これを実行すると、という感じのGyroid局面が描けます。メッシュに裂け目があるのは、前述した通り、解析解が「2枚張り」であるがゆえの2つのワイヤーフレーム面が表示として見えています。2つのワイヤーフレームの表示を上手く接続できる方法もあるかもしれませんが、そちらはmatplotlibのテクニックの問題になるため、これ以上は深い入りするのはやめておきます。
基礎からのFreeCAD 三訂版 (I/O BOOKS) FreeCAD入門 FreeCADの使い方 いろんな物を作りながら3DCADを学ぼう!: 3Dプリンターでの印刷も掲載 図面の描き方がやさしくわかる本 まとめ
以上、今回はGyroid関数の解析解を解いてみようというそれだけの企画でした。というのも、以前やった「G-coordinator」のサンプルコードにあるGyroid関数の解き方が何かとトリッキーであると感じたためで、次回以降では今回の解析式を利用して座標を求めていくようにスクリプトの補正をしてみたいと思います。