Я написал следующий код, чтобы повернуть кривую на указанный угол и вернуть новое уравнение. Я знаю, что когда мы хотим повернуть оси на угол A, новые координаты становятся X=xcosA-ysinA и Y=xsinA+ycosA. когда я проверяю свой fxn на гиперболе x^2+y^2=1. Ожидаемые уравнения: 2xy-1=0, но мой fxn дает -2xy-1=0. Где я делаю неправильно?
import sympy as sp
@display_mathjax_and_replace
def rotate(f,theta):
x, y, a, b = sp.symbols('x y a b')
rotation_matrix = sp.Matrix([[sp.cos(theta),-sp.sin(theta)],[sp.sin(theta), sp.cos(theta)]])
transformed_coords = rotation_matrix * sp.Matrix([a, b])
g = f.subs({x: transformed_coords[0], y: transformed_coords[1]})
return g
Я создал следующий декоратор, чтобы красиво представить его:
def display_mathjax_and_replace(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
result = result.subs({'a': 'x', 'b': 'y'})
simplified_expr = sp.simplify(result)
display(Math(sp.latex(sp.Eq(simplified_expr, 0))))
return wrapper
Я называю свой код:
x,y = sp.symbols('x y')
f = x**2 - y**2 -1
rotate(f,sp.pi/4)
Выход: -2xy-1
Ожидаемый результат: 2xy-1
Вы поменяли знак в членах sin
матрицы преобразования. Вот как это должно выглядеть для положительного вращения:
def rotate_1(f, theta):
x, y, a, b = sp.symbols('x y a b')
rotation_matrix = sp.Matrix([[sp.cos(theta),sp.sin(theta)],[-sp.sin(theta), sp.cos(theta)]])
transformed_coords = rotation_matrix * sp.Matrix([a, b])
g = f.subs({x: transformed_coords[0], y: transformed_coords[1]})
return g
rotate(f, sp.pi/4).simplify()
# out: 2*a*b - 1
Если вы используете SymPy Plotting Backend и интерактивную среду, такую как Jupyter Notebook, вы можете выполнить красивую визуализацию, которая поможет вам обнаружить любую возможную ошибку. Например:
%matplotlib widget
from sympy import *
from spb import *
def symbolic_rotate(f, theta, x, y):
a, b = var("a, b")
rotation_matrix = Matrix([[cos(theta),sin(theta)],[-sin(theta), cos(theta)]])
transformed_coords = rotation_matrix * Matrix([a, b])
g = f.subs({x: transformed_coords[0], y: transformed_coords[1]})
g = g.subs({a: x, b: y})
return g
var("x, y, theta, a, b")
f = x**2 - y**2 -1
graphics(
implicit_2d(f, (x, -10, 10), (y, -10, 10), label = "f"),
implicit_2d(symbolic_rotate(f, theta, x, y), (x, -10, 10), (y, -10, 10), label = "f rot",
params = {theta: (pi/6, 0, 2*pi)}),
aspect = "equal"
)
symbolic_rotate
создает новое выражение на основе символического угла поворота. Затем мы можем построить исходную и повернутую гиперболу и поиграть с ползунком. Здесь вы можете визуально проверить правильность матрицы преобразования.
Матрица вращения неверна.
Это происходит как
X=xcosA+ysinA
и
Y=-xsinA+ycosA
.
Для вращения против часовой стрелки.