|
|
from sympy import *
|
|
|
from convert_formula import *
|
|
|
|
|
|
def xy_to_polar(formula):
|
|
|
"""
|
|
|
把直角坐标方程转换为极坐标方程
|
|
|
:param formula: 直角坐标方程
|
|
|
:return: 极坐标方程
|
|
|
"""
|
|
|
formula = convert_formula(formula)
|
|
|
formula = formula.replace('x', '(r*cos(theta))')
|
|
|
formula = formula.replace('y', '(r*sin(theta))')
|
|
|
l = formula.split('=')
|
|
|
r, theta = symbols('r theta')
|
|
|
expr = sympify(l[0] + '-(' + l[1] + ')', evaluate=False)
|
|
|
left = trigsimp(radsimp(expand_trig(expr)))
|
|
|
return factor(left)
|
|
|
|
|
|
def polar_to_xy(formula):
|
|
|
"""
|
|
|
把极坐标方程转换为直角坐标方程
|
|
|
:param formula: 极坐标方程
|
|
|
:return: 直角坐标方程
|
|
|
"""
|
|
|
formula = convert_formula(formula)
|
|
|
formula = formula.replace('r', 'sqrt(x**2+y**2)')
|
|
|
formula = formula.replace('theta', 'atan2(y,x)') # 使用atan2替代arctan以处理全象限
|
|
|
l = formula.split('=')
|
|
|
x, y = symbols('x y')
|
|
|
expr = sympify(l[0] + '-(' + l[1] + ')', evaluate=False)
|
|
|
left = trigsimp(radsimp(expr.rewrite(sin))) # 重写为sin以优化三角表达式
|
|
|
return factor(left)
|
|
|
|
|
|
def t_to_xy(xf, yf):
|
|
|
"""
|
|
|
把参数方程转换为直角坐标方程
|
|
|
:param xf: 参数方程的x坐标
|
|
|
:param yf: 参数方程的y坐标
|
|
|
:return: 直角坐标方程
|
|
|
"""
|
|
|
xf = convert_formula(xf)
|
|
|
yf = convert_formula(yf)
|
|
|
xl = xf.split('=')
|
|
|
x, t = symbols('x t')
|
|
|
eq = Eq(sympify(xl[0]), sympify(xl[1]))
|
|
|
tl = solve(eq, t, domain=S.Reals)
|
|
|
if not tl:
|
|
|
raise ValueError("无法消去参数t")
|
|
|
# 选择最简单的解
|
|
|
t_solution = tl[0] if len(tl) == 1 else min(tl, key=lambda sol: len(str(sol)))
|
|
|
yf = yf.replace('t', str(t_solution))
|
|
|
yl = yf.split('=')
|
|
|
y = symbols('y')
|
|
|
eq2 = Eq(sympify(yl[0]), sympify(yl[1]))
|
|
|
return simplify(factor(eq2))
|
|
|
|
|
|
def xy_to_t(formula):
|
|
|
"""
|
|
|
把直角坐标方程转换为参数方程
|
|
|
:param formula: 直角坐标方程
|
|
|
:return: 参数方程
|
|
|
"""
|
|
|
formula = convert_formula(formula)
|
|
|
l = formula.split('=')
|
|
|
x, y = symbols('x y')
|
|
|
eq = Eq(sympify(l[0]), sympify(l[1]))
|
|
|
l2 = solve(eq, y, domain=S.Reals)
|
|
|
if not l2:
|
|
|
raise ValueError("无法求解y")
|
|
|
# 选择最简单的解
|
|
|
y_solution = l2[0] if len(l2) == 1 else min(l2, key=lambda sol: len(str(sol)))
|
|
|
return Eq(y, factor(simplify(y_solution)))
|
|
|
|
|
|
def t_to_polar(xf, yf):
|
|
|
"""
|
|
|
把参数方程转换为极坐标方程
|
|
|
:param xf: 参数方程的x坐标
|
|
|
:param yf: 参数方程的y坐标
|
|
|
:return: 极坐标方程
|
|
|
"""
|
|
|
xy = t_to_xy(xf, yf)
|
|
|
xy = str(xy).lstrip('Eq(')[:-1].replace(", ","=")
|
|
|
return xy_to_polar(xy)
|
|
|
|
|
|
def polar_to_t(formula):
|
|
|
"""
|
|
|
把极坐标方程转换为参数方程
|
|
|
:param formula: 极坐标方程
|
|
|
:return: 参数方程
|
|
|
"""
|
|
|
xy = polar_to_xy(formula)
|
|
|
xy = str(xy) + '=0'
|
|
|
return xy_to_t(xy)
|
|
|
|
|
|
def UI():
|
|
|
while True:
|
|
|
fr = input("请选择输入方程类型 1.直角坐标方程 2.参数方程 3.极坐标方程 q.退出: ")
|
|
|
if fr == "q":
|
|
|
break
|
|
|
if fr == "2":
|
|
|
xin = input("请输入x,格式x=x(t): ")
|
|
|
yin = input("请输入y,格式y=y(t): ")
|
|
|
else:
|
|
|
forin = input("请输入方程: ")
|
|
|
to = input("请选择输出方程类型 1.直角坐标方程 2.参数方程 3.极坐标方程: ")
|
|
|
if fr == to:
|
|
|
print("输入和输出的方程类型不能相同")
|
|
|
else:
|
|
|
try:
|
|
|
if fr == "1":
|
|
|
if to == "2":
|
|
|
print("x = t")
|
|
|
print("y =")
|
|
|
pprint(xy_to_t(forin))
|
|
|
elif to == "3":
|
|
|
pprint(Eq(xy_to_polar(forin), 0))
|
|
|
elif fr == "2":
|
|
|
if to == "1":
|
|
|
pprint(t_to_xy(xin, yin))
|
|
|
elif to == "3":
|
|
|
pprint(Eq(t_to_polar(xin, yin), 0))
|
|
|
elif fr == "3":
|
|
|
if to == "1":
|
|
|
pprint(Eq(polar_to_xy(forin), 0))
|
|
|
elif to == "2":
|
|
|
print("x = t")
|
|
|
print("y =")
|
|
|
pprint(polar_to_t(forin))
|
|
|
except Exception as e:
|
|
|
print(f"错误: {e}")
|
|
|
|
|
|
if __name__ == '__main__':
|
|
|
UI() |