Merencanakan revolusi yang solid dengan Python 3 (mungkin matplotlib)

Salam masalahnya:

R adalah daerah pada bidang xy yang dibatasi oleh parabola y=x^2+1 dan garis y=x+3. Benda padat yang berputar dibentuk dengan memutar R mengelilingi sumbu x. Saya perlu menggambar parabola dan garis dalam 2D ​​dan revolusi padat 3D, Bagaimana caranya? Saya telah menginstal anaconda.


person Robby    schedule 07.04.2016    source sumber
comment
Sepertinya Anda ingin kami menulis beberapa kode untuk Anda. Meskipun banyak pengguna yang bersedia memberikan kode untuk pembuat kode yang mengalami kesulitan, mereka biasanya hanya membantu jika pembuat kode telah mencoba menyelesaikan masalahnya sendiri. Cara yang baik untuk mendemonstrasikan upaya ini adalah dengan menyertakan kode yang telah Anda tulis sejauh ini, contoh masukan (jika ada), keluaran yang diharapkan, dan keluaran yang sebenarnya Anda dapatkan (keluaran konsol, penelusuran balik, dll.). Semakin banyak detail yang Anda berikan, semakin banyak kemungkinan jawaban yang Anda terima. Periksa FAQ dan Cara Bertanya.   -  person idjaw    schedule 07.04.2016


Jawaban (2)


Anda dapat menggunakan plot_surface:

import numpy as np
import matplotlib.pyplot as plt
import mpl_toolkits.mplot3d.axes3d as axes3d

fig = plt.figure()
ax = fig.add_subplot(1, 1, 1, projection='3d')

u = np.linspace(-1, 2, 60)
v = np.linspace(0, 2*np.pi, 60)
U, V = np.meshgrid(u, v)

X = U
Y1 = (U**2 + 1)*np.cos(V)
Z1 = (U**2 + 1)*np.sin(V)

Y2 = (U + 3)*np.cos(V)
Z2 = (U + 3)*np.sin(V)

ax.plot_surface(X, Y1, Z1, alpha=0.3, color='red', rstride=6, cstride=12)
ax.plot_surface(X, Y2, Z2, alpha=0.3, color='blue', rstride=6, cstride=12)
plt.show()

masukkan deskripsi gambar di sini

Untuk memplot permukaan menggunakan plot_surface Anda mulai dengan mengidentifikasi dua parameter 1 dimensi, u dan v:

u = np.linspace(-1, 2, 60)
v = np.linspace(0, 2*np.pi, 60)

sehingga x, y, z merupakan fungsi dari parameter u dan v:

x = x(u, v)
y = y(u, v)
z = z(u, v)

Hal yang perlu diperhatikan tentang ax.plot_surface adalah tiga argumen pertamanya harus berupa array 2D. Jadi kita menggunakan np.meshgrid untuk membuat matriks koordinat (U dan V) dari vektor koordinat (u dan v), dan mendefinisikan array 2D X, Y, Z sebagai fungsi dari U dan V:

X = U
Y1 = (U**2 + 1)*np.cos(V)
Z1 = (U**2 + 1)*np.sin(V)

Untuk setiap lokasi pada matriks koordinat U dan V, terdapat nilai yang sesuai untuk X dan Y dan Z. Ini membuat peta dari ruang uv 2 dimensi ke ruang xyz 3 dimensi. Untuk setiap persegi panjang di ruang uv, ada wajah di permukaan kita di ruang xyz. Permukaan melengkung yang digambar oleh plot_surface terdiri dari permukaan datar ini.

person unutbu    schedule 07.04.2016
comment
Jawaban Anda adalah untuk sumbu x. Bisakah Anda membantu saya menemukan titik temu revolusi di sekitar sumbu y? - person haccks; 23.04.2017
comment
@haccks: Dengan menggunakan kode di atas, cukup ubah ax.plot_surface(X, Y1, Z1,...) menjadi ax.plot_surface(Y1, X, Z1,...) dan lakukan hal serupa untuk panggilan ax.plot_surface kedua. Voila, permukaan revolusi kini berada di sekitar sumbu y. Tentu saja, X kini berperan sebagai y, dan Y1 serta Y2 kini menjadi nilai x, jadi agar lebih jelas, Anda juga ingin mengubah nama variabelnya. Namun hasilnya dicapai hanya dengan menukar variabel X dan Y. - person unutbu; 23.04.2017
comment
Saya mencobanya tetapi tidak berhasil. Rotasi sepanjang sumbu yang berbeda menghasilkan area dan bentuk yang berbeda. Menukar Y1 dan X akan menghasilkan luas dan bentuk yang sama. - person haccks; 23.04.2017
comment
Seharusnya seperti ini. - person haccks; 23.04.2017
comment
Anda perlu menyelesaikan x sebagai fungsi dari y. Dengan menukar X dan Y1, X kemudian dapat dinyatakan sebagai fungsi dari U (yang sama dengan Y1) dan V. Jadi, alih-alih Y1 = (U**2 + 1)*np.cos(V), Anda akan mendapatkan X = (...)*np.cos(V), dengan (...) berasal dari ekspresi Anda untuk x sebagai fungsi dari y. - person unutbu; 23.04.2017
comment
Maksudnya fungsi invers? - person haccks; 23.04.2017
comment
Ya. Temukan fungsi invers yang menyatakan x sebagai fungsi dari y. Kemudian gantikan U dengan y. Gunakan itu sebagai pengganti (...) di X = (...)*np.cos(V). - person unutbu; 24.04.2017
comment
Ya. Itu berfungsi untuk fungsi seperti y = x**2, y = 3*x + 5. Namun untuk fungsi seperti y = x**3 + x**2, tidak berfungsi. Anda tidak dapat menemukan invers untuk polinomial ini (AFAIK). - person haccks; 24.04.2017
comment
Saya melihat cara untuk memplot ini tanpa harus menyelesaikan kubiknya (walaupun ada rumusnya untuk itu). Kode ini terlalu panjang untuk dijelaskan di komentar. Jika Anda memposting pertanyaan, saya bisa menjawabnya di sana. - person unutbu; 24.04.2017
comment
Izinkan saya mengajukan pertanyaan. - person haccks; 24.04.2017

Mendukung hal di atas, Anda dapat menjadikannya dinamis dengan widget atau gif.

Membuat gif: Gunakan paket gif:

import gif

@gif.frame
def plot_volume(angle):
    fig = plt.figure(figsize = (20, 15))

    ax2 = fig.add_subplot(1, 1, 1, projection = '3d')
    angles = np.linspace(0, 360, 20)
    x = np.linspace(-1, 2, 60)
    v = np.linspace(0, 2*angle, 60)

    U, V = np.meshgrid(x, v)
    Y1 = (U**2 + 1)*np.cos(V)
    Z1 = (U**2 + 1)*np.sin(V)
    Y2 = (U + 3)*np.cos(V)
    Z2 = (U + 3)*np.sin(V)
    X = U
    ax2.plot_surface(X, Y1, Z1, alpha = 0.2, color = 'blue', rstride = 6, cstride = 6)
    ax2.plot_surface(X, Y2, Z2, alpha = 0.2, color = 'red', rstride = 6, cstride = 6)
    ax2.set_xlim(-3,3)
    ax2.set_ylim(-5,5)
    ax2.set_zlim(-5,5)
    ax2.view_init(elev = 50, azim = 30*angle)
    ax2.plot_wireframe(X, Y2, Z2)
    ax2.plot_wireframe(X, Y1, Z1, color = 'black')
    ax2._axis3don = False

frames = []
for i in np.linspace(0, 2*np.pi, 20):
    frame = plot_volume(i)
    frames.append(frame)

gif.save(frames, 'images/vol1.gif', duration = 500)

from IPython.display import Image

Image('images/vol1.gif')

Jadikan Interaktif: Gunakan ipywidgets.

def three_d_plotter(angle, rotate, turn):
    fig = plt.figure(figsize = (13, 6))
    ax = fig.add_subplot(1, 1, 1, projection='3d')

    u = np.linspace(-1, 2, 60)
    v = np.linspace(0, angle, 60)
    U, V = np.meshgrid(u, v)

    X = U
    Y1 = (U**2 + 1)*np.cos(V)
    Z1 = (U**2 + 1)*np.sin(V)

    Y2 = (U + 3)*np.cos(V)
    Z2 = (U + 3)*np.sin(V)

    ax.plot_surface(X, Y1, Z1, alpha=0.3, color='red', rstride=6, cstride=12)
    ax.plot_surface(X, Y2, Z2, alpha=0.3, color='blue', rstride=6, cstride=12)
    ax.plot_wireframe(X, Y2, Z2, alpha=0.3, color='blue', rstride=6, cstride=12)
    ax._axis3don = False
    ax.view_init(elev = rotate, azim = turn)

    plt.show()

from ipywidgets import interact
import ipywidgets as widgets

interact(three_d_plotter, angle = widgets.FloatSlider(0, min = 0, max = 2*np.pi, step = np.pi/10),
        rotate = widgets.FloatSlider(0, min = 0, max = 360, step = 5),
         turn = widgets.FloatSlider(0, min = 0, max = 500, step = 5))
person jfkoehler    schedule 08.02.2020