Project 01: How fast can the wooden box rotate without breaking the egg inside?¶
Name: Nam Bui
Introduction:¶
How fast can the wooden box rotates without breaking the egg inside under these conditions?
- The egg is initially placed in the middle of a 2-D, 10x10 meter box.
- The box is rotating clockwise (angular velocity vector points into/below the box's base).
- The egg has an initial velocity of $(1i +1j)m/s$.
- I will consider fictitious forces since I will look at the noninertial frame of the box. The frictional force is also considered.
- There will be a maximum of 10s for the egg to collide with the box edges and break. If the egg has not collided with box's wall, I will say the broken force is 0.
- I will assume the collisions of the egg with walls are elastic (except for egg breaking) and the force acting time is 0.005s.
The Physics Simulation:¶
Firstly, to account for the collision force on the egg, I will use Newton's Second Law: $$ F_{\text{collide}} = \frac{m \Delta v}{\Delta t} $$ in which $\Delta v$ is 2 times $v_{\text{travel}}$ of the egg in x or y direction (egg collides and reverse its direction with conserved speed) and $\Delta t$ is 0.005s as mentioned. Secondly, I will find the Coriolis acceleration and frictional acceleration as: $$|a_{\text{coriolis}}| = |-2(\omega \times v_{\text{egg}})| = 2 * \omega * v_{\text{egg}}$$ $$|a_{\text{friction}}| = \mu_{\text{k}} * 9.81$$ $$|a_{\text{centrifugal}}| = \omega^2 * r $$ Directions of these accelerations will be: $$ \hat{a_{\text{cor}}} = <-\hat{vy},\hat{vx}> $$ $$ \hat{a_{\text{fric}}} = <-\hat{vx},-\hat{vy}> $$ $$ \hat{a_{\text{cenf}}} = <\hat{x},\hat{y}> $$
The code below will demonstrate the egg's motion on the box's surface before colliding with an edge. I will analyze the egg's trajectory to see if different accelerations and collisions work on the egg correctly. In addition, the code also provides the relationship between varying angular speed omega and the resulting maximum colliding force on the egg within 10 seconds, thus I can find the omega resulting in the broken egg. The position of the egg is governed by these kinematic equations: $$ x_{\text{i+1}} = x_{\text{i}} + v_{\text{xi}}*\Delta t + (1/2)a_{\text{xi}}\Delta t^2$$ $$ y_{\text{i+1}} = y_{\text{i}} + v_{\text{yi}}*\Delta t + (1/2)a_{\text{yi}}\Delta t^2$$ For vectors and equations' justification, please see my Appendix A1.3.
import matplotlib.pyplot as plt
import numpy as np
# Box's dimension (on 2D: x-y plane)
left_barrier = -10
right_barrier = 10
top_barrier = 10
bot_barrier = -10
t_collide = 0.005
#Time of the event:
dt = 0.01
t_max = 10
t_list = []
#Egg's property:
m = 0.0005 #kg
F_break = 24.5 #breaking force for egg (source cited in references)
omega_list = [] #List for tested omega values
max_forces_per_omega = [] #I only take max collision force (among multiple collisions) of each omega value
# Testing omega loop:
for j in range(0, 20):
omega = j
omega_list.append(omega)
#Initial position and velocities of egg:
x = [0]
y = [0]
vx = [1]
vy = [1]
# Frictional force:
miu_k = 0.8 # This coefficient is an assumption since I cannot find a reference value and this value can be easily changed without significantly affecting the project.
F_normal = miu_k * m * 9.81
F_list = []
egg_broken = False #Flag egg is not broken at the beginning
# Position of egg:
for i in range(100):
r = np.sqrt(x[-1] ** 2 + y[-1] ** 2)
if r != 0:
r_unit_x = x[-1] / r
r_unit_y = y[-1] / r
else:
r_unit_x = 0
r_unit_y = 0
# Centrifugal accelerations:
if r != 0:
a_cenf = (omega**2) / r # Magnitude
a_cenf_x = a_cenf * r_unit_x #Vector in x direction
a_cenf_y = a_cenf * r_unit_y #Vector in y direction
else: #If r = 0, there is no centrifugal acceleration
a_cenf_x = 0
a_cenf_y = 0
v_travel = np.sqrt(vx[i] ** 2 + vy[i] ** 2) #This is the speed of egg
if v_travel != 0:
v_travel_unit_x = vx[i] / v_travel #Unit vector of egg velocity in x-direction
v_travel_unit_y = vy[i] / v_travel #Unit vector of egg velocity in y-direction
else:
v_travel_unit_x = 0
v_travel_unit_y = 0
# Coriolis acceleration:
if r != 0:
a_cor = 2 * omega * v_travel / r # Magnitude
a_cor_unit_x = -v_travel_unit_y # Unit vector in x-dir
a_cor_unit_y = v_travel_unit_x # Unit vector in y-dirn
a_cor_x = a_cor * a_cor_unit_x # Vector in x-dir
a_cor_y = a_cor * a_cor_unit_y # Vector in y-dir
else: # No coriolis force when egg is exactly at the center of the rotating box
a_cor_x = 0
a_cor_y = 0
#Frictional force:
if v_travel != 0:
a_fric_unit_x = (-vx[i] / v_travel) # kinetic friction acceleration unit vector in x-direction
a_fric_unit_y = (-vy[i] / v_travel) # kinetic friction acceleration unit vector in y-direction
a_fric = F_normal / m # kinetic friction magnitude
a_fric_x = a_fric * a_fric_unit_x # Vector in x-direction
a_fric_y = a_fric * a_fric_unit_y # Vector in y-direction
else: #No kinetic friction if egg's speed is 0
a_fric_x = 0
a_fric_y = 0
# Total accelerations:
a_x = a_cor_x + a_fric_x + a_cenf_x # acceleration in x-direction
a_y = a_cor_y + a_fric_y + a_cenf_y # acceleration in y-direction
# Egg positions: (using kinematic equations introduced before)
x_egg = x[i] + vx[i] * dt + 0.5 * a_x * dt**2
y_egg = y[i] + vy[i] * dt + 0.5 * a_y * dt**2
vx_egg = vx[i] + a_x * dt
vy_egg = vy[i] + a_y * dt
F_collide = 0 # Mark collision force = 0 at the beginning
# Collision events:
if x_egg <= left_barrier:
vx_egg = -vx[i]
x_egg = left_barrier
F_collide = m * 2 * abs(vx_egg) / t_collide
elif x_egg >= right_barrier:
vx_egg = -vx[i]
x_egg = right_barrier
F_collide = m * 2 * abs(vx_egg) / t_collide
elif y_egg <= bot_barrier:
vy_egg = -vy[i]
y_egg = bot_barrier
F_collide = m * 2 * abs(vy_egg) / t_collide
elif y_egg >= top_barrier:
vy_egg = -vy[i]
y_egg = top_barrier
F_collide = m * 2 * abs(vy_egg) / t_collide
F_list.append(F_collide)
x.append(x_egg)
y.append(y_egg)
vx.append(vx_egg)
vy.append(vy_egg)
# Egg breaking event:
if F_collide >= F_break:
if omega in [11, 12]:
print(f"Egg is broken for omega {omega} at: x = {x_egg} m, y = {y_egg} m")
egg_broken = True
break
if not egg_broken and omega in [11, 12]:
print(f"Egg has not been broken for omega: {omega}")
# Maximum force from each omega:
max_force = max(F_list) if F_list else 0
max_forces_per_omega.append(max_force)
#Plotting only two omega values:
if omega == 11:
plt.plot(x, y, "o-", label="omega = 11 rad/s")
plt.xlabel("X Position [m]")
plt.ylabel("Y Position [m]")
plt.title("Egg trajectory in 10 second interval")
plt.xlim(-10, 10)
plt.ylim(-10, 10)
plt.legend()
plt.grid(True)
plt.show()
if omega == 12:
plt.plot(x, y, "o-", label="omega = 12 rad/s")
plt.xlabel("X Position [m]")
plt.ylabel("Y Position [m]")
plt.title("Egg trajectory in 10 second interval")
plt.xlim(-10, 10)
plt.ylim(-10, 10)
plt.legend()
plt.grid(True)
plt.savefig("Figure2.png")
plt.show()
#Plotting omega variables vs max force:
x_force = [24.5] * 20 # Breaking point line
plt.plot(max_forces_per_omega, omega_list, "o-")
plt.plot(x_force, omega_list, label="Breaking point of egg: 24.5 N")
plt.xlabel("Maximum Forces [N]")
plt.ylabel("Omega [rad/s]")
plt.title("Different omega values and their maximum force on egg")
plt.legend()
plt.grid(True)
plt.show()
Egg has not been broken for omega: 11
Egg is broken for omega 12 at: x = -10 m, y = -2.1820474808173658 m
Conclusion¶
The simulation shows that the egg will not be broken when the omega values are smaller than 12 rad/s as the maximum colliding force (among several collisions within 10 seconds) is below 24.5N. Otherwise, any omega value larger or equal to 12 rad/s will break the egg as witnessed in Figure 2.
This simulation does not entirely represent the real case since it is limited to 10-second intervals (the egg might keep travelling for a long time before breaking in the real case). Also, this simulation only represents 2-D cases while realistically in 3-D. In addition, I varied and tested omega with the increment of 1 rad/s; the actual egg-breaking omega value might lie between 11-12 rad/s. Nevertheless, I believe this still ideally answers my research question with some restrictions: happening in a 2-D plane, elastic collisions, and 10-second intervals.
To leverage my simulation, I will try to find a more precise egg-breaking omega value to 3 decimal points. One way I can think of is to find the intersection point of the verticle 24.5N line (orange) with the omega-max_force line (blue) in Figure 3. In addition, I am assuming the collision time of the egg and the wall is constant at 0.005s. To improve, I will try to find different collision time depending on different egg's speed before collision.
References¶
- https://physics-network.org/what-forces-affect-the-egg-when-it-is-dropped/
- Analytical Mechanics, Book by Grant R. Fowles
Appendix 1: Code validation¶
A1.1: Comparison of simulation results with by-hand calculations¶
For this appendix, I will validate and compare the egg-breaking collision of omega = 12 rad/s and the no-egg-breaking last collision of omega = 11 rad/s by calculating by hand the collision force acting on the egg for both collisions, then compare if they are really above/below the breaking point of 24.5N.
First, I will use the code to identify the velocity before collisions:
import numpy as np
import matplotlib.pyplot as plt
# Box dimensions
left_barrier = -10
right_barrier = 10
top_barrier = 10
bot_barrier = -10
t_collide = 0.005
# Time of event
dt = 0.01
t_max = 10
t_list = []
#Egg's info
m = 0.0005
F_break = 24.5
#List for omega
omega_list = []
max_forces_per_omega = []
#List for colliding velocity
vx_collide = []
vy_collide=[]
# Check omega = 11 , 12
for j in [11,12]:
omega = j
omega_list.append(omega)
x = [0]
y = [0]
vx = [1]
vy = [1]
# Frictional force:
miu_k = 0.8
F_normal = miu_k * m * 9.81
F_list = []
egg_broken = False
# Position of egg:
for i in range(100):
r = np.sqrt(x[-1]**2+y[-1]**2)
if r != 0:
r_unit_x = x[-1]/r
r_unit_y = y[-1]/r
else:
r_unit_x = 0
r_unit_y = 0
# Centrifugal accelerations:
if r != 0:
a_cenf = (omega**2)/r
a_cenf_x = a_cenf * r_unit_x
a_cenf_y = a_cenf * r_unit_y
else:
a_cenf_x = 0
a_cenf_y = 0
# Egg's speed
v_travel = np.sqrt(vx[i] ** 2 + vy[i] ** 2)
if v_travel != 0:
v_travel_unit_x = vx[i] / v_travel
v_travel_unit_y = vy[i] / v_travel
else:
v_travel_unit_x = 0
v_travel_unit_y = 0
#Coriolis acceleration
if r != 0:
a_cor = 2 * omega * v_travel / r
a_cor_unit_x = -v_travel_unit_y
a_cor_unit_y = v_travel_unit_x
a_cor_x = a_cor * a_cor_unit_x
a_cor_y = a_cor * a_cor_unit_y
else:
a_cor_x = 0
a_cor_y = 0
# Frictional acceleration
if v_travel != 0:
a_fric_unit_x = -vx[i] / v_travel
a_fric_unit_y = -vy[i] / v_travel
a_fric = F_normal / m
a_fric_x = a_fric * a_fric_unit_x
a_fric_y = a_fric * a_fric_unit_y
else:
a_fric_x = 0
a_fric_y = 0
# Total accelerations:
a_x = a_cor_x + a_fric_x + a_cenf_x # acceleration in x-direction
a_y = a_cor_y + a_fric_y +a_cenf_y # acceleration in y-direction
# Egg positions:
x_egg = x[i] + vx[i] * dt + 0.5 * a_x * dt ** 2
y_egg = y[i] + vy[i] * dt + 0.5 * a_y * dt ** 2
vx_egg = vx[i] + a_x * dt
vy_egg = vy[i] + a_y * dt
F_collide = 0
#Collision events:
if x_egg <= left_barrier:
vx_collide.append(vx[-1])
vx_egg = -vx[i]
x_egg = left_barrier
F_collide = m * 2 * abs(vx_egg) / t_collide
elif x_egg >= right_barrier:
vx_collide.append(vx[-1])
vx_egg = -vx[i]
x_egg = right_barrier
F_collide = m * 2 * abs(vx_egg) / t_collide
elif y_egg <= bot_barrier:
vy_collide.append(vy[-1])
vy_egg = -vy[i]
y_egg = bot_barrier
F_collide = m * 2 * abs(vy_egg) / t_collide
elif y_egg >= top_barrier:
vy_collide.append(vy[-1])
vy_egg = -vy[i]
y_egg = top_barrier
F_collide = m * 2 * abs(vy_egg) / t_collide
F_list.append(F_collide)
x.append(x_egg)
y.append(y_egg)
vx.append(vx_egg)
vy.append(vy_egg)
# Identifying last collision velocity
if F_collide >= F_break:
if omega in [11, 12]:
print(f"Velocity before egg-breaking collision for omega = 12rad/s is vx = {vx[-2]:.5f} m/s; vy = {vy[-2]:.5f} m/s")
egg_broken = True
break
if omega == 11 and i == 99:
print(f"Velocity before the last collision for omega = 11rad/s is vx = {vx_collide[-1]:.5f} m/s; vy = {vy_collide[-1]:.5f} m/s")
Velocity before the last collision for omega = 11rad/s is vx = -85.98811 m/s; vy = 54.73307 m/s Velocity before egg-breaking collision for omega = 12rad/s is vx = -134.07946 m/s; vy = -17.97003 m/s
By-hand method calculation¶
Renotes that I assumed all collisions are elastic except for egg-breaking one, thus vy before and after collision is the same, thus no force was applied in y-direction. Indeed, the two by-hand collisions agree with the simulation results.
A1.2:¶
For the second appendix, I want to ensure that the fictitious accelerations acted correctly (directions and magnitudes). To do this, I will pick one random point on the trajectory of the egg for the omega = 12 rad/s case. Then, I will calculate the net acceleration at that point using equations from my reference textbook. And eventually relooking at the simulation trajectory to compare if the egg's velocity actually changes according to the calculated acclerations.
The code below is to determine the point:
import matplotlib.pyplot as plt
import numpy as np
#Box dimension
left_barrier = -10
right_barrier = 10
top_barrier = 10
bot_barrier = -10
t_collide = 0.005
#Time event:
dt = 0.01
t_max = 10
t_list = []
#Egg's info
m = 0.0005
F_break = 24.5
omega_list = []
max_forces_per_omega = []
#Varying w from 0 to 19:
for j in range(0, 20):
omega = j
omega_list.append(omega)
x = [0]
y = [0]
vx = [1]
vy = [1]
# Frictional force:
miu_k = 0.8
F_normal = miu_k * m * 9.81
F_list = []
egg_broken = False
# Position of egg:
for i in range(100):
r = np.sqrt(x[-1] ** 2 + y[-1] ** 2)
if r != 0:
r_unit_x = x[-1] / r
r_unit_y = y[-1] / r
else:
r_unit_x = 0
r_unit_y = 0
# Centrifugal accelerations:
if r != 0:
a_cenf = (omega**2) / r
a_cenf_x = a_cenf * r_unit_x
a_cenf_y = a_cenf * r_unit_y
else:
a_cenf_x = 0
a_cenf_y = 0
#Egg's speed:
v_travel = np.sqrt(vx[i] ** 2 + vy[i] ** 2)
if v_travel != 0:
v_travel_unit_x = vx[i] / v_travel
v_travel_unit_y = vy[i] / v_travel
else:
v_travel_unit_x = 0
v_travel_unit_y = 0
# Coriolis acceleration
if r != 0:
a_cor = 2 * omega * v_travel / r
a_cor_unit_x = -v_travel_unit_y
a_cor_unit_y = v_travel_unit_x
a_cor_x = a_cor * a_cor_unit_x
a_cor_y = a_cor * a_cor_unit_y
else:
a_cor_x = 0
a_cor_y = 0
#Frictional acceleration:
if v_travel != 0:
a_fric_unit_x = (
-vx[i] / v_travel
) # kinetic friction acceleration unit vector in x-direction
a_fric_unit_y = (
-vy[i] / v_travel
) # kinetic friction acceleration unit vector in y-direction
a_fric = F_normal / m # kinetic friction magnitude
a_fric_x = a_fric * a_fric_unit_x # kinetic friction in x-direction
a_fric_y = a_fric * a_fric_unit_y # kinetic friction in y-direction
else:
a_fric_x = 0
a_fric_y = 0
# Total accelerations:
a_x = a_cor_x + a_fric_x + a_cenf_x # acceleration in x-direction
a_y = a_cor_y + a_fric_y + a_cenf_y # acceleration in y-direction
# Egg positions:
x_egg = x[i] + vx[i] * dt + 0.5 * a_x * dt**2
y_egg = y[i] + vy[i] * dt + 0.5 * a_y * dt**2
vx_egg = vx[i] + a_x * dt
vy_egg = vy[i] + a_y * dt
F_collide = 0
# Collision events:
if x_egg <= left_barrier:
vx_egg = -vx[i]
x_egg = left_barrier
F_collide = m * 2 * abs(vx_egg) / t_collide
elif x_egg >= right_barrier:
vx_egg = -vx[i]
x_egg = right_barrier
F_collide = m * 2 * abs(vx_egg) / t_collide
elif y_egg <= bot_barrier:
vy_egg = -vy[i]
y_egg = bot_barrier
F_collide = m * 2 * abs(vy_egg) / t_collide
elif y_egg >= top_barrier:
vy_egg = -vy[i]
y_egg = top_barrier
F_collide = m * 2 * abs(vy_egg) / t_collide
F_list.append(F_collide)
x.append(x_egg)
y.append(y_egg)
vx.append(vx_egg)
vy.append(vy_egg)
# Printing the properties of 16th dot from w = 12 rad/s
if i == 15 and j == 12:
print(f"The picked coordinate is the 16th dot with x = {x[-1]:.4f}, y = {y[-1]:.4f}")
print(f"The velocity at the picked coordinate is vx = {vx[-1]:.4f}, vy = {vy[-1]:.4f}")
The picked coordinate is the 16th dot with x = -1.3321, y = 2.6406 The velocity at the picked coordinate is vx = -2.9619, vy = -123.7500
By-hand Analysis:¶
From the above figure, I can indeed see the egg velocity change direction according the the calculated net accceleration (toward the vector 'a' direction). This change in direction looks like the case where there is a centripetal acceleration of a curve.
A1.3:¶
Additional acceleration vectors justification:¶
Appendix 2: Reflection questions¶
Reflection 1: Coding Approaches (A)¶
(How well did you apply and extend your coding knowledge in this project? Consider steps you took to make the code more efficient, readable and/or concise. Discuss any new-to-you coding techniques, functions or python packages that you learned how to use. Reflect on any unforeseen coding challenges you faced in completing this project.)
I had a chance to revise useful coding techniques during this project such as nested for loops, appending lists for plots. A useful new knowledge that I learned is that if I created a list inside a loop, I need to reset or empty the list before the next loop so that every iteration will have consistent starting conditions. This was one of my mistakes that cost me much time to debug. Another helpful thing that I learned is to set a variable for a condition with a True/False so that I can use it for another conditional statement (this was presented in class but I forgot so it is considered new). The biggest challenge in this project is to debug the simulation when it does not behave as I expected. This is difficult since I had to consider multiple factors at a time to evaluate which one was wrong.
Reflection 2: Coding Approaches (B)¶
(Highlight an aspect of your code that you feel you did particularily well. Discuss an aspect of your code that would benefit the most from further effort.)
The part that I think is particularly good is how I append x and y lists for every omega, but only plotting and printing my desired omega values (11 & 12 rad/s). This is because x and y lists are emptied in the next iteration and I set the desired condition (True/False, omega = ...) to plot and print only at the end of the particular iterations. The aspect that would be most improved from further effort is my method to plot the egg's trajectory since I believe I could save much time and coding length if I use the function methods (Euler's method, solve_ivp).
Reflection 3: Simulation phyiscs and investigation (A)¶
(How well did you apply and extend your physical modelling and scientific investigation skills in this project? Consider the phase space you chose to explore and how throroughly you explored it. Consider how you translated physics into code and if appropriate any new physics you learned or developed a more thorough understanding of.)
I think I applied my physical modelling to some certain extent. I learned to set multiple initial conditions so that they are compatible with how I plan to simulate. But, I also admitted real-life case is much more complicated than my simulation. Also, I actually barely learned new physics during this project since they are mostly based on the textbook and my knowledge from my previous physics course.
Reflection 4: Simulation phyiscs and investigation (B)¶
(Highlight something you feel you did particularily well in terms of the context of your simulation, the physical modelling that you did or the investigation you performed. Discuss an aspect of these dimensions of your project that would benefit the most from further effort.)
The part I feel I did well is how I found a way to incorporate cross-products from Coriolis and centrifugal acceleration's equations into my simulation by finding unit direction vectors from velocity and position. This can only be achieved because Coriolis acceleration's direction is always perpendicular and dependent on velocity direction on a single plane, and the centrifugal acceleration's direction is always in the same direction as the position vector. The part is benefits most from further effort might be the collision part. I might need to find a way to find the collision of the egg for each omega value as time approaches infinity, otherwise, if time is limited, there are many cases where the egg has not had a "chance" to break yet.
Reflection 5: Effectiveness of your communication¶
(Highlight something you feel you did particularily well in your visualizations or written communication. Discuss an aspect of your visualizations or written communication that would benefit the most from further effort.)
The visualization I feel I did well is the trajectory plots of the egg on the surface. These plots are very helpful to recognize if the acceleration is operating correctly or if the egg has collided or not. The part that would benefit most from further effort is the communication during completing the coding. I feel like I need to add multiple comments mentioning what I did or adjusted along the way because I will have more information to refer back when doing the reflection questions.