curriculum/challenges/english/blocks/learn-encapsulation-by-building-a-projectile-trajectory-calculator/6616ec0bf9ee8548ce6b0f08.md
Now it's time to work on calculating the coordinates of the trajectory! Create a method of the Projectile class named __calculate_y_coordinate, it should have, other than self, an x parameter.
\[ y = y_0 + x \tan\theta - \frac{g x^2}{2 v_0^2 \cos^2\theta} \]
The above is the formula to calculate the vertical position $y$ for any given horizontal position $x$, having the starting angle $\theta$, speed $v_0$ and height $y_0$.
You will need to use math.tan() and math.cos() and remember that x ** y is the way to write $x^y$, and that the value of $g$ is in the variable GRAVITATIONAL_ACCELERATION.
Implement the method so that it returns the $y$ coordinate.
If you want to test the method, from outside of class, you can call ball._Projectile__calculate_y_coordinate() with a number as an argument after ball is declared.
Your Projectile class should have a method named __calculate_y_coordinate.
({test: () => {assert(runPython(`_Node(_code).find_class('Projectile').has_function('__calculate_y_coordinate')`))}})
The __calculate_y_coordinate method should have self, x as arguments.
({test: () => {assert(runPython(`_Node(_code).find_class('Projectile').find_function('__calculate_y_coordinate').has_args('self, x')`))}})
The method should return the correct value. For Projectile(12, 12, 12), given the 4 $x$ coordinates of 0, 1, 2 and 3, the y coordinate should be approximately 12, 12.18, 12.28, 12.32.
({test: () => {
assert(runPython(`
a = Projectile(12, 12, 12)
all([round(a._Projectile__calculate_y_coordinate(x), 2) == y for x,y in [(0, 12.0), (1, 12.18), (2, 12.28), (3, 12.32)]])
`))
}})
The method should return the correct value. For Projectile(45, 12, 22), given the $x$ coordinates of 6, 9, 10 and 12 the y coordinate should be approximately 14.32, 15.41, 15.76, 16.44.
({test: () => {
assert(runPython(`
b = Projectile(45, 12, 22)
all([round(b._Projectile__calculate_y_coordinate(x), 2) == y for x,y in [(6, 14.32), (9, 15.41), (10, 15.76), (12, 16.44)]])
`))
}})
The __calculate_y_coordinate method should not round the result.
({test: () => assert.isFalse(runPython(`Projectile(12, 13, 14)._Projectile__calculate_y_coordinate(5) == round(Projectile(12, 13, 14)._Projectile__calculate_y_coordinate(5), 2)`))})
import math
GRAVITATIONAL_ACCELERATION = 9.81
PROJECTILE = "∙"
x_axis_tick = "T"
y_axis_tick = "⊣"
class Projectile:
__slots__ = ('__speed', '__height', '__angle')
def __init__(self, speed, height, angle):
self.__speed = speed
self.__height = height
self.__angle = math.radians(angle)
def __str__(self):
return f'''
Projectile details:
speed: {self.__speed} m/s
height: {self.__height} m
angle: {round(math.degrees(self.__angle))}°
displacement: {round(self.__calculate_displacement(), 1)} m
'''
def __calculate_displacement(self):
horizontal_component = self.__speed * math.cos(self.__angle)
vertical_component = self.__speed * math.sin(self.__angle)
squared_component = vertical_component**2
gh_component = 2 * GRAVITATIONAL_ACCELERATION * self.__height
sqrt_component = math.sqrt(squared_component + gh_component)
return horizontal_component * (vertical_component + sqrt_component) / GRAVITATIONAL_ACCELERATION
--fcc-editable-region--
--fcc-editable-region--
ball = Projectile(10, 3, 45)
print(ball)