2016-12-16 14 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 цикл, но установить x и y с точки зрения i, который является постоянным после первого цикла ,

  2. Вы устанавливаете угол поворота в градусах. Однако для тригонометрических функций требуется угол, заданный в радиантах. Поэтому в основном вам нужно умножить угол на 2pi.

Третья точка, которая не является действительно проблемой, но делает сценарий трудно читать, что вы вернетесь 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