2016-12-16 170 views
2

我想在2D空间中旋转一个图形(由线组成)。我使用这种技巧: (1)我在原点翻译图形。旋转点在(0,0) (2)我执行旋转 (3)我把图回来使用matplotlib旋转矩阵使用旋转矩阵

问题来自我的旋转功能。不知道为什么它不起作用,因为我使用了旋转矩阵。您不需要必须查看整个代码,只需查看“旋转”功能和“动画”功能即可。你会看到我发表评论来帮助你。

如果你执行整件事,你会看到一条线缓慢移动。我不知道它是什么,但它不是预期的结果。我应该看到我的身影旋转。

如果你不做旋转,只是翻译两次(步骤(1)和步骤(3)我的过程),你会看到整个数字不移动(这是预计,因为我把它移动到中心和把它放在原来的位置),你可以看到这个图形的样子。所以唯一的问题来自旋转功能。

import numpy as np 
from matplotlib import pyplot as plt 
from matplotlib import animation 
import pylab as pl 
import math 

#Deplacement de la base pour pouvoir utiliser la matrice de rotation 
def center(x,y,c): 
    for i in range(len(x)): 
     x[i] = x[i] - c[0] 
    for i in range(len(y)): 
     y[i] = y[i] - c[1] 
    return None 

#Remettre la base à sa place 
def recenter(x,y,c): 
    for i in range(len(x)): 
     x[i] = x[i] + c[0] 
    for i in range(len(y)): 
     y[i] = y[i] + c[1] 
    return None 

#Rotation 
def rotation(x,y,angle): 
    my_list = [[],[]] 
    for i in range(len(x)): 
     my_list[0].append(x[i]*math.cos(angle) + y[i]*math.sin(angle)) 
    for j in range(len(y)): 
     my_list[1].append(x[i]*math.sin(angle)*(-1) + y[i]*math.cos(angle)) 
    return my_list 

#Here is the rotation matrix 
#cos sin 
#-sin cos 

# First set up the figure, the axis, and the plot element we want to animate 
fig = plt.figure() 
ax = plt.axes(xlim=(-125, 125), ylim=(-250, 250)) 
line, = ax.plot([], [], lw=2) 

#Les lignes du tableau 
plt.plot([0, 125], [50, 50], color='k', linestyle='-', linewidth=2) 
plt.plot([0, 125], [200, 200], color='k', linestyle='-', linewidth=2) 
plt.plot([17.5, 107.5], [80, 80], color='k', linestyle='-', linewidth=2) 
plt.plot([17.5, 107.5], [110, 110], color='k', linestyle='-', linewidth=2) 
plt.plot([17.5, 107.5], [140, 140], color='k', linestyle='-', linewidth=2) 
plt.plot([17.5, 107.5], [170, 170], color='k', linestyle='-', linewidth=2) 
plt.plot([17.5, 17.5], [80, 170], color='k', linestyle='-', linewidth=2) 
plt.plot([17.5, 17.5], [80, 170], color='k', linestyle='-', linewidth=2) 
plt.plot([47.5, 47.5], [80, 170], color='k', linestyle='-', linewidth=2) 
plt.plot([77.5, 77.5], [80, 170], color='k', linestyle='-', linewidth=2) 
plt.plot([107.5, 107.5], [80, 170], color='k', linestyle='-', linewidth=2) 

# initialization function: plot the background of each frame 
def init(): 
    line.set_data([], []) 
    return line, 

# animation function. This is called sequentially 
def animate(i): 
    c1 = 62.5 
    c2 = 10 
    pt_rot = (c1, c2) #Point from which I want to rotate 
    x = [47.5, 47.5, 77.5, 77.5, 47.5, 62.5, c1, 57.5, 67.5] 
    y = [15, 45, 45, 15, 15, 15, c2, 10, 10] 

    center(x,y,pt_rot) 
    #Uncomment these 3 following lines to test the double translation 
    my_list = rotation(x,y,(i/180)) 
    x = my_list[0] 
    y = my_list[1] 
    recenter(x, y, pt_rot) 

    line.set_data(x,y) 

    return line, 

# call the animator. blit=True means only re-draw the parts that have changed. 
anim = animation.FuncAnimation(fig, animate, init_func=init, 
           frames=200, interval=20, blit=True) 

plt.show() 
+0

函数'angle_position'的作用是什么?它从未在脚本中调用过。你问题的最后一段似乎是重要的一段。然而,这也是最不理解的一个。为什么翻译不能移动任何东西呢?整个问题到底是什么?如果线条旋转,它应该做什么,更正?当我运行你的代码时,我没有看到任何旋转。试着在你的问题中写下“预期的行为:<一些句子>”和“观察到的行为:<一些句子>”来澄清。 – ImportanceOfBeingErnest

+0

对不起,我会在问题中做出更加精确的更改。 –

+0

我想我回答你所有的问题: –

回答

1

有在脚本中两个主要问题:

  1. 在旋转功能,你让j循环,但在i方面树立xy,这是第一循环结束后的恒定。

  2. 您可以用度数设置旋转角度。但是,三角函数需要辐射体中设置的角度。所以基本上你需要将角度乘以2π。

第三点,这是不是一个真正的问题,但使脚本难以阅读的是,你在翻译函数返回None。如果每个函数都返回一些值,并且将这些值返回到下一个函数,我发现它更易于阅读。

这是一个完整的可运行脚本。

import numpy as np 
from matplotlib import pyplot as plt 
from matplotlib import animation 
import math 


def center(x,y,c): 
    for i in range(len(x)): 
     x[i] = x[i] - c[0] 
    for i in range(len(y)): 
     y[i] = y[i] - c[1] 
    # return x,y <--------------------- here 
    return x,y 

def recenter(x,y,c): 
    for i in range(len(x)): 
     x[i] = x[i] + c[0] 
    for i in range(len(y)): 
     y[i] = y[i] + c[1] 
    # return x,y <--------------------- here 
    return x,y 

def rotation(x,y,angle): 
    my_list = [[],[]] 
    for i in range(len(x)): 
     my_list[0].append(x[i]*math.cos(angle) + y[i]*math.sin(angle)) 
    for j in range(len(y)): 
     #Big mistake here, replace i by j <--------------------- here 
     my_list[1].append(x[j]*math.sin(angle)*(-1.) + y[j]*math.cos(angle)) 
    return my_list[0], my_list[1] 



fig = plt.figure() 
ax = plt.axes(xlim=(10, 110), ylim=(-40, 60)) 
ax.set_aspect('equal') 
line, = ax.plot([],[], lw=2) 

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

def animate(i): 
    c1 = 62.5 
    c2 = 10 
    pt_rot = (c1, c2) 
    x = [47.5, 47.5, 77.5, 77.5, 47.5, 62.5, c1, 57.5, 67.5] 
    y = [15, 45, 45, 15, 15, 15, c2, 10, 10] 

    x,y = center(x,y,pt_rot) # <--------------------- here 
    x,y = rotation(x,y,(i/180.)*np.pi) # <------------ here 
    x,y = recenter(x, y, pt_rot) # <------------------ here 

    line.set_data(x,y) 
    return line, 


anim = animation.FuncAnimation(fig, animate, init_func=init, 
           frames=359, interval=20, blit=True) 

plt.show() 
+0

谢谢。这是一个愚蠢的错误。我会按照您的建议返回“无”。 –

+0

如果这解决了您的问题,您可以[接受答案](http://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work),使问题不会留在未解决的名单。 – ImportanceOfBeingErnest