CyberChaos(さいばかおす)

プログラミング言語、トランスパイラ、RPA、ChatGPT、データマイニング、リバースエンジニアリングのための忘備録

任意の直方体から任意の円錐をくり抜くPydroid用のGUIプログラムを書いて。

2025-02-09 09:45:54 | DeepSeek
以下は、直方体から円錐をくり抜く操作を可視化するPydroid用GUIプログラムです。matplotlibを使用して3D形状を表示します。

```python
import tkinter as tk
from tkinter import ttk, messagebox
import numpy as np
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg
from mpl_toolkits.mplot3d import Axes3D

class ShapeCarvingApp:
def __init__(self, root):
self.root = root
self.root.title("3D Shape Carving")
self.root.geometry("1000x800")
# 直方体パラメータ
self.cuboid_vars = {
'width': tk.DoubleVar(value=5.0),
'height': tk.DoubleVar(value=5.0),
'depth': tk.DoubleVar(value=5.0)
}
# 円錐パラメータ
self.cone_vars = {
'radius': tk.DoubleVar(value=1.5),
'height': tk.DoubleVar(value=3.0),
'x_pos': tk.DoubleVar(value=2.5),
'y_pos': tk.DoubleVar(value=2.5),
'z_pos': tk.DoubleVar(value=0.0),
'direction': tk.StringVar(value='Z')
}
# グラフ設定
self.figure = plt.figure(figsize=(8, 6))
self.ax = self.figure.add_subplot(111, projection='3d')
# GUI初期化
self.create_widgets()
self.plot_shapes()

def create_widgets(self):
# 入力パネル
input_frame = ttk.LabelFrame(self.root, text="形状パラメータ")
input_frame.pack(side=tk.LEFT, fill=tk.Y, padx=10, pady=10)

# 直方体入力
ttk.Label(input_frame, text="直方体設定", font=('Arial', 10, 'bold')).grid(row=0, column=0, columnspan=2, pady=5)
ttk.Label(input_frame, text="幅:").grid(row=1, column=0, sticky=tk.W)
ttk.Entry(input_frame, textvariable=self.cuboid_vars['width'], width=8).grid(row=1, column=1)
ttk.Label(input_frame, text="高さ:").grid(row=2, column=0, sticky=tk.W)
ttk.Entry(input_frame, textvariable=self.cuboid_vars['height'], width=8).grid(row=2, column=1)
ttk.Label(input_frame, text="奥行き:").grid(row=3, column=0, sticky=tk.W)
ttk.Entry(input_frame, textvariable=self.cuboid_vars['depth'], width=8).grid(row=3, column=1)

# 円錐入力
ttk.Label(input_frame, text="円錐設定", font=('Arial', 10, 'bold')).grid(row=4, column=0, columnspan=2, pady=5)
ttk.Label(input_frame, text="半径:").grid(row=5, column=0, sticky=tk.W)
ttk.Entry(input_frame, textvariable=self.cone_vars['radius'], width=8).grid(row=5, column=1)
ttk.Label(input_frame, text="高さ:").grid(row=6, column=0, sticky=tk.W)
ttk.Entry(input_frame, textvariable=self.cone_vars['height'], width=8).grid(row=6, column=1)
ttk.Label(input_frame, text="X位置:").grid(row=7, column=0, sticky=tk.W)
ttk.Entry(input_frame, textvariable=self.cone_vars['x_pos'], width=8).grid(row=7, column=1)
ttk.Label(input_frame, text="Y位置:").grid(row=8, column=0, sticky=tk.W)
ttk.Entry(input_frame, textvariable=self.cone_vars['y_pos'], width=8).grid(row=8, column=1)
ttk.Label(input_frame, text="Z位置:").grid(row=9, column=0, sticky=tk.W)
ttk.Entry(input_frame, textvariable=self.cone_vars['z_pos'], width=8).grid(row=9, column=1)
ttk.Label(input_frame, text="方向:").grid(row=10, column=0, sticky=tk.W)
ttk.Combobox(input_frame, textvariable=self.cone_vars['direction'],
values=['X', 'Y', 'Z'], width=6).grid(row=10, column=1)

# 制御ボタン
btn_frame = ttk.Frame(input_frame)
btn_frame.grid(row=11, column=0, columnspan=2, pady=10)
ttk.Button(btn_frame, text="更新", command=self.plot_shapes).pack(side=tk.LEFT, padx=5)
ttk.Button(btn_frame, text="リセット", command=self.reset_values).pack(side=tk.LEFT, padx=5)

# 3D表示領域
graph_frame = ttk.Frame(self.root)
graph_frame.pack(side=tk.RIGHT, fill=tk.BOTH, expand=True)
self.canvas = FigureCanvasTkAgg(self.figure, master=graph_frame)
self.canvas.get_tk_widget().pack(fill=tk.BOTH, expand=True)

def plot_shapes(self):
try:
self.ax.clear()
# 直方体の描画
self.draw_cuboid()
# 円錐の描画
self.draw_cone()
# グラフ設定
self.ax.set_xlabel('X')
self.ax.set_ylabel('Y')
self.ax.set_zlabel('Z')
self.ax.set_title('直方体 - 円錐くり抜き')
self.ax.set_box_aspect([1,1,1])
self.canvas.draw()
except Exception as e:
messagebox.showerror("エラー", f"描画エラー:\n{str(e)}")

def draw_cuboid(self):
# 直方体の頂点座標を計算
w = self.cuboid_vars['width'].get() / 2
h = self.cuboid_vars['height'].get() / 2
d = self.cuboid_vars['depth'].get() / 2
vertices = np.array([[-w, -h, -d], [w, -h, -d], [w, h, -d], [-w, h, -d],
[-w, -h, d], [w, -h, d], [w, h, d], [-w, h, d]])
# 面の定義
faces = [[vertices[j] for j in [0,1,2,3]],
[vertices[j] for j in [4,5,6,7]],
[vertices[j] for j in [0,3,7,4]],
[vertices[j] for j in [1,2,6,5]],
[vertices[j] for j in [0,1,5,4]],
[vertices[j] for j in [2,3,7,6]]]
# ワイヤーフレームで描画
for face in faces:
x = [p[0] for p in face]
y = [p[1] for p in face]
z = [p[2] for p in face]
self.ax.plot(x + [x[0]], y + [y[0]], z + [z[0]], color='blue', alpha=0.5)

def draw_cone(self):
# 円錐パラメータ取得
r = self.cone_vars['radius'].get()
h = self.cone_vars['height'].get()
x = self.cone_vars['x_pos'].get()
y = self.cone_vars['y_pos'].get()
z = self.cone_vars['z_pos'].get()
direction = self.cone_vars['direction'].get()
# 方向に応じて円錐を生成
theta = np.linspace(0, 2*np.pi, 50)
z_vals = np.linspace(0, h, 50)
theta, z_vals = np.meshgrid(theta, z_vals)
x_cone = r * (1 - z_vals/h) * np.cos(theta)
y_cone = r * (1 - z_vals/h) * np.sin(theta)
z_cone = z_vals
# 方向調整
if direction == 'X':
x_cone, z_cone = z_cone, x_cone
elif direction == 'Y':
y_cone, z_cone = z_cone, y_cone
# 位置調整
x_cone += x
y_cone += y
z_cone += z
# 表面を描画(半透明)
self.ax.plot_surface(x_cone, y_cone, z_cone, color='red', alpha=0.3)

def reset_values(self):
self.cuboid_vars['width'].set(5.0)
self.cuboid_vars['height'].set(5.0)
self.cuboid_vars['depth'].set(5.0)
self.cone_vars['radius'].set(1.5)
self.cone_vars['height'].set(3.0)
self.cone_vars['x_pos'].set(2.5)
self.cone_vars['y_pos'].set(2.5)
self.cone_vars['z_pos'].set(0.0)
self.cone_vars['direction'].set('Z')
self.plot_shapes()

if __name__ == "__main__":
root = tk.Tk()
app = ShapeCarvingApp(root)
root.mainloop()
```

### 主な機能
1. 直方体のサイズ(幅・高さ・奥行き)設定
2. 円錐のパラメータ(半径・高さ・位置・方向)設定
3. リアルタイム3Dプレビュー
4. 形状パラメータのリセット機能
5. 半透明表示によるくり抜き部分の可視化

### 使い方
1. 直方体のサイズを入力
2. くり抜く円錐のパラメータを設定
3. 「更新」ボタンで形状を再描画
4. 3Dビューを指で回転して確認
5. パラメータ調整を繰り返して最適な形状を作成

### 注意事項
- 円錐の位置が直方体の外にある場合でも描画されます
- 実際の切削処理ではなく視覚的表現のみです
- 数値入力時は小数点数を使用可能(例:2.5)
- 方向設定は円錐の向きを変更(X/Y/Z軸方向)

Pydroidで実行する場合は、matplotlibとnumpyのインストールが必要です。3D描画部分は指で自由に回転させて多方向から確認できます。



これは直方体と円錐を描いて重ねただけであるにすぎない。
直方体の表面から飛び出ている部分は表示させないようにして、直方体の表面も着色すべきだ。


最新の画像もっと見る

コメントを投稿

ブログ作成者から承認されるまでコメントは反映されません。