muhammadas/physics_simulation_app
0
1import gradio as gr2import numpy as np3import matplotlib.pyplot as plt4import io5from PIL import Image6 7def simulate_projectile(velocity, angle):8 g = 9.819 theta = np.radians(angle)10 11 # --- Physics Calculations ---12 # Time of flight: t = (2 * v0 * sin(theta)) / g13 t_flight = (2 * velocity * np.sin(theta)) / g14 t = np.linspace(0, t_flight, 200)15 16 # Trajectory equations17 x = velocity * np.cos(theta) * t18 y = (velocity * np.sin(theta) * t) - (0.5 * g * t**2)19 20 max_height = (velocity**2 * (np.sin(theta)**2)) / (2 * g)21 total_range = (velocity**2 * np.sin(2 * theta)) / g22 23 # --- Plotting the Trajectory ---24 plt.figure(figsize=(10, 5))25 plt.plot(x, y, label='Path of Object', color='#2563eb', lw=2)26 plt.fill_between(x, y, color='#2563eb', alpha=0.1)27 plt.axhline(0, color='black', lw=1)28 plt.title("Projectile Trajectory Visualization")29 plt.xlabel("Distance (m)")30 plt.ylabel("Height (m)")31 plt.grid(True, linestyle=':', alpha=0.7)32 plt.legend()33 34 # Convert plot to PIL image35 buf = io.BytesIO()36 plt.savefig(buf, format='png', bbox_inches='tight')37 buf.seek(0)38 img = Image.open(buf)39 plt.close()40 41 # --- AI Analysis Text ---42 # Using double {{ }} to prevent Python f-string errors with LaTeX43 analysis_text = f"""44### 🔬 AI Physics Analysis45At a launch velocity of **{velocity} m/s** and an angle of **{angle}°**, the object follows a parabolic arc.46 47**Calculated Metrics:**48* **Maximum Height:** {max_height:.2f} meters49* **Horizontal Range:** {total_range:.2f} meters50* **Total Flight Time:** {t_flight:.2f} seconds51 52**The Physics Equation:**53The relationship between horizontal distance ($x$) and vertical height ($y$) is given by:54 55$$y = x \\tan(\\theta) - \\frac{{gx^2}}{{2v_0^2 \\cos^2(\\theta)}}$$56 """57 58 return img, analysis_text59 60# --- Gradio UI Layout ---61with gr.Blocks(theme=gr.themes.Soft()) as demo:62 gr.Markdown("# 🚀 Physics Lab: Projectile Simulator")63 gr.Markdown("Adjust initial conditions to see the physics of motion in action.")64 65 with gr.Row():66 with gr.Column(scale=1):67 v_input = gr.Slider(5, 100, value=30, label="Initial Velocity (m/s)")68 a_input = gr.Slider(1, 90, value=45, label="Launch Angle (Degrees)")69 run_btn = gr.Button("Simulate", variant="primary")70 71 with gr.Column(scale=2):72 plot_out = gr.Image(label="Trajectory Graph")73 text_out = gr.Markdown()74 75 run_btn.click(76 fn=simulate_projectile, 77 inputs=[v_input, a_input], 78 outputs=[plot_out, text_out]79 )80 81if __name__ == "__main__":82 demo.launch()