import dash
from dash import dcc, html
from dash.dependencies import Input, Output
import plotly.graph_objects as go
import numpy as np
# Initialize the Dash app
app = dash.Dash(__name__)
# Define the layout of the app
app.layout = html.Div([
html.H1("3D Spring-Mass System Simulation"),
dcc.Graph(id='3d-spring-mass-graph'),
dcc.Interval(id='interval-component', interval=50, n_intervals=0)
])
# Constants for the spring-mass system
m = 1.0 # mass
k = 1.0 # spring constant
damping = 0.1 # damping coefficient
initial_position = np.array([1.0, 0.0, 0.0]) # initial position
initial_velocity = np.array([0.0, 0.0, 0.0]) # initial velocity
# Time parameters
t_max = 20 # max time
dt = 0.05 # time step
time = np.arange(0, t_max, dt)
# Initialize position and velocity
position = np.zeros((len(time), 3))
velocity = np.zeros((len(time), 3))
position[0] = initial_position
velocity[0] = initial_velocity
# Simulate the spring-mass system
for i in range(1, len(time)):
acceleration = -k * position[i-1] / m - damping * velocity[i-1] / m
velocity[i] = velocity[i-1] + acceleration * dt
position[i] = position[i-1] + velocity[i] * dt
@app.callback(
Output('3d-spring-mass-graph', 'figure'),
Input('interval-component', 'n_intervals')
)
def update_graph(n_intervals):
t_index = n_intervals % len(time)
fig = go.Figure(data=[
go.Scatter3d(
x=position[:t_index, 0],
y=position[:t_index, 1],
z=position[:t_index, 2],
mode='lines',
line=dict(color='blue', width=4)
),
go.Scatter3d(
x=[position[t_index, 0]],
y=[position[t_index, 1]],
z=[position[t_index, 2]],
mode='markers',
marker=dict(size=8, color='red')
)
])
fig.update_layout(
scene=dict(
xaxis_title='X',
yaxis_title='Y',
zaxis_title='Z',
aspectratio=dict(x=1, y=1, z=1)
),
margin=dict(l=0, r=0, t=0, b=0)
)
return fig
if __name__ == '__main__':
app.run_server(debug=True)