Straight Line Motion#
Let \(\mathbf{e}\) and \(\mathbf{e}'\) represent two inertial observers. \(\mathbf{e}'\) moving parallel to \(\mathbf{e}\) at a constant velocity \(v=[v_1\:\:\:v_2\:\:\:v_3]^T\). Let \((t,x)\) is a representation of a point \(\mathbf{P}\) in \(\mathbf{e}\). Then this same point has the representation \(\left(t,(x-vt)\right)\) in the \(\mathbf{e}'\) frame.
Let the point \(\mathbf{P}\) is seen to be moving in a straight line through the origin by \(\mathbf{e}\).
We’ll animate those frames and the path of the \(P\) seen from different frames.
Import following libraries on your notebook
[2]:
import plotly.graph_objects as go
import numpy as np
Note
The functions create_line_trace
, create_point_trace
, create_arrow_trace
, and and
others were written in previous tutorials. Please include them in your notebook on top before
starting to follow this tutorial. You can download it by clicking the Download icon on the
Navigation Bar.
Since we have explained the syntax and functions going to use here I am leaving the code only. Follow the previous tutorials for better understanding. Hit the play button and see!
[4]:
frames = []
origin = [0, 0, 0]
origin_prime = [5, 5, 5]
interval = np.linspace(0, 50, 100)
line2_end_initial = [25, 10, 10]
point_P_start = [-10, -10, -10]
velocity_prime = 0.5 # Velocity for frame 'e''
velocity = 0.8 # Velocity for frame 'e'
# Initialize a list to keep track of P's path
path_of_P = []
# Initialize a list to keep track of P's path in e' frame
path_of_P_e_prime = []
# Add origin 'O'
traces = [create_point_trace(origin_prime, color='black', size=3, name="O'"),
create_point_trace(origin, color='black', size=3, name='O'),
create_point_trace(point_P_start, color='red', size=8, name='P'),
create_line_trace(start=point_P_start, end=[10, 10, 10], color='blue', width=3, name='P in e frame', showlegend=True),
create_line_trace(start=point_P_start, end=line2_end_initial, color='purple', width=3, name="P in e' frame", showlegend=True),
create_line_trace(start=point_P_start, end=point_P_start, color='orange', width=2, dash='dash', name='P in our frame', showlegend=True)]
# Create orthonormal frame traces
frame_traces = create_orthonormal_frame_traces(frame_name="e'", origin=origin_prime, length=5, color='green')
traces.extend(frame_traces)
# Create orthonormal frame traces
frame_traces = create_orthonormal_frame_traces(frame_name='e', origin=origin, length=5, color='red')
traces.extend(frame_traces)
traces.append(create_line_trace(start=origin, end=[50, 0, 0], color='blue', width=3, dash='dash', name='Frame e Motion', showlegend=True))
traces.append(create_line_trace(start=[0, 5, 5], end=[50, 5, 5], color='purple', width=3, dash='dash', name="Frame e' Motion", showlegend=True))
# Animation
for i in range(0, len(interval), 2):
new_origin_prime = [origin_prime[0] + interval[i] * velocity_prime, origin_prime[1], origin_prime[2]]
new_origin = [origin[0] + interval[i] * velocity, origin[1], origin[2]]
# Define the moving line
line1_start = [point - 10 for point in new_origin]
line1_end = [point + 10 for point in new_origin]
line2_start = [-10 + new_origin_prime[j] - origin_prime[j] for j in range(3)]
line2_end = [line2_end_initial[j] + new_origin_prime[j] - origin_prime[j] for j in range(3)]
# Generate coordinates array from line1_start to line1_end
x_coordinates_array = np.linspace(line1_start[0], line1_end[0], len(interval))
y_coordinates_array = np.linspace(line1_start[1], line1_end[1], len(interval))
z_coordinates_array = np.linspace(line1_start[2], line1_end[2], len(interval))
# Select the i-th point as P
point_P = [x_coordinates_array[i], y_coordinates_array[i], z_coordinates_array[i]]
# Append current position of P to the path
path_of_P.append(point_P)
# Calculate P's position relative to e' frame
point_P_e_prime = [point_P[j] - new_origin_prime[j]+5 for j in range(3)]
path_of_P_e_prime.append(point_P_e_prime)
frame_data = [
# Move origin prime 'O''
create_point_trace(new_origin_prime, color='black', size=3, name="O'"),
# Move origin 'O'
create_point_trace(new_origin, color='black', size=3, name='O'),
# Move P through line
create_point_trace(point_P, color='red', size=8, name='P'),
# Moving line through 'O'
create_line_trace(start=line1_start, end=line1_end, color='blue', width=3, name='P in e frame', showlegend=True),
create_line_trace(start=line2_start, end=line2_end, color='purple', width=3, name="P in e' frame", showlegend=True),
# Trace for the actual path of P
create_line_trace(start=path_of_P[0], end=path_of_P[-1], color='orange', width=2, dash='solid', name='P in our frame', showlegend=True)
# Trace for the actual path of P in e' frame
# create_line_trace(start=path_of_P_e_prime[0], end=path_of_P_e_prime[-1], color='purple', width=2, dash='dash', name="P's Path in e' frame", showlegend=True)
]
# Move the orthonormal frames
frame_traces_prime = create_orthonormal_frame_traces(frame_name="e'", origin=new_origin_prime, length=5, color='green')
frame_traces = create_orthonormal_frame_traces(frame_name='e', origin=new_origin, length=5, color='red')
frame_data.extend(frame_traces_prime)
frame_data.extend(frame_traces)
frames.append(go.Frame(data=frame_data))
for p_point in path_of_P:
traces.append(create_point_trace(p_point, color='orange', size=1, name=''))
# # plot the path of P in e' frame
# for p_point_e_prime in path_of_P_e_prime:
# traces.append(create_point_trace(p_point_e_prime, color='orange', size=1, name=''))
print(path_of_P_e_prime[-1])
# Set layout for the figure
layout = create_3d_layout(title='Parallel Frames', xaxis_title='e1 Axis', yaxis_title='e2 Axis', zaxis_title='e3 Axis')
fig = go.Figure()
fig = go.Figure(data=traces, layout=layout, frames=frames)
axis_range = [0, 60]
# Adjust the camera settings
fig.update_layout(
scene=dict(
xaxis=dict(range=[-10,50]),
# yaxis=dict(range=axis_range),
# zaxis=dict(range=axis_range),
camera=dict(
up=dict(x=0, y=0, z=1), # Sets the up direction (in this case, the z-axis is up)
center=dict(x=0, y=0, z=0), # Centers the view on the given coordinates
eye=dict(x=1, y=-1.25, z=1.25) # Sets the position of the camera
),
aspectmode='cube' # Keeps the aspect ratio of the axes fixed
)
)
# Add play and pause buttons
fig.update_layout(
updatemenus=[
dict(
type="buttons",
buttons=[
dict(label="Play",
method="animate",
args=[None, dict(frame=dict(duration=100, redraw=True), fromcurrent=True)]),
dict(label="Pause",
method="animate",
args=[[None], dict(frame=dict(duration=0, redraw=False), mode="immediate")])
]
)
]
)
fig.show()
[24.64646464646465, 9.7979797979798, 9.7979797979798]