行星 3D 表示的 Python 代码

问题描述 投票:0回答:0

我最近尝试编写(在 ChatGPT 的帮助下)一个 python 代码,绘制一个由 3D 球体表示的行星及其从互联网上获取的表面图像。 代码有效,但不是我想要的:绘制了带有行星表面的 3D 球体,但结果是不可接受的,正如您在图像中发现的那样,网格不够精细,无法清晰地表示表面. 这是图片:image 在函数中,我只能添加到地球表面的链接。

这是函数:

import numpy as np
import imageio
'''
 plot_planet - returns a 3d sphere with all the planets belong to the solar system and the sun. 
 
 Prototype: plot_planet('planet', ax)

 AUTHOR: Giovanni Facchinetti, 2023
 
'''


def plot_planet(planet_name, ax):
    # Define planet properties
    planets = {
        'sun': {
            'radius': 695700.0,  # km
            'color': 'yellow',
            'texture': '...'
        },
        'mercury': {
            'radius': 2439.7,  # km
            'color': 'gray',
            'texture': '...'
        },
        'venus': {
            'radius': 6051.8,  # km
            'color': 'orange',
            'texture': '...'
        },
        'earth': {
            'radius': 6371.0,  # km
            'color': 'blue',
            'texture': 'https://www.solarsystemscope.com/textures/download/8k_earth_daymap.jpg'

        },
        'mars': {
            'radius': 3389.5,  # km
            'color': 'red',
            'texture': '...'
        },
        'jupiter': {
            'radius': 69911.0,  # km
            'color': 'brown',
            'texture': '...'
        },
        'saturn': {
            'radius': 58232.0,  # km
            'color': 'goldenrod',
            'texture': '...'
        },
        'uranus': {
            'radius': 25362.0,  # km
            'color': 'cyan',
            'texture': '...'
        },
        'neptune': {
            'radius': 24622.0,  # km
            'color': 'blueviolet',
            'texture': '...'
        },
        'pluto': {
            'radius': 1188.3,  # km
            'color': 'gray',
                    },
    }

    # Get planet properties
    planet = planets.get(planet_name)
    if planet is None:
        raise ValueError(f'Invalid planet name: {planet_name}')

    # Create planet
    u, v = np.mgrid[0:2 * np.pi:100j, 0:np.pi:100j]
    x = planet['radius'] * np.cos(u) * np.sin(v)
    y = planet['radius'] * np.sin(v) * np.sin(u)
    z = planet['radius'] * np.cos(v)

    if 'texture' in planet:
        # Load the image from the internet URL
        image_url = planet['texture']
        image = imageio.imread(image_url)

        # Flip the image vertically
        image = np.flipud(image)
        # Set the texture coordinates based on the sphere coordinates
        phi = np.arctan2(y, x)
        theta = np.arccos(z / planet['radius'])

        # Convert texture coordinates to pixel coordinates
        texture_x = (phi + np.pi) / (2 * np.pi) * image.shape[1]
        texture_y = (np.pi - theta) / np.pi * (image.shape[0] - 1)

        # Make sure the image array is large enough
        image = np.pad(image,
                       [(max(0, int(texture_y.max() - image.shape[0])) // 2,
                         max(0, int(texture_y.max() - image.shape[0])) // 2 + max(0, int(texture_y.max() - image.shape[
                             0])) % 2),
                        (0, max(0, int(texture_x.max() - image.shape[1]))),
                        (0, 0)], mode='edge')

        # Sample the texture at the given coordinates
        texture = image[np.clip(texture_y.astype(int), 0, image.shape[0] - 1), np.clip(texture_x.astype(int), 0,
                                                                                       image.shape[1] - 1)]
        # Plot the textured sphere
        ax.plot_surface(x, y, z, facecolors=texture / 255.0, shade=True)

    else:
        # Plot the solid-colored sphere
        ax.plot_surface(x, y, z, rstride=1, cstride=1, color=planet['color'], alpha=0.5)
    

要绘制地球,您可以尝试运行此代码:

from plot_planet import plot_planet
import matplotlib.pyplot as plt

fig = plt.figure(figsize=(13, 18))

# Plot the orbit
ax1 = fig.add_subplot(projection='3d')
plot_planet('earth', ax1)
ax1.axis('equal')
plt.show()

请注意,我已经尝试增加网格数,但这不是正确的做法,因为:

  1. 结果不变
  2. 计算成本增加

我想要的是在表面上可视化从互联网上拍摄的相同图像(即 8k 质量)。

非常感谢任何建议

python plot surface
© www.soinside.com 2019 - 2024. All rights reserved.