极地动画

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

我有这个任务:使用极坐标创建一个心形动画。从画一颗心开始,然后添加动画作为下一步;使用渲染角度的可变增加。 然后我需要以同样的方式在极坐标中构建其他图形。 我还需要将绘图功能与图形分开,这样就可以用最少的代码更改来更改图形

我尝试运行这个,输出看起来很奇怪,当我改变 theta 和 r 时,其他数字看起来并不像预期的那样。我不确定是否可以使用 tkinter 或 pygame 或类似的东西来完成此任务。如果您能提出任何想法来完成此任务,我将很高兴。

import matplotlib.pyplot as plt
import numpy as np
import matplotlib.animation as animation

fig = plt.figure()
ax = fig.add_subplot(111, polar=True)

theta = np.linspace(0, 2*np.pi, 100)
r = 1 - (np.abs(theta) - 1) ** 2

line, = ax.plot([], [], color='red')

def init():
line.set_data([], [])
return line,

def animate(i):
    current_theta = theta[:i]
    current_r = r[:i]
    x_polar = current_r * np.cos(current_theta)
    y_polar = current_r * np.sin(current_theta)
    line.set_data(x_polar, y_polar)
    return line,

ani = animation.FuncAnimation(fig, animate, init_func=init, frames=len(theta), interval=50, blit=True)

plt.show()
python matplotlib tkinter polar-coordinates matplotlib-animation
2个回答
0
投票

您似乎使用了错误的半径表达式。您的半径与 theta 的平方成正比,并且随着 theta 的增加而变得非常负,这无法在极坐标图中表示。您很可能缺少正弦或余弦。玩了一下,我发现

r = 1 - (np.abs(np.cos(theta)) - 1) ** 2
可以产生心形。

一般来说,计算 theta 和 r(极坐标图的坐标),然后对图进行诸如笛卡尔坐标(x_极坐标和 y_极坐标)转换之类的操作,这对我来说似乎很奇怪。

关于分离问题,将半径的计算移出animate函数。动画函数应该只负责更新绘图:

def heart(theta):
    return 1 - (np.abs(np.cos(theta)) - 1) ** 2

def cardiod(theta):
    return 0.5 * (1 - np.sin(theta))

theta = np.linspace(0, 2*np.pi, 100)
r = heart(theta)

# transformation needed for your example
theta, r = r * np.cos(theta), r * np.sin(theta)

# test of the cardiod function; this function does not need any transformation afterwards
# r = cardiod(theta)


def animate(i):
    current_theta = theta[:i]
    current_r = r[:i]
    line.set_data(current_theta, current_r)
    return line,

我为维基百科上的Cardioid添加了一个函数,即“心脏曲线”,作为准备多个函数的示例。


0
投票

我又写了一个代码:

# Import modules
import numpy as np 
import matplotlib.pyplot as plt 
from matplotlib.animation import FuncAnimation
# ------------------------------------------ #
  
# Define the figure
fig = plt.figure(figsize=(16,16))
# Setting the axes projection as polar 
ax = fig.add_subplot(111, projection='polar')

# Define the heart equation from https://pavpanchekha.com/blog/heart-polar-coordinates.html
t = np.linspace(0.0, 2.0*np.pi, 200, endpoint=True)
r = np.sin(t)*np.sqrt(np.abs(np.cos(t))) / (np.sin(t) + 7/5) - 2*np.sin(t) + 2

# Define a list that stores temporary data points
# [[theta], [radius]]
data_points = [[], []]

# Define the index of the last data point that needs to be plotted
# For example, if index = 5, data_points[0][-1] = t[5] and data_points[1][-1] = r[5]
index = 0

def animate(i):
     # Global variables
     global data_points, index

     # Clear the plot
     ax.clear()

     # Remove tick labels
     ax.set_xticklabels([])
     ax.set_yticklabels([])

     # Append a data point to the list
     data_points[0].append(t[index])
     data_points[1].append(r[index])

     # Update the index
     index += 1

     # Reset the index and points 
     # if index is out of range
     if (index == len(t)):
          index = 0
          data_points = [[], []]
          
     # Plot the "heart"
     plt.plot(data_points[0], data_points[1], color="red")

     # Define the limits
     ax.set_rlim(min(r), max(r))

     # Remove border
     #ax.axis("off")

# Calling the animation function
ani1 = FuncAnimation(fig, animate, interval=30)

# Display the plot
plt.show()

这会产生:(您必须增加 theta 数组中的点数以获得更好的平滑线)

将您编写代码的方式更改为我的...我希望这会有所帮助!

© www.soinside.com 2019 - 2024. All rights reserved.