import streamlit as st import numpy as np import plotly.graph_objects as go import plotly.express as px import pandas as pd from math import sin, cos, tan, asin, acos, atan2, sqrt, degrees, radians, pi import time def calculate_triangle_area(a, b, c): """Calculate triangle area using Heron's formula""" s = (a + b + c) / 2 # semi-perimeter area = sqrt(s * (s - a) * (s - b) * (s - c)) return area def draw_triangle(side_a, side_b, side_c, angle_A, angle_B, angle_C, title="Triangle"): """Draw a triangle with labeled sides and angles using Plotly""" # Place vertices (C at origin, B on x-axis) C = np.array([0, 0]) B = np.array([side_a, 0]) A = np.array([side_b * cos(radians(angle_C)), side_b * sin(radians(angle_C))]) # Create triangle coordinates for plotting triangle_x = [A[0], B[0], C[0], A[0]] # Close the triangle triangle_y = [A[1], B[1], C[1], A[1]] # Create the figure fig = go.Figure() # Add triangle fill fig.add_trace(go.Scatter( x=triangle_x, y=triangle_y, fill='toself', fillcolor='rgba(173, 216, 230, 0.3)', line=dict(color='blue', width=3), mode='lines', name='Triangle', showlegend=False )) # Add vertices fig.add_trace(go.Scatter( x=[A[0]], y=[A[1]], mode='markers+text', marker=dict(color='red', size=12), text=['A'], textposition='top center', textfont=dict(size=16, color='black'), name='Vertex A', showlegend=True )) fig.add_trace(go.Scatter( x=[B[0]], y=[B[1]], mode='markers+text', marker=dict(color='green', size=12), text=['B'], textposition='bottom center', textfont=dict(size=16, color='black'), name='Vertex B', showlegend=True )) fig.add_trace(go.Scatter( x=[C[0]], y=[C[1]], mode='markers+text', marker=dict(color='blue', size=12), text=['C'], textposition='middle left', textfont=dict(size=16, color='black'), name='Vertex C', showlegend=True )) # Calculate midpoints for side labels mid_AB = (A + B) / 2 mid_BC = (B + C) / 2 mid_CA = (C + A) / 2 # Add side labels fig.add_trace(go.Scatter( x=[mid_AB[0]], y=[mid_AB[1]], mode='text', text=[f'c = {side_c:.2f}'], textfont=dict(size=12, color='black'), textposition='top center', showlegend=False )) fig.add_trace(go.Scatter( x=[mid_BC[0]], y=[mid_BC[1]], mode='text', text=[f'a = {side_a:.2f}'], textfont=dict(size=12, color='black'), textposition='bottom center', showlegend=False )) fig.add_trace(go.Scatter( x=[mid_CA[0]], y=[mid_CA[1]], mode='text', text=[f'b = {side_b:.2f}'], textfont=dict(size=12, color='black'), textposition='middle left', showlegend=False )) # Add angle labels fig.add_trace(go.Scatter( x=[A[0] - 0.3], y=[A[1] - 0.3], mode='text', text=[f'∠A = {angle_A:.1f}°'], textfont=dict(size=10, color='black'), showlegend=False )) fig.add_trace(go.Scatter( x=[B[0] + 0.2], y=[B[1] + 0.2], mode='text', text=[f'∠B = {angle_B:.1f}°'], textfont=dict(size=10, color='black'), showlegend=False )) fig.add_trace(go.Scatter( x=[C[0] + 0.2], y=[C[1] + 0.2], mode='text', text=[f'∠C = {angle_C:.1f}°'], textfont=dict(size=10, color='black'), showlegend=False )) # Set layout all_x = [A[0], B[0], C[0]] all_y = [A[1], B[1], C[1]] margin = 1.0 fig.update_layout( title=dict(text=title, font=dict(size=18, color='black'), x=0.5), xaxis=dict( range=[min(all_x) - margin, max(all_x) + margin], showgrid=True, gridcolor='lightgray', zeroline=True, zerolinecolor='gray' ), yaxis=dict( range=[min(all_y) - margin, max(all_y) + margin], showgrid=True, gridcolor='lightgray', zeroline=True, zerolinecolor='gray', scaleanchor="x", scaleratio=1 ), plot_bgcolor='white', paper_bgcolor='white', width=700, height=600, margin=dict(l=50, r=50, t=80, b=50) ) return fig def draw_vectors(a_x, a_y, b_x, b_y, angle_between): """Draw two vectors and show the angle between them using Plotly""" fig = go.Figure() # Draw vectors from origin fig.add_trace(go.Scatter( x=[0, a_x], y=[0, a_y], mode='lines+markers', line=dict(color='red', width=4), marker=dict(symbol='arrow', angle=90, size=15, color='red'), name=f'Vector A ({a_x:.2f}, {a_y:.2f})' )) fig.add_trace(go.Scatter( x=[0, b_x], y=[0, b_y], mode='lines+markers', line=dict(color='blue', width=4), marker=dict(symbol='arrow', angle=90, size=15, color='blue'), name=f'Vector B ({b_x:.2f}, {b_y:.2f})' )) # Create angle arc magnitude_a = sqrt(a_x**2 + a_y**2) magnitude_b = sqrt(b_x**2 + b_y**2) angle_a = atan2(a_y, a_x) angle_b = atan2(b_y, b_x) if angle_a < angle_b: arc_angles = np.linspace(angle_a, angle_b, 50) else: arc_angles = np.linspace(angle_b, angle_a, 50) arc_radius = min(magnitude_a, magnitude_b) * 0.3 arc_x = arc_radius * np.cos(arc_angles) arc_y = arc_radius * np.sin(arc_angles) # Add angle arc fig.add_trace(go.Scatter( x=arc_x, y=arc_y, mode='lines', line=dict(color='green', width=4), showlegend=False )) # Add angle label mid_angle = (angle_a + angle_b) / 2 label_x = (arc_radius + 0.5) * cos(mid_angle) label_y = (arc_radius + 0.5) * sin(mid_angle) fig.add_trace(go.Scatter( x=[label_x], y=[label_y], mode='text', text=[f'{angle_between:.1f}°'], textfont=dict(size=14, color='green'), showlegend=False )) # Add vector endpoint labels fig.add_trace(go.Scatter( x=[a_x], y=[a_y], mode='text', text=['A'], textfont=dict(size=16, color='red'), textposition='top right', showlegend=False )) fig.add_trace(go.Scatter( x=[b_x], y=[b_y], mode='text', text=['B'], textfont=dict(size=16, color='blue'), textposition='top right', showlegend=False )) # Set layout max_range = max(magnitude_a, magnitude_b) * 1.2 fig.update_layout( title=dict(text=f'Vectors with {angle_between:.1f}° angle between them', font=dict(size=18, color='black'), x=0.5), xaxis=dict( range=[-max_range * 0.1, max_range], showgrid=True, gridcolor='lightgray', zeroline=True, zerolinecolor='black', zerolinewidth=2 ), yaxis=dict( range=[-max_range * 0.1, max_range], showgrid=True, gridcolor='lightgray', zeroline=True, zerolinecolor='black', zerolinewidth=2, scaleanchor="x", scaleratio=1 ), plot_bgcolor='white', paper_bgcolor='white', width=700, height=600, margin=dict(l=50, r=50, t=80, b=50) ) return fig def law_of_sines_calculator(): st.header("📏 Law of Sines Calculator") st.markdown("**Formula:** a/sin(A) = b/sin(B) = c/sin(C)") st.markdown("**Equivalent:** sin(A)/a = sin(B)/b = sin(C)/c") # Add formula explanation with st.expander("📚 Understanding the Law of Sines"): st.markdown(""" The Law of Sines can be written in two equivalent forms: **Form 1:** a/sin(A) = b/sin(B) = c/sin(C) **Form 2:** sin(A)/a = sin(B)/b = sin(C)/c Both forms are mathematically identical and lead to the same calculations: - To find a side: side = (other_side × sin(opposite_angle)) / sin(known_angle) - To find an angle: sin(angle) = (opposite_side × sin(known_angle)) / known_side **Use the Law of Sines when you have:** - **AAS (Angle-Angle-Side)**: Two angles and one side - **ASA (Angle-Side-Angle)**: Two angles and the included side - **SSA (Side-Side-Angle)**: Two sides and one angle (ambiguous case) """) # Add a visual demonstration of the relationship with st.expander("🔍 See the calculation steps"): st.markdown(""" **Example calculation process:** If we know: angle A, angle B, and side a **Step 1:** Find angle C C = 180° - A - B **Step 2:** Use Law of Sines to find side b From: a/sin(A) = b/sin(B) Rearrange: b = (a × sin(B)) / sin(A) **Step 3:** Find side c From: a/sin(A) = c/sin(C) Rearrange: c = (a × sin(C)) / sin(A) """) col1, col2 = st.columns([1, 1]) with col1: st.subheader("📝 Input Triangle Data") known_case = st.selectbox( "What do you know about the triangle?", ["Two angles and one side (AAS/ASA)", "Two sides and one angle (SSA)"] ) if known_case == "Two angles and one side (AAS/ASA)": st.write("**Enter two angles and one side:**") angle_A = st.number_input("Angle A (degrees):", min_value=0.1, max_value=179.9, value=60.0, key="sines_angleA") angle_B = st.number_input("Angle B (degrees):", min_value=0.1, max_value=179.9, value=50.0, key="sines_angleB") side_a = st.number_input("Side a (opposite to angle A):", min_value=0.1, value=10.0, key="sines_sidea") # Calculate third angle angle_C = 180 - angle_A - angle_B if angle_C <= 0: st.error("❌ Invalid triangle! Sum of angles must be less than 180°") return # Calculate other sides using Law of Sines side_b = side_a * sin(radians(angle_B)) / sin(radians(angle_A)) side_c = side_a * sin(radians(angle_C)) / sin(radians(angle_A)) # Validate triangle if side_b <= 0 or side_c <= 0: st.error("❌ Invalid triangle! Check your inputs.") return else: # SSA case st.write("**Enter two sides and one angle (ambiguous case):**") side_a = st.number_input("Side a:", min_value=0.1, value=10.0, key="sines_ssa_sidea") side_b = st.number_input("Side b:", min_value=0.1, value=8.0, key="sines_ssa_sideb") angle_A = st.number_input("Angle A (opposite to side a):", min_value=0.1, max_value=179.9, value=60.0, key="sines_ssa_angleA") # Check for validity sin_B = side_b * sin(radians(angle_A)) / side_a if sin_B > 1: st.error("❌ No triangle possible with these measurements!") return elif abs(sin_B - 1) < 1e-10: # sin_B == 1 (within floating point precision) angle_B = 90.0 angle_C = 90 - angle_A side_c = side_a * cos(radians(angle_A)) st.info("✅ Right triangle solution found!") else: angle_B = degrees(asin(sin_B)) angle_C = 180 - angle_A - angle_B side_c = side_a * sin(radians(angle_C)) / sin(radians(angle_A)) # Check for ambiguous case if side_b < side_a and angle_A < 90: angle_B2 = 180 - angle_B angle_C2 = 180 - angle_A - angle_B2 if angle_C2 > 0: side_c2 = side_a * sin(radians(angle_C2)) / sin(radians(angle_A)) st.warning(f"⚠️ Ambiguous case! Two triangles possible:") st.write(f"**Triangle 1:** B = {angle_B:.2f}°, C = {angle_C:.2f}°, c = {side_c:.3f}") st.write(f"**Triangle 2:** B = {angle_B2:.2f}°, C = {angle_C2:.2f}°, c = {side_c2:.3f}") # Let user choose which triangle to display triangle_choice = st.radio("Choose triangle to visualize:", ["Triangle 1", "Triangle 2"]) if triangle_choice == "Triangle 2": angle_B, angle_C, side_c = angle_B2, angle_C2, side_c2 with col2: st.subheader("📊 Results") # Display results in a nice table results_df = pd.DataFrame({ 'Element': ['Side a', 'Side b', 'Side c', 'Angle A', 'Angle B', 'Angle C'], 'Value': [f'{side_a:.3f}', f'{side_b:.3f}', f'{side_c:.3f}', f'{angle_A:.2f}°', f'{angle_B:.2f}°', f'{angle_C:.2f}°'], 'Type': ['Given' if known_case == "Two angles and one side (AAS/ASA)" else 'Given', 'Calculated' if known_case == "Two angles and one side (AAS/ASA)" else 'Given', 'Calculated', 'Given' if known_case == "Two angles and one side (AAS/ASA)" else 'Given', 'Given' if known_case == "Two angles and one side (AAS/ASA)" else 'Calculated', 'Calculated'] }) st.dataframe(results_df, use_container_width=True) # Calculate area using formula: Area = (1/2)ab*sin(C) area = 0.5 * side_a * side_b * sin(radians(angle_C)) perimeter = side_a + side_b + side_c col_metric1, col_metric2 = st.columns(2) with col_metric1: st.metric("Area", f"{area:.3f} sq units") with col_metric2: st.metric("Perimeter", f"{perimeter:.3f} units") # Draw the triangle fig = draw_triangle(side_a, side_b, side_c, angle_A, angle_B, angle_C, "Law of Sines Triangle") st.plotly_chart(fig, use_container_width=True) def law_of_cosines_calculator(): st.header("📐 Law of Cosines Calculator") st.markdown("**Formula:** c² = a² + b² - 2ab⋅cos(C)") # Add formula explanation with st.expander("📚 When to use Law of Cosines"): st.markdown(""" Use the Law of Cosines when you have: - **SSS (Side-Side-Side)**: All three sides known - **SAS (Side-Angle-Side)**: Two sides and the included angle This is especially useful when the Law of Sines doesn't apply directly. """) col1, col2 = st.columns([1, 1]) with col1: st.subheader("📝 Input Triangle Data") known_case = st.selectbox( "What do you know?", ["Three sides (SSS)", "Two sides and included angle (SAS)"] ) if known_case == "Three sides (SSS)": st.write("**Enter all three sides:**") side_a = st.number_input("Side a:", min_value=0.1, value=5.0, key="cosines_sss_sidea") side_b = st.number_input("Side b:", min_value=0.1, value=7.0, key="cosines_sss_sideb") side_c = st.number_input("Side c:", min_value=0.1, value=9.0, key="cosines_sss_sidec") # Check triangle inequality if not (side_a + side_b > side_c and side_b + side_c > side_a and side_a + side_c > side_b): st.error("❌ Invalid triangle! Triangle inequality not satisfied.") st.write("**Triangle Inequality Rules:**") st.write(f"• a + b > c: {side_a:.2f} + {side_b:.2f} = {side_a + side_b:.2f} {'✓' if side_a + side_b > side_c else '✗'} {side_c:.2f}") st.write(f"• b + c > a: {side_b:.2f} + {side_c:.2f} = {side_b + side_c:.2f} {'✓' if side_b + side_c > side_a else '✗'} {side_a:.2f}") st.write(f"• a + c > b: {side_a:.2f} + {side_c:.2f} = {side_a + side_c:.2f} {'✓' if side_a + side_c > side_b else '✗'} {side_b:.2f}") return # Calculate angles using Law of Cosines try: angle_A = degrees(acos((side_b**2 + side_c**2 - side_a**2) / (2 * side_b * side_c))) angle_B = degrees(acos((side_a**2 + side_c**2 - side_b**2) / (2 * side_a * side_c))) angle_C = 180 - angle_A - angle_B except ValueError: st.error("❌ Error calculating angles. Check your side lengths.") return else: # SAS case st.write("**Enter two sides and the included angle:**") side_a = st.number_input("Side a:", min_value=0.1, value=5.0, key="cosines_sas_sidea") side_b = st.number_input("Side b:", min_value=0.1, value=7.0, key="cosines_sas_sideb") angle_C = st.number_input("Angle C (between sides a and b):", min_value=0.1, max_value=179.9, value=60.0, key="cosines_sas_angleC") # Calculate third side using Law of Cosines side_c = sqrt(side_a**2 + side_b**2 - 2 * side_a * side_b * cos(radians(angle_C))) # Calculate other angles using Law of Cosines try: angle_A = degrees(acos((side_b**2 + side_c**2 - side_a**2) / (2 * side_b * side_c))) angle_B = 180 - angle_A - angle_C except ValueError: st.error("❌ Error calculating angles. Check your inputs.") return with col2: st.subheader("📊 Results") # Display results results_df = pd.DataFrame({ 'Element': ['Side a', 'Side b', 'Side c', 'Angle A', 'Angle B', 'Angle C'], 'Value': [f'{side_a:.3f}', f'{side_b:.3f}', f'{side_c:.3f}', f'{angle_A:.2f}°', f'{angle_B:.2f}°', f'{angle_C:.2f}°'], 'Type': ['Given', 'Given', 'Given' if known_case == "Three sides (SSS)" else 'Calculated', 'Calculated', 'Calculated', 'Calculated' if known_case == "Three sides (SSS)" else 'Given'] }) st.dataframe(results_df, use_container_width=True) # Calculate area and perimeter area = calculate_triangle_area(side_a, side_b, side_c) perimeter = side_a + side_b + side_c col_metric1, col_metric2 = st.columns(2) with col_metric1: st.metric("Area", f"{area:.3f} sq units") with col_metric2: st.metric("Perimeter", f"{perimeter:.3f} units") # Determine triangle type if abs(angle_A - 90) < 0.01 or abs(angle_B - 90) < 0.01 or abs(angle_C - 90) < 0.01: triangle_type = "Right Triangle" elif angle_A > 90 or angle_B > 90 or angle_C > 90: triangle_type = "Obtuse Triangle" else: triangle_type = "Acute Triangle" st.info(f"**Triangle Type:** {triangle_type}") # Draw the triangle fig = draw_triangle(side_a, side_b, side_c, angle_A, angle_B, angle_C, "Law of Cosines Triangle") st.plotly_chart(fig, use_container_width=True) def vector_angle_calculator(): st.header("🔄 Vector Angle Calculator") st.markdown("**Formula:** cos(θ) = (A⋅B) / (|A|⋅|B|)") # Add explanation with st.expander("📚 Understanding Vector Angles"): st.markdown(""" **Dot Product Formula:** A⋅B = |A||B|cos(θ) **Applications:** - Physics: Work = Force⋅Displacement⋅cos(θ) - Computer Graphics: Lighting calculations - Engineering: Force analysis - Navigation: Direction calculations """) col1, col2 = st.columns([1, 1]) with col1: st.subheader("📝 Enter Vectors") # Vector input methods input_method = st.radio("Input method:", ["Component form", "Magnitude & Direction"]) if input_method == "Component form": st.write("**Vector A:**") a_x = st.number_input("A_x component:", value=3.0, key="vector_ax") a_y = st.number_input("A_y component:", value=4.0, key="vector_ay") st.write("**Vector B:**") b_x = st.number_input("B_x component:", value=1.0, key="vector_bx") b_y = st.number_input("B_y component:", value=2.0, key="vector_by") else: st.write("**Vector A:**") mag_a = st.number_input("Magnitude of A:", min_value=0.1, value=5.0, key="vector_mag_a") dir_a = st.number_input("Direction of A (degrees):", value=53.0, key="vector_dir_a") st.write("**Vector B:**") mag_b = st.number_input("Magnitude of B:", min_value=0.1, value=2.24, key="vector_mag_b") dir_b = st.number_input("Direction of B (degrees):", value=63.4, key="vector_dir_b") # Convert to components a_x = mag_a * cos(radians(dir_a)) a_y = mag_a * sin(radians(dir_a)) b_x = mag_b * cos(radians(dir_b)) b_y = mag_b * sin(radians(dir_b)) # Calculate vector properties dot_product = a_x * b_x + a_y * b_y magnitude_a = sqrt(a_x**2 + a_y**2) magnitude_b = sqrt(b_x**2 + b_y**2) if magnitude_a == 0 or magnitude_b == 0: st.error("❌ Zero vector detected! Cannot calculate angle.") return cos_theta = dot_product / (magnitude_a * magnitude_b) # Clamp to [-1, 1] to avoid floating point errors cos_theta = max(-1, min(1, cos_theta)) angle_degrees = degrees(acos(cos_theta)) # Calculate cross product for 2D (gives scalar) cross_product = a_x * b_y - a_y * b_x with col2: st.subheader("📊 Results") # Vector information table vector_info = pd.DataFrame({ 'Property': ['A_x', 'A_y', 'B_x', 'B_y', '|A|', '|B|'], 'Value': [f'{a_x:.3f}', f'{a_y:.3f}', f'{b_x:.3f}', f'{b_y:.3f}', f'{magnitude_a:.3f}', f'{magnitude_b:.3f}'] }) st.dataframe(vector_info, use_container_width=True) # Key results col_metric1, col_metric2 = st.columns(2) with col_metric1: st.metric("Dot Product (A⋅B)", f"{dot_product:.3f}") st.metric("Angle", f"{angle_degrees:.2f}°") with col_metric2: st.metric("Cross Product (2D)", f"{cross_product:.3f}") st.metric("cos(θ)", f"{cos_theta:.4f}") # Vector relationship if abs(dot_product) < 1e-10: st.info("🔄 **Vectors are perpendicular (orthogonal)**") elif cos_theta > 0: st.info("📐 **Vectors point in similar directions (acute angle)**") else: st.info("📐 **Vectors point in opposite directions (obtuse angle)**") # Draw vectors fig = draw_vectors(a_x, a_y, b_x, b_y, angle_degrees) st.plotly_chart(fig, use_container_width=True) # Additional calculations st.subheader("🧮 Additional Calculations") # Unit vectors unit_a_x = a_x / magnitude_a if magnitude_a != 0 else 0 unit_a_y = a_y / magnitude_a if magnitude_a != 0 else 0 unit_b_x = b_x / magnitude_b if magnitude_b != 0 else 0 unit_b_y = b_y / magnitude_b if magnitude_b != 0 else 0 st.write(f"**Unit vector A:** ({unit_a_x:.3f}, {unit_a_y:.3f})") st.write(f"**Unit vector B:** ({unit_b_x:.3f}, {unit_b_y:.3f})") # Vector sum and difference sum_x, sum_y = a_x + b_x, a_y + b_y diff_x, diff_y = a_x - b_x, a_y - b_y st.write(f"**A + B:** ({sum_x:.3f}, {sum_y:.3f})") st.write(f"**A - B:** ({diff_x:.3f}, {diff_y:.3f})") def triangle_visualizer(): st.header("🎨 Interactive Triangle Visualizer") st.markdown("Explore how changing triangle properties affects its shape and calculations!") col1, col2 = st.columns([1, 1]) with col1: st.subheader("🎛️ Triangle Controls") # Interactive sliders for triangle properties side_a = st.slider("Side a:", min_value=1.0, max_value=15.0, value=8.0, step=0.1) side_b = st.slider("Side b:", min_value=1.0, max_value=15.0, value=6.0, step=0.1) angle_C = st.slider("Angle C (degrees):", min_value=10.0, max_value=170.0, value=60.0, step=1.0) # Calculate using Law of Cosines side_c = sqrt(side_a**2 + side_b**2 - 2 * side_a * side_b * cos(radians(angle_C))) # Calculate other angles try: angle_A = degrees(acos((side_b**2 + side_c**2 - side_a**2) / (2 * side_b * side_c))) angle_B = 180 - angle_A - angle_C except ValueError: st.error("Invalid triangle configuration!") return # Real-time calculations area = 0.5 * side_a * side_b * sin(radians(angle_C)) perimeter = side_a + side_b + side_c # Display live results st.subheader("📊 Live Results") col_live1, col_live2 = st.columns(2) with col_live1: st.metric("Side c", f"{side_c:.2f}") st.metric("Angle A", f"{angle_A:.1f}°") st.metric("Area", f"{area:.2f}") with col_live2: st.metric("Angle B", f"{angle_B:.1f}°") st.metric("Perimeter", f"{perimeter:.2f}") # Triangle type if abs(angle_A - 90) < 0.1 or abs(angle_B - 90) < 0.1 or abs(angle_C - 90) < 0.1: triangle_type = "Right" elif angle_A > 90 or angle_B > 90 or angle_C > 90: triangle_type = "Obtuse" else: triangle_type = "Acute" st.info(f"**Triangle Type:** {triangle_type}") with col2: st.subheader("📐 Interactive Triangle") # Draw the interactive triangle fig = draw_triangle(side_a, side_b, side_c, angle_A, angle_B, angle_C, "Interactive Triangle") st.plotly_chart(fig, use_container_width=True) # Show which laws apply st.subheader("📚 Applicable Laws") st.write("**Given:** Two sides (a, b) and included angle (C)") st.write("**Use:** Law of Cosines to find side c") st.write("**Then:** Law of Cosines or Sines to find remaining angles") # Show the calculations with st.expander("🔍 See the calculations"): st.write("**Step 1: Find side c using Law of Cosines**") st.latex(r"c^2 = a^2 + b^2 - 2ab \cos(C)") st.write(f"c² = {side_a}² + {side_b}² - 2({side_a})({side_b})cos({angle_C}°)") st.write(f"c² = {side_a**2:.2f} + {side_b**2:.2f} - {2*side_a*side_b:.2f} × {cos(radians(angle_C)):.4f}") st.write(f"c = {side_c:.3f}") st.write("**Step 2: Find angle A using Law of Cosines**") st.latex(r"\cos(A) = \frac{b^2 + c^2 - a^2}{2bc}") st.write(f"cos(A) = ({side_b}² + {side_c:.2f}² - {side_a}²) / (2 × {side_b} × {side_c:.2f})") st.write(f"A = {angle_A:.2f}°") st.write("**Step 3: Find angle B**") st.write(f"B = 180° - A - C = 180° - {angle_A:.2f}° - {angle_C}° = {angle_B:.2f}°") def main(): st.set_page_config(page_title="Triangle Solver & Vector Calculator", page_icon="📐", layout="wide") st.title("📐 Triangle Solver & Vector Calculator") st.markdown("### Master the Law of Sines, Law of Cosines, and Vector Applications!") # Add educational tips tips = [ "💡 **Law of Sines**: Use when you have angle-side-angle (ASA) or side-angle-angle (SAA)", "🎯 **Law of Cosines**: Use when you have side-side-side (SSS) or side-angle-side (SAS)", "📊 **Vector Tip**: The angle between vectors uses the dot product formula", "🔄 **Remember**: Always check if your triangle is valid (triangle inequality)", "⚡ **Practical**: These laws help in navigation, engineering, and physics!" ] st.info(np.random.choice(tips)) # Sidebar for mode selection st.sidebar.header("🎛️ Calculator Mode") mode = st.sidebar.radio( "Choose what to calculate:", ["Law of Sines", "Law of Cosines", "Vector Angle Calculator", "Triangle Visualizer"] ) # Educational content sidebar with st.sidebar.expander("📚 Quick Reference"): st.markdown(""" **Law of Sines:** a/sin(A) = b/sin(B) = c/sin(C) **Law of Cosines:** c² = a² + b² - 2ab⋅cos(C) **Vector Angle:** cos(θ) = (A⋅B)/(|A||B|) **Triangle Inequality:** a + b > c, b + c > a, a + c > b """) # Main content based on mode if mode == "Law of Sines": law_of_sines_calculator() elif mode == "Law of Cosines": law_of_cosines_calculator() elif mode == "Vector Angle Calculator": vector_angle_calculator() else: triangle_visualizer() # Footer with applications st.markdown("---") st.subheader("🌟 Real-World Applications") app_col1, app_col2, app_col3 = st.columns(3) with app_col1: st.markdown(""" **🏗️ Engineering** - Structural analysis - Force calculations - Bridge design """) with app_col2: st.markdown(""" **🧭 Navigation** - GPS systems - Ship navigation - Flight paths """) with app_col3: st.markdown(""" **🎮 Technology** - Computer graphics - Game physics - Robotics """) if __name__ == "__main__": main()