how to calculate x and y co-ordinates when the body is moving downwards, while following elliptical equation
Question:
Assuming that an object is moving vertically downwards as well along Y-axis at a velocity of lets say 0.5 m/s while following the elliptical equation,
major axis radius = 100
minor axis radius = 25
Body’s initial position can be assumed to be at (x,y) = (175, 150). Ellipse Image
I know how to fetch co-ordinates o ellipse when it is not moving downwards.
a = 25
b = 100
h = 150
k = 150
$ x = sqrt{a^2 - {(y-k)^2 * a^2 over b^2} } + h $
$ x = sqrt{25^2 - {(y-150)^2 * 25^2 over 100^2} } + 150 $
# Python code:
t = np.linspace(0,360,360)
x = 150 + 25*np.cos(np.radians(t)) # 150 is major axis of ellipse
y = 150 + 100*np.sin(np.radians(t)) # 150 is minor axis of ellipse
# plt.plot(x,y)
# plt.show()
df = pd.DataFrame(list(zip(x, y)), columns = ['x', 'y'])
# remove duplicate rows
df = df.drop_duplicates(keep = 'first')
ax = sns.scatterplot(data = df, x = 'x', y = 'y')
ax.set_xlim(0, 400)
ax.set_ylim(0, 300)
plt.grid()
def solve_for_x(y):
a = 25
b = 100
h = 150
k = 150
x1 = math.sqrt(a**2 - ( ( (y-k)**2 * a**2 )/b**2 )) + h
x2 = - math.sqrt(a**2 - ( ( (y-k)**2 * a**2 )/b**2 )) + h
# print(f'x = {x}')
return x1, x2
This code will return both sides of ellipse.
But my question is how to calculate x and y co-ordinates when the body is moving downwards. I imagine the path traced will be a weird 2d spring like structure.
Answers:
When I graph the parametric equation, I’m finding that the downward motion occurs where t is 90 to 270 degrees.
You could capture only this portion of the graph by changing the line where t is assigned:
t = np.linspace(90, 270, 360)
If you want fewer slices, change the third number to be smaller.
For printing’s sake, I will shorten num to 10.
t = np.linspace(90, 270, 10)
Running the script in interactive mode,
>>> df
x y
0 150.000000 250.000000
1 141.449496 243.969262
2 133.930310 226.604444
3 128.349365 200.000000
4 125.379806 167.364818
5 125.379806 132.635182
6 128.349365 100.000000
7 133.930310 73.395556
8 141.449496 56.030738
9 150.000000 50.000000
If you are somehow restricted using your original t values, it’s also possible to slice the dataframe however you’d like.
Rerunning script with
t = np.linspace(0, 360, 360)
Command line
>>> df[90:270:10]
x y
90 149.890613 249.999043
100 145.539153 248.395190
110 141.323987 243.785014
120 137.373904 236.309370
130 133.809594 226.196667
140 130.739958 213.755883
150 128.258786 199.367130
160 126.441885 183.470035
170 125.344768 166.550311
180 125.000957 149.124916
190 125.420956 131.726257
200 126.591933 114.885927
210 128.478109 99.118457
220 131.021856 84.905600
230 134.145453 72.681609
240 137.753463 62.819971
250 141.735649 55.621994
260 145.970340 51.307602
You have to define the angular speed of a point on your ellipse, and from that you can determine a new np.linspace
array that will represent time. Then you can simply substract 1/2*g*time**2
from your y
array to get the y-coordinates of points on the falling ellipse.
I added a colormap to represent the time too.
# Imports.
import matplotlib.pyplot as plt
import numpy as np
# Constants.
G = 9.81
ANGULAR_SPEED = 60 # °/s
SPINS = 2.5
POINTS = 10000
# "Physics!"
angle = np.linspace(0, 360*SPINS, POINTS)
x = 150 + 25*np.cos(np.radians(angle))
ys = 150 + 100*np.sin(np.radians(angle)) # Static.
time = angle/ANGULAR_SPEED
yf = ys - 1/2*G*time**2
# Show the result.
fig, ax = plt.subplots()
# ax.set_aspect(1) # Optional: so that autoscaling doesn't squish our ellipse into a circle.
ax.scatter(x, ys, label="static ellipse")
ax.scatter(x, yf, label="falling ellipse", c=time, cmap="autumn")
ax.legend()
fig.show()
If you want to stick to a constant downward velocity, it’s possible too:
# Constants.
...
VY = -200
...
# "Physics!"
...
yf = ys + VY*time
...
Assuming that an object is moving vertically downwards as well along Y-axis at a velocity of lets say 0.5 m/s while following the elliptical equation,
major axis radius = 100
minor axis radius = 25
Body’s initial position can be assumed to be at (x,y) = (175, 150). Ellipse Image
I know how to fetch co-ordinates o ellipse when it is not moving downwards.
a = 25
b = 100
h = 150
k = 150
$ x = sqrt{a^2 - {(y-k)^2 * a^2 over b^2} } + h $
$ x = sqrt{25^2 - {(y-150)^2 * 25^2 over 100^2} } + 150 $
# Python code:
t = np.linspace(0,360,360)
x = 150 + 25*np.cos(np.radians(t)) # 150 is major axis of ellipse
y = 150 + 100*np.sin(np.radians(t)) # 150 is minor axis of ellipse
# plt.plot(x,y)
# plt.show()
df = pd.DataFrame(list(zip(x, y)), columns = ['x', 'y'])
# remove duplicate rows
df = df.drop_duplicates(keep = 'first')
ax = sns.scatterplot(data = df, x = 'x', y = 'y')
ax.set_xlim(0, 400)
ax.set_ylim(0, 300)
plt.grid()
def solve_for_x(y):
a = 25
b = 100
h = 150
k = 150
x1 = math.sqrt(a**2 - ( ( (y-k)**2 * a**2 )/b**2 )) + h
x2 = - math.sqrt(a**2 - ( ( (y-k)**2 * a**2 )/b**2 )) + h
# print(f'x = {x}')
return x1, x2
This code will return both sides of ellipse.
But my question is how to calculate x and y co-ordinates when the body is moving downwards. I imagine the path traced will be a weird 2d spring like structure.
When I graph the parametric equation, I’m finding that the downward motion occurs where t is 90 to 270 degrees.
You could capture only this portion of the graph by changing the line where t is assigned:
t = np.linspace(90, 270, 360)
If you want fewer slices, change the third number to be smaller.
For printing’s sake, I will shorten num to 10.
t = np.linspace(90, 270, 10)
Running the script in interactive mode,
>>> df
x y
0 150.000000 250.000000
1 141.449496 243.969262
2 133.930310 226.604444
3 128.349365 200.000000
4 125.379806 167.364818
5 125.379806 132.635182
6 128.349365 100.000000
7 133.930310 73.395556
8 141.449496 56.030738
9 150.000000 50.000000
If you are somehow restricted using your original t values, it’s also possible to slice the dataframe however you’d like.
Rerunning script with
t = np.linspace(0, 360, 360)
Command line
>>> df[90:270:10]
x y
90 149.890613 249.999043
100 145.539153 248.395190
110 141.323987 243.785014
120 137.373904 236.309370
130 133.809594 226.196667
140 130.739958 213.755883
150 128.258786 199.367130
160 126.441885 183.470035
170 125.344768 166.550311
180 125.000957 149.124916
190 125.420956 131.726257
200 126.591933 114.885927
210 128.478109 99.118457
220 131.021856 84.905600
230 134.145453 72.681609
240 137.753463 62.819971
250 141.735649 55.621994
260 145.970340 51.307602
You have to define the angular speed of a point on your ellipse, and from that you can determine a new np.linspace
array that will represent time. Then you can simply substract 1/2*g*time**2
from your y
array to get the y-coordinates of points on the falling ellipse.
I added a colormap to represent the time too.
# Imports.
import matplotlib.pyplot as plt
import numpy as np
# Constants.
G = 9.81
ANGULAR_SPEED = 60 # °/s
SPINS = 2.5
POINTS = 10000
# "Physics!"
angle = np.linspace(0, 360*SPINS, POINTS)
x = 150 + 25*np.cos(np.radians(angle))
ys = 150 + 100*np.sin(np.radians(angle)) # Static.
time = angle/ANGULAR_SPEED
yf = ys - 1/2*G*time**2
# Show the result.
fig, ax = plt.subplots()
# ax.set_aspect(1) # Optional: so that autoscaling doesn't squish our ellipse into a circle.
ax.scatter(x, ys, label="static ellipse")
ax.scatter(x, yf, label="falling ellipse", c=time, cmap="autumn")
ax.legend()
fig.show()
If you want to stick to a constant downward velocity, it’s possible too:
# Constants.
...
VY = -200
...
# "Physics!"
...
yf = ys + VY*time
...