Determining final velocity at a target distance - python

In this program I've been working on with Python the goal is to take user inputs on a given initial velocity, angle, and how far away a structure is/how tall it is we're aiming for. I have been able to calculate how long it takes for something to reach a target, but I'm not sure why the final velocity (how fast it is going when it reaches the target) is coming up wrong.
# User inputs
velocity = float(input('Give me a velocity to fire at (in m/s): '))
angle = float(input('Give me an angle to fire at: '))
distance = float(input('Give me how far away you are from the
structure: '))
height = float(input('Give me the height of the structure (in meters):
'))
slingshot = 5 #Height of slingshot in meters
gravity = 9.8 #Earth gravity
# Converting angles to radians
angleRad = math.radians(angle)
# Computing our x and y coordinate
x = math.cos(angleRad)
y = math.sin(angleRad)
# Calculations
time = distance/(velocity * x)
vx = x
vy = y + (-9.8 * time)
finalVelocity = math.sqrt((vx ** 2) + (vy ** 2))
# Output of program
print('It takes your bird' , time , 'seconds to reach the structure')
print('Your velocity at the target distance is' , finalVelocity ,
'meters per second.')
Here is a sample input and what the expected output should be:
Input Velocity: 20
Input Angle: 40
Input Distance: 25
Input Height of Structure: 15
Expected Output:
Time to reach structure: 1.63176 s
Final velocity: 15.6384 s
My Program's Output:
Time to reach structure: 1.63176
Final velocity: 15.36755
At first glance it would appear my program is very close, so I suspected a rounding error, but it is mere coincidence with the chosen numbers that they're close.

You miscalculated the horizontal and vertical components of the final velocity. You only used the cosine and sine of the angle, rather than the (magnitude of the) initial velocity times the cosine and sine, respectively. If you modify the following two lines of code, you will obtain the result you were looking for given the sample input you provided:
vx = velocity * x
vy = velocity * y - 9.8 * time
I rewrote your original code a bit and also computed the final height to check whether the structure was hit or not, so feel free to use it if needed:
import math
# User inputs
# v0 = float(input('Give me a velocity to fire at (in m/s): '))
# angle = float(input('Give me an angle to fire at: '))
# distance = float(input('Give me how far away you are from the structure: '))
# height_structure = float(input('Give me the height of the structure (in meters):'))
# Test inputs
v0 = 20
angle = 40
distance = 25
height_structure = 15
# Constants
height_slingshot = 5 # Height of slingshot in meters
g = 9.8 # Earth gravity
# Converting angle to radians
angleRad = math.radians(angle)
# Computing initial velocity components
vx0 = v0 * math.cos(angleRad)
vy0 = v0 * math.sin(angleRad)
# Computing time to travel horizontal distance
t_x = distance / vx0
# Computing final vertical velocity component
vy_final = vy0 - g * t_x
# Computing magnitude of final velocity
v_final = math.sqrt((vx0 ** 2) + (vy_final ** 2))
# Note: Horizontal component is constant
# Computing final height
y_final = height_slingshot + vy0 * t_x - g / 2 * t_x ** 2
# Verify if t_x was computed correctly
# t_y1 = (vy0 + math.sqrt(vy0 ** 2 - 2 * g * y_final)) / g
# t_y2 = (vy0 - math.sqrt(vy0 ** 2 - 2 * g * y_final)) / g
# Output of program
print('It takes your bird', t_x, 'seconds to reach the structure.')
print('Your velocity at the target distance is', v_final,
'meters per second.')
print('\nFinal height: ', y_final)
print('Structure height:', height_structure)
if 0. <= y_final <= height_structure:
print('\nYou hit the structure!')
elif y_final < 0:
print('\nYou missed. Not far enough!')
else:
print('\nYou missed. Too far!')

Related

creating a model of a planet's orbit using matplotlib

as part of my project for python I am attempting to create a model of the orbit of the planets in the solar system, as test I used the data I was provided for Mercury, along with the calculations I was given by my professor for the velocity and accleration of the planet, however upon executing the code it appears to be a straight line instead of an ellepictal orbit as it should be.
Constants:
These are the recommended constants we suggest you use in your calculations:
G (gravitational constant) = 6.67408e-11
Time step = 10000 this is "time" in the below fomulas
Number of steps = 6000 this is the number of x and y locations to collect per planet
Acceleration:
To calculate the acceleration of a planet based on location and gravitational force from the sun:
Where:
x is the x co-ordinate (current location)
y is the y co-ordinate (current location)
G is gravitational constant 6.67408e-11 this never changes
M_sun is the mass of the sun
Broken down further, for x acceleration you can do:
Calc1 = G x M_sun
Calc2 = x^2 + y^2
Calc3 = Calc2^3/2
Calc4 = Calc1/Calc3
Calc5 = Calc4 * (0 - x)
Which is the same for y acceleration except for replacing x with y in Calc5.
Velocity:
Velocity is the directional speed. To update Velocity after a jump in time you can do:
x velocity (new) = x velocity (previous) + (x acceleration * time)
y velocity (new) = y velocity (previous) + (y acceleration * time)
Location:
To update the location after a jump in time you can do:
x location (new) = x location (previous) + (x velocity * time)
y location (new) = y location (previous) + (y velocity * time)
code that i ran (expecting an elleptical orbital model)
import matplotlib.pyplot as plt
planet_1_name="mercury"
planet_1_mass=3.285*10**23
planet_1_diameter=4879
planet_1_xlocation=0
planet_1_ylocation=5.7*10**10
planet_1_xvelocity=47000
planet_1_yvelocity=0
planet_1_xlist=[planet_1_xlocation]
planet_1_ylist=[planet_1_ylocation]
g=6.67408*10**-11
m_sun=2.00*10**30
time_step=10000
number_of_steps=6000
for step in range(6000):
xcalc1= g*m_sun
xcalc2= (planet_1_xlocation)**2 + (planet_1_ylocation)**2
xcalc3= (xcalc2)**3/2
xcalc4= (xcalc1)/(xcalc3)
xcalc5= xcalc4 * (0-(planet_1_xlocation))
ycalc1= g*m_sun
ycalc2= (planet_1_xlocation)**2 + (planet_1_ylocation)**2
ycalc3= (ycalc2)**3/2
ycalc4= (ycalc1)/(ycalc3)
ycalc5= ycalc4 * (0-(planet_1_ylocation))
planet_1_xvelocity= planet_1_xvelocity + (xcalc5 * time_step)
planet_1_yvelocity= planet_1_yvelocity + (ycalc5 * time_step)
planet_1_xlocation= planet_1_xlocation + (planet_1_xvelocity * time_step)
planet_1_ylocation= planet_1_ylocation + (planet_1_yvelocity * time_step)
planet_1_xlist.append(planet_1_xlocation)
planet_1_ylist.append(planet_1_xlocation)
plt.plot(planet_1_xlist,planet_1_ylist)
plt.show()
resulting graph

Trying to figure out how to find the final distance on my turtle with random number

This is my code, I'm trying to figure out how to get the total distance of the entire length that my turtle has traveled and I don't know how to figure it without taking it out of a loop which I can't do because the numsteps is an input. This is for school by the way
for a in range(numsteps):
s = randint(-100,100)
angle = random() * 2 * pi
x = s * cos(angle)
y = s * sin(angle)
walking.goto(x,y)
distance = sqrt(x ** 2 + y ** 2)
finald.goto(x,y)
print("The final distance is {:,.0f}".format(distance))
print("Your total distance traveled is {}")
You have to save your previous position to compute the distance from the current position to it.
Then every time after computing the distance (near the end of the loop) the current position becomes a previous one:
from math import sin, cos, pi, sqrt
from random import random, randint
start_x, start_y = 0, 0 # The starting point coordinates
previous_x, previous_y = start_x, start_y
total_distance = 0 # We will progressively increase it
numsteps = int(input("Number of steps: "))
for __ in range(numsteps):
s = randint(-100, 100)
angle = random() * 2 * pi
x = s * cos(angle)
y = s * sin(angle)
# walking.goto(x, y) # I commented it out for testing
distance = sqrt((x - previous_x) ** 2 + (y - previous_y) ** 2)
total_distance += distance
prev_x, prev_y = x, y
final_distance = sqrt((x - start_x) ** 2 + (y - start_y) ** 2)
print("The final distance is {:,.0f}".format(final_distance))
print("Your total distance traveled is {:,.0f}".format(total_distance))
Note the __ instead of your a (or other regular name) — this special name (one or two underscore characters) indicates that its value is out of our interest.
(Because we use range(numsteps) only as a counter.)
I'd make simplifications based on some observations:
Turtle already knows the distance function, no need to reinvent it
Moving backwards (negative distance) when we can head in any direction is redundant -- it's really no different than moving forward in any direction.
We can more easily calculate how far we did move than measure how far we will move.
This results in code more like:
from math import pi
from random import random
from turtle import Screen, Turtle
numsteps = int(input("Number of steps: "))
screen = Screen()
walking = Turtle()
walking.radians()
total_distance = 0 # sum of all distances traveled
for _ in range(numsteps):
previous = walking.position()
angle = random() * 2 * pi
distance = random() * 100
walking.setheading(angle)
walking.forward(distance)
total_distance += walking.distance(previous)
final_distance = walking.distance(0, 0) # distance from where we started
print("Your final distance traveled is {:,.0f} pixels".format(final_distance))
print("Your total distance traveled is {:,.0f} pixels".format(total_distance))
screen.exitonclick()
OUTPUT
> python3 test.py
Number of steps: 100
Your final distance traveled is 356 pixels
Your total distance traveled is 4,630 pixels
>

"TypeError: 'float' object is not callable" for artillery script

I decided to try and code ballistic computer. Below is the code i've put together that takes the muzzle velocity, the distance and the elevation bearing of a target and outputs the required angle to shoot so that a shell fired will collide at the desired location. Currently i'm suffering with an error in the second last line and i have no clue how to ammend this error. Any help at all would be appreciated.
import math
print("Note that the platform you are firing off must be perfectly flat to ensure optimal accuracy")
print("---------------------------------------------------------------")
g = (-9.81) **#g is negative in this case**
degrees = float(input("What is the angle from horizon of the spotter? [0-90] "))
radians = math.radians(degrees) **#Sin only works with radians**
U = float(input("What is the muzzle velocity of the gun? "))
Target_distance = float(input("What is the distance to the target in Meters? ")) #direct distance to target
y = float(math.sin(radians))**Target_distance #horizontal distance to target**
x = float(math.cos(radians))**Target_distance #elevation to target from you**
print("the elevation of the target is",y)
print("the distance to the targetenter code here is",x)
print("true distance to target is",Target_distance)
max_angle = math.radians(45)
max_dist = ((U**2)/(2*g))*(1+(math.sqrt(1+((2*g*y)/(U**2)*((math.sin(max_angle)*
(math.sin(max_angle)))))))*math.sin(max_angle))#shows the maximum distance of the shell being fired
print (("max gun range is"),-1*max_dist)
print("---------------------------------------------------------------")
theta = math.degrees((math.asin((g*x)/(U**2)))*-1) #equation needs to be halved to get correct solution
solution1 = (theta *0.5)
solution2 = (90 - solution1)
print(solution1)
print(solution2)
print("---------------------------------------------------------------")
#issue here (TypeError 'float' object is not callable) - variables passed in are U,g,x,y
"TypeError: 'float' object is not callable" for artillery script
solution_3 = math.degrees(math.atan((U*U) + (math.sqrt(U*U*U*U - g ( g * (x * x) + ( 2 * y * (U**2)))))) / ( g * x))
print (solution_3)
Use this instead:
solution_3 = math.degrees(math.atan((U**2) + (math.sqrt(U**4 - g * ( g * (x * x) + ( 2 * y * (U**2)))))) / ( g * x))
A * was missing after "g"
import math
g = -9.81
degrees = float(input("What is the angle from horizon of the spotter? [0-90] "))
radians = math.radians(degrees) #Sin only works with radians
U = int(input("What is the muzzle velocity of the gun? "))
Target_distance = float(input("What is the distance to the target in Meters? ")) #direct distance to target
y = float(math.sin(radians)) #Target_distance #horizontal distance to target
x = float(math.cos(radians)) #Target_distance #elevation to target from you
print("the elevation of the target is",y)
print("the distance to the targetenter code here is",x)
print("true distance to target is",Target_distance)
max_angle = math.radians(45)
max_dist = ((U*2)/(2*g))*(1+(math.sqrt(1+((2*g*y)/(U*2)*((math.sin(max_angle) * (math.sin(max_angle)))))))*math.sin(max_angle)) #shows the maximum distance of the shell being fired
print (("max gun range is"),-1*max_dist)
print("---------------------------------------------------------------")
theta = math.degrees((math.asin((g*x)/(U**2)))-1) #equation needs to be halved to get correct
# solution = ???
solution1 = (theta *0.5)
solution2 = (90 - solution1)
print(solution1)
print(solution2)
print("---------------------------------------------------------------")
The problem is that you forgot about sign between brackets * and varibles *
In python gU not working like g*U, you should specify what you want
I think I've found a common issue here:
...
max_dist = ((U2)/(2g))(1+(math.sqrt(1+((2gy)/(U2)((math.sin(max_angle)
... ^ ^ ^ ^ ^
| | | | |
You're getting a call error simply because you are not using the appropriate multiplication operator * for the variables I've pointed out above. This seems to be a common theme in your Python script as well.
It's great to see you implementing equations into code, and while you continue improving your programming skills you must look into organizing and structuring your code for legibility. That way you, the programming errors will be more apparent.

Why has this piece of code to be there?

I try to understand this code and I actually understood the whole thing except these 2 line:
f_grav = gravity * sun.mass * earth.mass * (sun.pos - earth.pos).norm() / (sun.pos - earth.pos).mag2
earth.vel = earth.vel + (f_grav/earth.mass) * dt
Why couldn't it just be: f_grav = gravity * sun.mass * earth.mass / (sun.pos-earth.pos)**2
I also dont get the role of .norm() and .mag2
Here is the whole code snippet of the program(GlowScript):
sunRadius = 10 * realSunRadius # the size for our solar system
earthRadius = sunRadius * 0.25 # note: real value would be sunRadius * 0.01, a good choice for sim is * 0.25
astronomicalUnit = 212.7 * realSunRadius # the distance from Sun to Earth - the Sun is about 100 Sun diameters away
gravity = 6.6e-11 # sets the strength of the gravitational constant to 6.6x10-11 Newton x meters squared per kilograms squared
# create the Sun object
sun = sphere( radius = sunRadius, opacity = 0.7, emissive = True, texture = "http://i.imgur.com/yoEzbtg.jpg" )
sun.mass = 2e30 # mass of the Sun in kilograms is 2,000,000,000,000,000,000,000,000,000,000 kg
sun.pos = vec(0,0,0)
sun.vel = vec(0,0,0)
# place a few sources of light at the same position as the Sun to illuminate the Earth and Moon objects
sunlight = local_light( pos = vec(0,0,0), color=color.white )
more_sunlight = local_light( pos = vec(0,0,0), color=color.white ) # I found adding two lights was about right
# create the Earth object
earth = sphere ( radius = earthRadius, texture = "http://i.imgur.com/rhFu01b.jpg",make_trail=True)
earth.mass = 6e24 # mass of Earth in kilograms
earth.pos = vec(astronomicalUnit, 0, 0)
earth.vel = vec(0,0,-30000) # the Earth is moving around 30000 m/s
dt = 10000
# below is the main loop of the program - everything above is "setup" and now we are in the main "loop" where all the action occurs
while (True): # this will make it loop forever
rate(100) # this limits the animation rate so that it won't depend on computer/browser processor speed
# calculate the force of gravity on each object
f_grav = gravity * sun.mass * earth.mass * (sun.pos - earth.pos).norm() / (sun.pos - earth.pos).mag2
earth.vel = earth.vel + (f_grav/earth.mass) * dt
# update the position of the Earth and Moon by using simple circle trigonometry
earth.pos = earth.pos + earth.vel * dt
(sun.pos-earth.pos) is a vector. I don't think you can do (sun.pos-earth.pos)**2 because you can't square a vector. Unless you're trying to do a dot product of the vector with itself? But the result of a dot product is a scalar, so f_grav would be a scalar. Forces are vectors, so it doesn't make sense to use a dot product there.
In comparison, f_grav = gravity * sun.mass * earth.mass * (sun.pos - earth.pos).norm() / (sun.pos - earth.pos).mag2 makes sense because you're multiplying (sun.pos - earth.pos).norm(), a vector, by three scalars, and dividing by one scalar. So the result is a vector as desired.
.norm() returns a unit vector so that the result is a vector not a scalar. This is the vector form of Newtonian gravity. (See Wikipedia)
.mag2 does the same thing as what is expected from **2, however in general, powers of vectors are not defined, so it wouldn't make sense to define the exponentiation operator on the vector class.

Show how a projectile (turtle) travels over time

I am new to Python, and currently having a rough time with turtle graphics. This is what I am trying to solve
On Turtellini (the planet where Python turtles live) the
transportation system propels turtles with a giant slingshot. A
particular turtle's original location (x0, y0) is (-180, -100). He is
then shot upward at an initial vertical velocity (vy) of 88 units per
second and a horizontal velocity (vx) of 20 units per second to the
right. He travels for 16 seconds. The acceleration due to gravity (g)
is 11 units per second squared. The the location of the turtle at a
given second (t) is calculated as follows: x = x0 + vx * t and y = y0
+ vy * t - g/2 * t2 . This program is to show how a turtle travels over this period of time.
The output should be like this:
Here is what I should do;
set up the constants (vertical velocity, horizontal velocity,
gravity) and variables (x and y coordinates) set up the turtle by
giving him a proper shape, putting his tail up, moving him to the
initial position, putting his tail down make a loop that repeats for
seconds 1 through 16 inclusive. in each iteration of the loop display
the the values of the x and y variables (in the shell window), move
the turtle to those coordinates, have the turtle stamp his shape,
calculate the new values for the x and y variables after the loop
terminates, move the turtle to the last calculated coordinates,
change his color, and stamp his shape, then wait for a mouse click
My code so far:
import turtle
def main():
wn = turtle.Screen()
turtellini = turtle.Turtle()
t = int(input("Blab blab blab: "))
x0 = -180
y0 = -100
vx = 20
vy = 88
g = 11
x = (float(x0 + vx * t))
y = (float(y0 + vy * t - g / 2 * t**2))
turtellini.color("black")
turtellini.shape("turtle")
turtellini.up()
turtellini.goto(-180,-100)
turtellini.down()
for i in range(1,16,1):
turtellini.stamp()
turtellini.forward(i)
turtellini.right(i)
print(x)
print(y)
if __name__ == "__main__":
main()
I know I am doing bad; but can anyone help me to solve this problem?
You seem to have most of the parts and pieces. The biggest issue I see is you didn't put your x,y calculation in the loop. The loop iteration variable i is really t in your motion equations. Each time you calculate a new x,y you simply move the turtle to that position:
import turtle
from math import pi, atan
x0, y0 = -180, -100 # initial location
vx, vy = 20.0, 88.0 # initial velocity in units per second
travel_time = 16 # seconds
g = 11.0 # acceleration due to gravity in units per second squared
turtellini = turtle.Turtle(shape='turtle', visible=False)
turtellini.penup()
turtellini.radians() # to make turtle compatible with math.atan()
turtellini.setheading(pi / 2) # straight up
turtellini.goto(x0, y0)
turtellini.pendown()
turtellini.showturtle()
turtellini.stamp()
for t in range(1, travel_time + 1):
x = x0 + vx * t
y = y0 + vy * t - g / 2 * t**2
turtellini.goto(x, y)
print(x, y)
angle = atan((vy * t - g * t**2) / (vx * t)) # a guess!
turtellini.setheading(angle)
turtellini.stamp()
turtle.exitonclick()
Unlike the gold standard image, I assumed the turtle was aerodynamic like a bullet and travelled head first through the flight. I don't know, and couldn't quickly find, the formula for the flight angle of a projectile so I guessed from the existing formulas:

Categories

Resources