计算三边求其他,两角一边求其他,可求边,角,各角的sin,cos,tan值,以及周长和面积
Python代码:
import tkinter as tk
from tkinter import messagebox
import math
class TriangleCalculator:
def __init__(self, root):
self.root = root
self.root.title("三角形计算器")
self.create_widgets()
def create_widgets(self):
self.frame = tk.Frame(self.root)
self.frame.pack(padx=10, pady=10)
self.input_labels = ['边a', '边b', '边c', '角A (°)', '角B (°)', '角C (°)', 'sinA', 'cosA', 'tanA', 'sinB', 'cosB', 'tanB', 'sinC', 'cosC', 'tanC', '高ha', '高hb', '高hc', '面积', '周长']
self.inputs = {}
row = 0
for label in self.input_labels:
tk.Label(self.frame, text=label).grid(row=row, column=0)
self.inputs[label] = tk.Entry(self.frame)
self.inputs[label].grid(row=row, column=1)
row += 1
self.calculate_button = tk.Button(self.frame, text="计算", command=self.calculate)
self.calculate_button.grid(row=row, column=0, columnspan=2, pady=(10, 0))
row += 1
self.clear_button = tk.Button(self.frame, text="清除", command=self.clear)
self.clear_button.grid(row=row, column=0, columnspan=2, pady=(10, 0))
self.add_custom_keyboard()
def add_custom_keyboard(self):
self.keyboard_frame = tk.Frame(self.root)
self.keyboard_frame.pack(padx=10, pady=10)
buttons = [
('√', self.insert_sqrt),
('°', self.insert_degree),
]
row = 0
col = 0
for (text, command) in buttons:
button = tk.Button(self.keyboard_frame, text=text, command=command)
button.grid(row=row, column=col, padx=5, pady=5)
col += 1
def insert_sqrt(self):
self.insert_text('√')
def insert_degree(self):
self.insert_text('°')
def insert_text(self, text):
widget = self.root.focus_get()
if isinstance(widget, tk.Entry):
widget.insert(tk.END, text)
def calculate(self):
try:
a = self.try_parse(self.inputs['边a'].get())
b = self.try_parse(self.inputs['边b'].get())
c = self.try_parse(self.inputs['边c'].get())
A = self.try_parse(self.inputs['角A (°)'].get(), degrees=True)
B = self.try_parse(self.inputs['角B (°)'].get(), degrees=True)
C = self.try_parse(self.inputs['角C (°)'].get(), degrees=True)
calculated = False
if None not in (a, b, c): # 三边已知
A = math.degrees(math.acos((b**2 + c**2 - a**2) / (2 * b * c)))
B = math.degrees(math.acos((a**2 + c**2 - b**2) / (2 * a * c)))
C = 180 - A - B
calculated = True
elif A is not None and B is not None and a is not None: # 两角一边已知 (角A, 角B, 边a)
C = 180 - A - B
if C > 0:
b = a * math.sin(math.radians(B)) / math.sin(math.radians(A))
c = a * math.sin(math.radians(C)) / math.sin(math.radians(A))
calculated = True
elif A is not None and B is not None and b is not None: # 两角一边已知 (角A, 角B, 边b)
C = 180 - A - B
if C > 0:
a = b * math.sin(math.radians(A)) / math.sin(math.radians(B))
c = b * math.sin(math.radians(C)) / math.sin(math.radians(B))
calculated = True
elif A is not None and C is not None and a is not None: # 两角一边已知 (角A, 角C, 边a)
B = 180 - A - C
if B > 0:
b = a * math.sin(math.radians(B)) / math.sin(math.radians(A))
c = a * math.sin(math.radians(C)) / math.sin(math.radians(A))
calculated = True
elif A is not None and C is not None and b is not None: # 两角一边已知 (角A, 角C, 边b)
B = 180 - A - C
if B > 0:
a = b * math.sin(math.radians(A)) / math.sin(math.radians(B))
c = b * math.sin(math.radians(C)) / math.sin(math.radians(B))
calculated = True
elif B is not None and C is not None and a is not None: # 两角一边已知 (角B, 角C, 边a)
A = 180 - B - C
if A > 0:
b = a * math.sin(math.radians(B)) / math.sin(math.radians(A))
c = a * math.sin(math.radians(C)) / math.sin(math.radians(A))
calculated = True
elif B is not None and C is not None and b is not None: # 两角一边已知 (角B, 角C, 边b)
A = 180 - B - C
if A > 0:
a = b * math.sin(math.radians(A)) / math.sin(math.radians(B))
c = b * math.sin(math.radians(C)) / math.sin(math.radians(B))
calculated = True
elif None not in (a, b, A): # 两边夹一角
C = math.degrees(math.acos((a**2 + b**2 - c**2) / (2 * a * b)))
B = 180 - A - C
c = math.sqrt(a**2 + b**2 - 2 * a * b * math.cos(math.radians(C)))
calculated = True
elif None not in (a, c, A): # SSA情况
B = math.degrees(math.asin(b * math.sin(math.radians(A)) / a))
C = 180 - A - B
calculated = True
elif None not in (b, c, B): # SSA情况
A = math.degrees(math.asin(a * math.sin(math.radians(B)) / c))
C = 180 - A - B
calculated = True
elif A is not None and B is not None and c is not None: # AAS情况
C = 180 - A - B
if C > 0:
a = c * math.sin(math.radians(A)) / math.sin(math.radians(C))
b = c * math.sin(math.radians(B)) / math.sin(math.radians(C))
calculated = True
elif A is not None and C is not None and b is not None: # AAS情况
B = 180 - A - C
if B > 0:
a = b * math.sin(math.radians(A)) / math.sin(math.radians(B))
c = b * math.sin(math.radians(C)) / math.sin(math.radians(B))
calculated = True
elif B is not None and C is not None and a is not None: # AAS情况
A = 180 - B - C
if A > 0:
b = a * math.sin(math.radians(B)) / math.sin(math.radians(A))
c = a * math.sin(math.radians(C)) / math.sin(math.radians(A))
calculated = True
if calculated:
self.clear_results()
self.inputs['角A (°)'].insert(0, f"{A:.2f}")
self.inputs['角B (°)'].insert(0, f"{B:.2f}")
self.inputs['角C (°)'].insert(0, f"{C:.2f}")
self.inputs['边a'].insert(0, f"{a:.2f}")
self.inputs['边b'].insert(0, f"{b:.2f}")
self.inputs['边c'].insert(0, f"{c:.2f}")
self.inputs['sinA'].insert(0, f"{math.sin(math.radians(A)):.2f}")
self.inputs['cosA'].insert(0, f"{math.cos(math.radians(A)):.2f}")
self.inputs['tanA'].insert(0, f"{math.tan(math.radians(A)):.2f}")
self.inputs['sinB'].insert(0, f"{math.sin(math.radians(B)):.2f}")
self.inputs['cosB'].insert(0, f"{math.cos(math.radians(B)):.2f}")
self.inputs['tanB'].insert(0, f"{math.tan(math.radians(B)):.2f}")
self.inputs['sinC'].insert(0, f"{math.sin(math.radians(C)):.2f}")
self.inputs['cosC'].insert(0, f"{math.cos(math.radians(C)):.2f}")
self.inputs['tanC'].insert(0, f"{math.tan(math.radians(C)):.2f}")
# 计算面积和周长
s = (a + b + c) / 2
area = math.sqrt(s * (s - a) * (s - b) * (s - c))
circumference = a + b + c
# 计算高
ha = 2 * area / a
hb = 2 * area / b
hc = 2 * area / c
self.inputs['高ha'].insert(0, f"{ha:.2f}")
self.inputs['高hb'].insert(0, f"{hb:.2f}")
self.inputs['高hc'].insert(0, f"{hc:.2f}")
self.inputs['面积'].insert(0, f"{area:.2f}")
self.inputs['周长'].insert(0, f"{circumference:.2f}")
else:
messagebox.showerror("输入错误", "输入值不足或无效,请确保至少有一个完整的'两边加一个非夹角'或'一边加两非夹角'的数据输入。")
except ValueError as ve:
messagebox.showerror("数值错误", str(ve))
except Exception as e:
messagebox.showerror("计算错误", str(e))
def try_parse(self, value, degrees=False):
if not value:
return None
if '√' in value:
value = value.replace('√', '')
value = math.sqrt(float(value))
elif '°' in value:
value = value.replace('°', '')
value = float(value)
else:
value = float(value)
if degrees:
return value
return value
def clear(self):
for entry in self.inputs.values():
entry.delete(0, tk.END)
self.clear_results()
def clear_results(self):
for entry in self.inputs.values():
entry.delete(0, tk.END)
if __name__ == "__main__":
root = tk.Tk()
app = TriangleCalculator(root)
root.mainloop()