You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python实现曲线旋转时符号错误问题排查

问题

我写了以下Python代码,用来把曲线按指定角度旋转并返回新方程。已知坐标轴旋转角度A时,新坐标为X = xcosA - ysinA、Y = xsinA + ycosA。用双曲线x² - y² = 1测试函数时,预期方程是2xy - 1 = 0,但函数输出-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


错误原因

问题出在旋转方向搞反了。你现在的代码逻辑是:把原方程里的x,y替换成了「坐标轴旋转θ后的新坐标」,但实际我们需要的是「将旋转后的曲线的坐标(a,b)转换回原坐标系的坐标」代入原方程。

简单说:

  • 你用的矩阵是点逆时针旋转θ的变换,但曲线旋转θ角等价于坐标轴反向旋转θ,所以应该用旋转矩阵的逆变换(旋转矩阵是正交矩阵,逆矩阵等于转置,也等价于旋转-θ的矩阵)。

当你想得到曲线旋转θ后的方程时,正确的替换逻辑是:假设旋转后的点坐标是(a,b),那么它在原坐标系中的对应点(x,y)是(a,b)反向旋转θ后的结果,即:

x = a*cosθ + b*sinθ
y = -a*sinθ + b*cosθ

而不是你现在用的x = a*cosθ - b*sinθ、y = a*sinθ + b*cosθ。


修正方案

把旋转矩阵换成逆矩阵(将θ换成-θ,或者直接取转置),修改后的rotate函数如下:

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

或者更直接地,跳过矩阵直接写出替换式:

import sympy as sp
@display_mathjax_and_replace
def rotate(f,theta):
   x, y, a, b = sp.symbols('x y a b')
   # 原坐标x,y由新坐标a,b反向旋转得到
   x_transformed = a*sp.cos(theta) + b*sp.sin(theta)
   y_transformed = -a*sp.sin(theta) + b*sp.cos(theta)
   g = f.subs({x: x_transformed, y: y_transformed})
   return g

验证结果

运行修正后的代码,调用rotate(f, sp.pi/4)会输出预期的2xy - 1 = 0,符合要求。


内容的提问来源于stack exchange,提问作者Prince Yadav

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.18 22:41:07