You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

133 lines
4.3 KiB

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

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()