質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Anaconda

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

STL

STL(Standard Template Library)は、ジェネティックコンテイナー、イテレーター、アルゴリズム、そして関数オブジェクトのC++ライブラリーです。

3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

0回答

1873閲覧

pythonで3Dモデルの球面近似をしたい

jy8666

総合スコア2

Anaconda

Anacondaは、Python本体とPythonで利用されるライブラリを一括でインストールできるパッケージです。環境構築が容易になるため、Python開発者間ではよく利用されており、商用目的としても利用できます。

STL

STL(Standard Template Library)は、ジェネティックコンテイナー、イテレーター、アルゴリズム、そして関数オブジェクトのC++ライブラリーです。

3DCG

コンピュータの演算により、3次元空間の仮想物体を、2次元平面上で表現する手法である。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2021/12/22 15:12

編集2021/12/22 16:09

1房のぶどうの3Dモデルを読み込んで、一粒ずつ球面近似をするプログラムを作りたいと思っています。
4か所クリックした部分を球近似してその球の中心を求める仕様にするつもりです。

1個の3Dモデルを球近似するプログラムは既出ですが、近似する物体が複数個画面上にあるような3Dモデルの時はどうするのだろうかと思い質問させていただきました。
以下のソースコードではvalueエラーが出てしまい機能しないので解決策を教えてほしいです。よろしくお願いします。

###ソースコード

python

1import pyvista as pv 2import numpy as np 3from stl import mesh 4 5spher_mode = False # 球近似計算モード 6count = 0 # 【ベクトル計算モード】クリックした回数をカウント 7vector = [] # 【ベクトル計算モード】入力したベクトル情報 8plotter = pv.Plotter() 9filename = "grape.stl" # 読み込むSTLファイル 10 11def approx(plot): 12  """ 13 入力 14 point_cloud: 点群のxyz座標のリスト numpyのarray形式で3x3xN行列 15 出力 16 radius : 近似球の半径 スカラー 17 sphere_center : 球の中心座標 xyz numpyのarray 18 """ 19 20 A_1 = np.zeros((3,3)) 21 #Aのカッコの中の1項目用に変数A_1をおく 22 v_1 = np.array([0.0,0.0,0.0]) 23 v_2 = 0.0 24 v_3 = np.array([0.0,0.0,0.0]) 25 #ベクトルの1乗、2乗、3乗平均の変数をv_1, v_2, v_3とする 26 #1乗、3乗はベクトル、2乗はスカラーとなる 27 28 N = len(point_cloud) 29 #Nは点群の数 30 31 """シグマの計算""" 32 for v in point_cloud: 33 v_1 += v 34 v_2 += np.dot(v, v) 35 v_3 += np.dot(v, v) * v 36 37 A_1 += np.dot(np.array([v]).T, np.array([v])) 38 39 v_1 /= N 40 v_2 /= N 41 v_3 /= N 42 A = 2 * (A_1 / N - np.dot(np.array([v_1]).T, np.array([v_1]))) 43 # 式② 44 b = v_3 - v_2 * v_1 45 # 式③ 46 sphere_center = np.dot(np.linalg.inv(A), b) 47 # 式① 48 return(sphere_center) 49 50 51"""半径と中心を定めて 点群ファイルに保存する""" 52def draw_sphere(radius,sphere_center): 53 54 """ 55 入力 56 sphere_center : 中心座標のxyz numpyのarray 57 """ 58 59 point_list = [] 60 61 """球面の点群を作成していく""" 62 for i in range(360): 63 i = i * np.pi / 180 #ラジアン表記にする 64 for j in range(360): 65 j = j * np.pi / 180 #ラジアン表記にする 66 point = radius * np.array([np.sin(i) * np.cos(j),np.sin(i) * np.sin(j), np.cos(i)]) + sphere_center 67 #座標点を追加していく 68 point_list.append(point) 69 70 print(np.array(point_list)) 71 72 return 73 74def right_click(data): 75 global spher_mode, count, vector 76 77 if(spher_mode is True): 78 count += 1 79 data = np.array(data) 80 plotter.add_points(data, render_points_as_spheres=True, point_size=10.0, color='yellow') # 指定した座標を黄色で表示 81 print('data:{} click:{}/4'.format(data, count)) 82 vector.append(data) # 指定した座標データを一時保存 83 84 if count == 4: # 4回目のクリック時に判定 85 while True: 86 try: 87 dic = {'y':True, 'yes':True, 'n':False, 'no':False} 88 res = input('確定しますか? (Yes/No) >> ') 89 res = dic[res] 90 break 91 except KeyError: 92 pass 93 94 if res == True: 95 print('OK!') 96 print(approx(vector)) 97 spher_mode = False 98 else: 99 print('リトライ') 100 vector = [] 101 102 count = 0 103 paint_meshdata() 104 105       sphere_stl = mesh.Mesh.from_file('grape.stl') 106 sphere_points = sphere_stl.points.reshape([0,1,2,3])#stlから点群を抽出 107 108 print(sphere_points) # 表面データの点群が代入される 109 radius, center = approx.sphere_fit(sphere_points) 110 111 print('中心の座標:',(center))#中心の座標 112 113 114 plotter.track_click_position(callback=right_click,side='right') # 右クリックを押したときの処理 115 116 plotter.add_key_event('a', press_akey) 117 118 plotter.show() 119

###エラー

WARNING:root:Encountered issue in callback (most recent call last): File "C:\Users\anaconda3\lib\site-packages\pyvista\plotting\render_window_interactor.py", line 133, in _click_callback callback(self._plotter.pick_click_position()) File "sample.py", line 115, in right_click print(approx(vector)) File "sample.py", line 78, in approx sphere_points = sphere_stl.points.reshape([0,1,2,3])#stl から点群を抽出 ValueError: cannot reshape array of size 2069388 into shape (0,1,2,3)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

まだ回答がついていません

会員登録して回答してみよう

アカウントをお持ちの方は

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問