2016-08-14 10 views
0

matplotlibにベジェサーフェスをプロットしようとしている。私はx、y、zの関数を持っています(私はそれらをタイプしませんでした。sympyは自動的にそれらを生成しました)が、コードを実行するたびに空白のプロットが得られます。ちなみに、px、py、pzは制御点の行列です。私が間違っていたことと正しいものを教えてもらえますか?あるいは、パイソンを使用してベジェサーフェスをプロットする別の方法を提案しますか?pythonベジェサーフェスプロットに問題がある - 空のプロットを返す。

fig = plt.figure() 
ax = fig.gca(projection='3d') 

u = np.linspace(0, 1, 10) 
v = np.linspace(0, 1, 10) 

x = px[0][0]*u**3*v**3 + px[0][1]*3*u**3*v**2*(-v + 1) + px[0][2]*3*u**3*v* (-v + 1)**2 + px[0][3]*u**3*(-v + 1)**3 + \ 
px[1][0]*3*u**2*v**3*(-u + 1) + px[1][1]*9*u**2*v**2*(-u + 1)*(-v + 1) + px[1][2]*9*u**2*v*(-u + 1)*(-v + 1)**2 + \ 
px[1][3]*3*u**2*(-u + 1)*(-v + 1)**3 + px[2][0]*3*u*v**3*(-u + 1)**2 + px[2][1]*9*u*v**2*(-u + 1)**2*(-v + 1) + \ 
px[2][2]*9*u*v*(-u + 1)**2*(-v + 1)**2 + px[2][3]*3*u*(-u + 1)**2*(-v + 1)**3 + px[3][0]*v**3*(-u + 1)**3 + \ 
px[3][1]*3*v**2*(-u + 1)**3*(-v + 1) + px[3][2]*3*v*(-u + 1)**3*(-v + 1)**2 + px[3][3]*(-u + 1)**3*(-v + 1)**3 

y = py[0][0]*u**3*v**3 + py[0][1]*3*u**3*v**2*(-v + 1) + py[0][2]*3*u**3*v*(-v + 1)**2 + py[0][3]*u**3*(-v + 1)**3 +\ 
py[1][0]*3*u**2*v**3*(-u + 1) + py[1][1]*9*u**2*v**2*(-u + 1)*(-v + 1) + py[1][2]*9*u**2*v*(-u + 1)*(-v + 1)**2 + \ 
py[1][3]*3*u**2*(-u + 1)*(-v + 1)**3 + py[2][0]*3*u*v**3*(-u + 1)**2 + py[2][1]*9*u*v**2*(-u + 1)**2*(-v + 1) + \ 
py[2][2]*9*u*v*(-u + 1)**2*(-v + 1)**2 + py[2][3]*3*u*(-u + 1)**2*(-v + 1)**3 + py[3][0]*v**3*(-u + 1)**3 + \ 
py[3][1]*3*v**2*(-u + 1)**3*(-v + 1) + py[3][2]*3*v*(-u + 1)**3*(-v + 1)**2 + py[3][3]*(-u + 1)**3*(-v + 1)**3 

z = pz[0][0]*u**3*v**3 + pz[0][1]*3*u**3*v**2*(-v + 1) + pz[0][2]*3*u**3*v*(-v + 1)**2 + pz[0][3]*u**3*(-v + 1)**3 + \ 
pz[1][0]*3*u**2*v**3*(-u + 1) + pz[1][1]*9*u**2*v**2*(-u + 1)*(-v + 1) + pz[1][2]*9*u**2*v*(-u + 1)*(-v + 1)**2 +\ 
pz[1][3]*3*u**2*(-u + 1)*(-v + 1)**3 + pz[2][0]*3*u*v**3*(-u + 1)**2 + pz[2][1]*9*u*v**2*(-u + 1)**2*(-v + 1) + \ 
pz[2][2]*9*u*v*(-u + 1)**2*(-v + 1)**2 + pz[2][3]*3*u*(-u + 1)**2*(-v + 1)**3 + pz[3][0]*v**3*(-u + 1)**3 + \ 
pz[3][1]*3*v**2*(-u + 1)**3*(-v + 1) + pz[3][2]*3*v*(-u + 1)**3*(-v + 1)**2 + pz[3][3]*(-u + 1)**3*(-v + 1)**3 

ax.plot_surface(x, y, z, rstride=4, cstride=4, color='b') 

plt.show() 
+0

By私はDe Casteljauのアルゴリズムを使用することができましたが、得た後にポイントをプロットする方法がわかりませんでした –

答えて

0

ここでmatplotlibの持つ曲線ベジェプロットする例をいくつだ:

EXAMPLE1

stackoverflow

import numpy as np 
from scipy.misc import comb 
from matplotlib import pyplot as plt 


def bernstein_poly(i, n, t): 
    return comb(n, i) * (t**(n - i)) * (1 - t)**i 


def bezier_curve(points, nTimes=1000): 
    nPoints = len(points) 
    xPoints = np.array([p[0] for p in points]) 
    yPoints = np.array([p[1] for p in points]) 

    t = np.linspace(0.0, 1.0, nTimes) 

    polynomial_array = np.array(
     [bernstein_poly(i, nPoints - 1, t) for i in range(0, nPoints)]) 

    xvals = np.dot(xPoints, polynomial_array) 
    yvals = np.dot(yPoints, polynomial_array) 

    return xvals, yvals 


if __name__ == "__main__": 
    nPoints = 4 
    points = np.random.rand(nPoints, 2) * 200 
    xpoints = [p[0] for p in points] 
    ypoints = [p[1] for p in points] 

    xvals, yvals = bezier_curve(points, nTimes=1000) 
    plt.plot(xvals, yvals) 
    plt.plot(xpoints, ypoints, "ro") 
    for nr in range(len(points)): 
     plt.text(points[nr][0], points[nr][1], nr) 

    plt.show() 

EXAMPLE2

から

の場合:このwebsite

EDITに示したようにあなたは私に言わせればmatplotlib tutorial

import matplotlib.pyplot as plt 
from matplotlib.path import Path 
import matplotlib.patches as patches 

verts = [ 
    (0., 0.), # P0 
    (0.2, 1.), # P1 
    (1., 0.8), # P2 
    (0.8, 0.), # P3 
    ] 

codes = [Path.MOVETO, 
     Path.CURVE4, 
     Path.CURVE4, 
     Path.CURVE4, 
     ] 

path = Path(verts, codes) 

fig = plt.figure() 
ax = fig.add_subplot(111) 
patch = patches.PathPatch(path, facecolor='none', lw=2) 
ax.add_patch(patch) 

xs, ys = zip(*verts) 
ax.plot(xs, ys, 'x--', lw=2, color='black', ms=10) 

ax.text(-0.05, -0.05, 'P0') 
ax.text(0.15, 1.05, 'P1') 
ax.text(1.05, 0.85, 'P2') 
ax.text(0.85, -0.05, 'P3') 

ax.set_xlim(-0.1, 1.1) 
ax.set_ylim(-0.1, 1.1) 
plt.show() 

...パラメトリック曲線について考える私の好きな道から

は、その行列形式を使用していますあなたはそれを3dの場合に拡張したいと思っています。ここには実例があります:

import matplotlib as mpl 
import numpy as np 
from scipy.misc import comb 
from matplotlib import pyplot as plt 
from mpl_toolkits.mplot3d import Axes3D 


def bernstein_poly(i, n, t): 
    return comb(n, i) * (t**(n - i)) * (1 - t)**i 


def bezier_curve(points, nTimes=1000): 
    nPoints = len(points) 
    xPoints = np.array([p[0] for p in points]) 
    yPoints = np.array([p[1] for p in points]) 
    zPoints = np.array([p[2] for p in points]) 

    t = np.linspace(0.0, 1.0, nTimes) 

    polynomial_array = np.array(
     [bernstein_poly(i, nPoints - 1, t) for i in range(0, nPoints)]) 

    xvals = np.dot(xPoints, polynomial_array) 
    yvals = np.dot(yPoints, polynomial_array) 
    zvals = np.dot(zPoints, polynomial_array) 

    return xvals, yvals, zvals 


if __name__ == "__main__": 
    nPoints = 4 
    points = np.random.rand(nPoints, 3) * 200 
    xpoints = [p[0] for p in points] 
    ypoints = [p[1] for p in points] 
    zpoints = [p[2] for p in points] 

    xvals, yvals, zvals = bezier_curve(points, nTimes=1000) 

    fig = plt.figure() 
    ax = fig.gca(projection='3d') 
    ax.plot(xvals, yvals, zvals, label='bezier') 
    ax.plot(xpoints, ypoints, zpoints, "ro") 
    for nr in range(len(points)): 
     ax.text(points[nr][0], points[nr][1], points[nr][2], nr) 

    plt.show() 
+0

ねえ、本当に助けになりました。私は実際にmatplotlibで見た後にパスを使うことを考えましたが、3次元のサーフェスにどのように拡張するのかは分かりませんでした。いずれかの例を3次元のサーフェスに拡張する方法を説明できますか?最初の例で「zvals」を追加するだけで簡単ですか? –

+0

@JasonIrukulapati確かに、私は私の答えを編集し、あなたの最後に簡単な例を示しました。私はいつも第2のケースを勉強することを奨励し、一度あなたはそれが3dにまで伸びていることは些細なことになります。 – BPL

+0

すごくおかげさまで! –

関連する問題