2017-02-17 4 views
0

私はPython2.7で3D numpy配列を使って作業しており、2D傾きのディスクにあるピクセルだけを取得しようとしています。ある傾斜したディスクで3D数値配列をマスキングする

circle

:ここ

ディスク(=円)の境界線をプロットする私のコードで私は

import numpy as np 
import matplotlib.pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 


#creating a 3d numpy array (empty in this example, but will represent a binary 3D image in my application) 
space=np.zeros((40,40,20)) 

r = 8 #radius of the circle 
theta = np.pi/4 # "tilt" of the circle 
phirange = np.linspace(0, 2 * np.pi) #to make a full circle 

#center of the circle 
center=[20,20,10] 

#computing the values of the circle in spherical coordinates and converting them 
#back to cartesian 
for phi in phirange: 
    x = r * np.cos(theta) * np.cos(phi) + center[0] 
    y= r*np.sin(phi) + center[1] 
    z= r*np.sin(theta)* np.cos(phi) + center[2] 
    space[int(round(x)),int(round(y)),int(round(z))]=1 


x,y,z = space.nonzero() 

#plotting 
fig = plt.figure() 
ax = fig.add_subplot(111, projection='3d') 
ax.scatter(x, y, z, zdir='z', c= 'red') 
plt.show() 

にプロットは、以下の図を与える興味を持っています良いスタートですが、円で定義されたディスクにあるspaceのピクセルの値だけを取得する方法が必要です。次の画像のピンクゾーンにあるもの(私のアプリケーションでは、spaceは)3Dバイナリイメージで、ここではそれだけでプロットし、あなたに私がしたいディスクを表示できるようにする)numpy.zeros(です:

どう

disc

私はprocede必要がありますか? 私はいくつかのマジックが関与していると思いますが、私はあなたが2Dでそれをやる方法を理解しています(this questionのように)が、これを3Dに適用するのに問題があります。

+0

「落ちる」とはどういう意味ですか?ピクセルがポイントの場合は、円の内側だけでなく、平面と交差するという保証はありません。代わりに高さ1のシリンダーを見たいと思っていますか? – Eric

+0

はい、私は知っている、近似との作業はこのアプリケーションでは問題ありません。従って、私が示すコードのround()は、図の点は近似的に円上にあります。私は、これは1ピクセルの高さのシリンダでポイントを探すことと同等であると言うことができると思います。 – Soltius

答えて

1

簡単な方法の1つは、ディスクプレーンの法線ベクトルを計算することです。あなたは球座標を使うことができます。 でないことを確認して、中心を追加し、φを0に設定し、cosとsinθを入れ替え、sinにマイナス記号を付ける。

そのベクトルを呼び出すことができます。プレーンはv0 * x0 + v1 * x1 + v2 * x2 == cで与えられます。xの円から点を挿入してcを計算できます。

次に、x0とx1の2次元グリッドを作成し、x2を解くことができます。これはx0、x1メッシュの関数として高さx2を与えます。これらの点については、ディスクセンターからの距離を計算し、離れすぎた点を破棄することができます。これは本当にマスクを使用して行います。

最終的に、プロットしたい精度によって、x2の値をグリッド単位に丸めることができますが、サーフェスプロットの場合などはそうしません。

説明したように3Dマスクを取得するには、x2を四捨五入してから、すべてゼロのスペースから始めて、スペース[x0、x1、x2] = Trueを使用してディスクピクセルを設定します。これは、前に説明したように、x0、x1、x2をマスクしていることを前提としています。

+0

私は正しい方向に私を導くあなたの入力に感謝します。私はあなたが提案したものを正確にはしませんでしたが、私のコードは法線ベクトルなどを計算することに基づいています。より正確には、http://demonstrations.wolfram.com/ParametricEquationOfACircleIn3D/のテクニックを使用して、外側円のパラメータ化を取得しました。その後、私はちょうど0から私のmaxradiusに半径を通ってディスクを入手しました! – Soltius

1

よく、数学の問題がある場合は、Mathematics Stack Exchangeサイトで尋ねる必要があります。

私の見解では、まずディスクが入っている表面を見つけて、その表面の領域計算を、たとえばリンクされた質問で述べた方法で行う必要があります。

numpyまたはmatplotlibここでは間違いなくプロジェクションの責任を負いません。

どのサーフェスが入っているかを明示せずに、方程式がプレーンであることを保証しない場合、そのエリアは何も意味しません。

関連する問題