Python and physics - calculating drag & determining if object has reached terminal velocity - python

I'm trying to calculate the drag of a sphere if it were to be dropped off a building, the program runs but the equations wrong. It could be that I'm just making this overly complexed, but I'm stuck right now.. What I am trying to do is determine the amount of distance the sphere has traveled in the allotted time (Which works), but I am unable to figure out a way to use drag as a factor. Any help would be appreciated
import math
height = float(raw_input("Enter the height of the building: ")) #meters
weight = float(raw_input("Enter the weight of the sphere: ")) #weight of sphere in kilograms
mass = float(raw_input("Mass of the sphere: ")) #mass of the sphere
time = float(raw_input("Enter the time interval: ")) #determines how long to continue the experiment after the sphere has been dropped
# kilograms
#variables
velocity = math.sqrt(2) * height * weight #calculate the velocity
energy = 1 / 2 * mass * velocity ** 2 #kinetic energy
gravity = 9.81 #gravity
radius = 0.5 #radius of the sphere being dropped
volume = 4.3 * math.pi * radius ** 3 #calculate the volume
speed = gravity * time #determine the maximum speed in the time allotted
density = mass / volume #determine the density of the sphere
force = mass * gravity #determine the force in newtons
drag = gravity * density * speed ** 2 #calculate the drag
distance = .5 * gravity * time ** 2 #calculate the distance traveled
print "Force = {} Newtons".format(force)
print "The ball is", height - distance, "meters from the ground"
print "The maximum speed of the ball was:", speed
print "It would take the ball {} seconds to reach terminal velocity"#.format(None)
print "Density:", density
print "Drag: ", drag
print "Mass: ", mass
print "Volume: ", volume
print "Velocity: ", velocity

Python 2.7 defaults to integer division, so
energy = 1 / 2 * mass * vellocity ** 2
is equivalent to
energy = (1 // 2) * mass * velocity ** 2 = 0 * mass * velocity ** 2 = 0
To default to floating point division, place the following line at the top of your script:
from __future__ import division
or simply write energy as:
energy = 0.5 * mass * velocity ** 2

Related

Atomic Simulation Using Pygame [duplicate]

I would like to make some kind of solar system in pygame. I've managed to do a fixed one but I thought it would be more interesting to do one with planets moving around the sun and moons around planets etc. Is there a way I could do that (using pygame if possible)?
What I would like is :
Sun = pygame.draw.circle(...)
planet1 = pygame.draw.circle(...)
etc.
a = [planet1, planet2, ...]
for p in a:
move p[2] to pos(x, y)
That is what I think would work but I'm not sure how to do it. Also, I've thought about deleting the ancient planet and drawing a new one right next to it, but problem is I'm using random features (like colours, distance to the sun, number of planets in the system etc.) and it would have to keep these same features. Any ideas?
Thanks in advance!
You can implement gravity with Newton's Law of Universal Gravitation and Newton's Second Law to get the accelerations of the planets. Give each planet an initial position, velocity and mass. Acceleration is change in velocity a = v * dt, velocity is change in position v = r * dt, so we can integrate to find velocity and position.
Universal gravitation: F = G * m1 * m2 / r ** 2 where F is the magnitude of the force on the object, G is the gravitational constant, m1 and m2 are the masses of the objects and r is the distance between the two objects.
Newton's Second Law: F = m1 * a where a is the acceleration.
dt = 0.01 # size of time step
G = 100 # gravitational constant
def calcGravity(sun, planet):
'Returns acceleration of planet with respect to the sun'
diff_x = sun.x - planet.x
diff_y = sun.y - planet.y
acceleration = G * sun.mass / (diff_x ** 2 + diff_y ** 2)
accel_x = acceleration * diff_x / (diff_x ** 2 + diff_y ** 2)
accel_y = acceleration * diff_y / (diff_x ** 2 + diff_y ** 2)
return accel_x, accel_y
while True:
# update position based on velocity
planet.x += planet.vel_x * dt
planet.y += planet.vel_y * dt
# update velocity based on acceleration
accel_x, accel_y = calcGravity(sun, planet)
planet.vel_x += accel_x * dt
planet.vel_y += accel_y * dt
This can produce circular and elliptical orbits. Creating an orbiting moon requires a very small timestep (dt) for the numeric integration.
Note: this approach is subtly inaccurate due to the limits of numeric integration.
Sample implementation in pygame here, including three planets revolving around a sun, a moon, and a basic orbital transfer.
https://github.com/c2huc2hu/orbital_mechanics
Coordinates of a planet rotated about the Sun through some angle with respect to the X-axis are , where r is the distance to the Sun, theta is that angle, and (a, b) are the coordinates of the sun. Draw your circle centered at (x, y).
EDIT:
General elliptical orbit:
Where
r0 is the radius of a circular orbit with the same angular momentum, and e is the "eccentricity" of the ellipse

Calculate the output of volume and surface area of a sphere

The volume and surface area of a sphere can be calculated with the following formulas. Create this as a terminal application. Write one function for volume and another function for surface area. The results should display both the volume and the surface area rounded to 2 decimal places. Use pi from Python’s math module. Include the following doctests. You must get pass
all tests to receive full credit. Pay close attention to how you name your functions. They must
match
volume examples/doctests:
round(volume_of_sphere(0), 2)
0.0
round(volume_of_sphere(1), 2)
4.19
round(volume_of_sphere(12.3), 2)
7794.78
round(volume_of_sphere(18.9), 2)
28279.65
round(volume_of_sphere(33.33), 2)
155093.84
surface area examples/doctests:
round(surface_area(0), 2)
0.0
round(surface_area(1), 2)
12.57
round(surface_area(12.3), 2)
1901.17
round(surface_area(18.9), 2)
13959.84
round(surface_area(33.33), 2)
155093.84
MY CODE:
''' Python3 program to calculate Volume and
Surface area of Sphere'''
# Importing Math library for value Of PI
import math
pi = math.pi
# Function to calculate Volume of Sphere
def volume(r):
vol = (4 / 3) * pi * r * r * r
return vol
# Function To Calculate Surface Area of Sphere
def surfacearea(s):
sur_ar = 4 * pi * r * r
return sur_ar
# Driver Code
radius = round(volume(1), 2)
area = round(area(0), 2)
print( "Volume Of Sphere : ", volume(radius) )
print( "Surface Area Of Sphere : ", surfacearea(area) )
The two programs below will find the surface area and the volume of a sphere with the radius. This is just a simpler way. The first program is more accurate but both will do the job.
pi=22/7
radian = float(input('Radius of sphere: '))
sur_area = 4 * pi * radian **2
volume = (4/3) * (pi * radian ** 3)
print("Surface Area is: ", sur_area)
print("Volume is: ", volume)
or
PI = 3.14
radius = float(input('Please Enter the Radius of a Sphere: '))
sa = 4 * PI * radius * radius
Volume = (4 / 3) * PI * radius * radius * radius
print("\n The Surface area of a Sphere = %.2f" %sa)
print("\n The Volume of a Sphere = %.2f" %Volume)
Since there is no obvious question here, I am assuming the objective is to complete the mathematical functions and pass the doctests. Having said that, it would be quite impossible to do that without being mathematically incorrect because the last two doctests for the surface area function are wrong, round(surface_area(18.9), 2) should be 4488.83 not 13959.84 and round(surface_area(33.33), 2) should be 13934.72 and not 155093.84.

Elliptical orbit in vpython

I have the following code. This code is simulation of orbiting objects around other objects, E.g. Solar system. As you run it, the objects orbit in circular trajectory.
import math
from vpython import *
lamp = local_light(pos=vector(0,0,0), color=color.yellow)
# Data in units according to the International System of Units
G = 6.67 * math.pow(10,-11)
# Mass of the Earth
ME = 5.973 * math.pow(10,24)
# Mass of the Moon
MM = 7.347 * math.pow(10,22)
# Mass of the Mars
MMa = 6.39 * math.pow(10,23)
# Mass of the Sun
MS = 1.989 * math.pow(10,30)
# Radius Earth-Moon
REM = 384400000
# Radius Sun-Earth
RSE = 149600000000
RMS = 227900000000
# Force Earth-Moon
FEM = G*(ME*MM)/math.pow(REM,2)
# Force Earth-Sun
FES = G*(MS*ME)/math.pow(RSE,2)
# Force Mars-Sun
FEMa = G*(MMa*MS)/math.pow(RMS,2)
# Angular velocity of the Moon with respect to the Earth (rad/s)
wM = math.sqrt(FEM/(MM * REM))
# Velocity v of the Moon (m/s)
vM = wM * REM
print("Angular velocity of the Moon with respect to the Earth: ",wM," rad/s")
print("Velocity v of the Moon: ",vM/1000," km/s")
# Angular velocity of the Earth with respect to the Sun(rad/s)
wE = math.sqrt(FES/(ME * RSE))
# Angular velocity of the Mars with respect to the Sun(rad/s)
wMa = math.sqrt(FEMa/(MMa * RMS))
# Velocity v of the Earth (m/s)
vE = wE * RSE
# Velocity v of the Earth (m/s)
vMa = wMa * RMS
print("Angular velocity of the Earth with respect to the Sun: ",wE," rad/s")
print("Velocity v of the Earth: ",vE/1000," km/s")
# Initial angular position
theta0 = 0
# Position at each time
def positionMoon(t):
theta = theta0 + wM * t
return theta
def positionMars(t):
theta = theta0 + wMa * t
return theta
def positionEarth(t):
theta = theta0 + wE * t
return theta
def fromDaysToS(d):
s = d*24*60*60
return s
def fromStoDays(s):
d = s/60/60/24
return d
def fromDaysToh(d):
h = d * 24
return h
# Graphical parameters
print("\nSimulation Earth-Moon-Sun motion\n")
days = 365
seconds = fromDaysToS(days)
print("Days: ",days)
print("Seconds: ",seconds)
v = vector(384,0,0)
E = sphere(pos = vector(1500,0,0), color = color.blue, radius = 60, make_trail=True)
Ma = sphere(pos = vector(2300,0,0), color = color.orange, radius = 30, make_trail=True)
M = sphere(pos = E.pos + v, color = color.white,radius = 10, make_trail=True)
S = sphere(pos = vector(0,0,0), color = color.yellow, radius=700)
t = 0
thetaTerra1 = 0
dt = 5000
dthetaE = positionEarth(t+dt)- positionEarth(t)
dthetaM = positionMoon(t+dt) - positionMoon(t)
dthetaMa = positionMars(t+dt) - positionMars(t)
print("delta t:",dt,"seconds. Days:",fromStoDays(dt),"hours:",fromDaysToh(fromStoDays(dt)),sep=" ")
print("Variation angular position of the Earth:",dthetaE,"rad/s that's to say",degrees(dthetaE),"degrees",sep=" ")
print("Variation angular position of the Moon:",dthetaM,"rad/s that's to say",degrees(dthetaM),"degrees",sep=" ")
while t < seconds:
rate(500)
thetaEarth = positionEarth(t+dt)- positionEarth(t)
thetaMoon = positionMoon(t+dt) - positionMoon(t)
thetaMars = positionMars(t+dt) - positionMars(t)
# Rotation only around z axis (0,0,1)
E.pos = rotate(E.pos,angle=thetaEarth,axis=vector(0,1,0))
Ma.pos = rotate(Ma.pos,angle=thetaMars,axis=vector(0,1,0))
v = rotate(v,angle=thetaMoon,axis=vector(0,1,0))
M.pos = E.pos + v
t += dt
I am wondering How to change the path of orbit to elliptical?
I have tried several ways but I could not manage to find any solution.
Thank you.
Thank you
This seems like more of a physics issue as opposed to a programming issue. The problem is that you are assuming that each of the orbits are circular when calculating velocity and integrating position linearly (e.g v * dt). This is not how you would go about calculating the trajectory of an orbiting body.
For the case of simplicity, we will assume all the masses are point masses so there aren't any weird gravity gradients or attitude dynamics to account for.
From there, you can refer to this MIT page. (http://web.mit.edu/12.004/TheLastHandout/PastHandouts/Chap03.Orbital.Dynamics.pdf) on orbit dynamics. On the 7th page, there is an equation relating the radial position from your centerbody as a function of a multitude of orbital parameters. It seems like you have every parameter except the eccentricity of the orbit. You can either look that up online or calculate it if you have detailed ephemeral data or apoapsis/periapsis information.
From that equation, you will see a phi - phi_0 term in the denominator. That is colloquially known as the true anomaly of the satellite. Instead of time, you would iterate on this true anomaly parameter from 0 to 360 to find your radial distance, and from true anomaly, inclination, right angle to the ascending node, and the argument of periapses, you can find the 3D cartesian coordinates at a specific true anomaly.
Going from true anomaly is a little less trivial. You will need to find the eccentric anomaly and then the mean anomaly at each eccentric anomaly step. You now have mean anomaly as a function of time. You can linearly interpolate between "nodes" at which you calculate the position with v * dt. You can calculate the velocity from using the vis-viva equation and dt would be the difference between the calculated time steps.
At each time step you can update the satellite's position in your python program and it will properly draw your trajectories.
For more information of the true anomaly, wikipedia has a good description of it: https://en.wikipedia.org/wiki/True_anomaly
For more information about orbital elements (which are needed to convert from radial position to cartesian coordinates): https://en.wikipedia.org/wiki/Orbital_elements

Using code to write a function that calculates values for Projectile motion

I have an assignment that asks me to use some given code to write a function which calculates the angle needed to hit a target 10 metres away.
here is the given code:
from visual import *
from visual.graph import * # For the graphing functions
#Create a graph display window (gdisplay)
win = gdisplay(xtitle="Distance [m]", ytitle="Height [m]")
#And a curve on this display
poscurve = gcurve(gdisplay=win, color=color.cyan)
#Target position (10 meters away)
target_pos = vector(10,0,0)
#Set the starting angle (in degrees)
angle = 45
#Set the magnitude of the starting velocity (in m/s)
v0 = 12.0
#Gravity vector (m/s**2)
g = vector(0, -9.8, 0)
#Create a vector for the projectile's velocity
velocity = v0 * vector(cos(anglepi/180), sin(anglepi/180), 0)
#and the position
position = vector(0,0,0)
dt = 0.01 # Time step
#Start loop. Each time taking a small step in time
while (position.y > 0) or (velocity.y > 0): # Change in position # dx = (dx/dt) * dt dx = velocity * dt
# Change in velocity
# dv = (dv/dt) * dt
dv = g * dt
# Update the position and velocity
position = position + dx
velocity = velocity + dv
# Plot the current position
poscurve.plot(pos=position)
#When loop finishes, velocity.y must be < 0, and position.y < 0
print "Landed at X position: ", position.x print "X distance to target: ", position.x - target_pos.x
How would I now write a function to calculate the required value? I have no idea where to start, any help would be greatly appreciated!
Thanks
You could use maths to work out an equation for the result.
This works out as:
range = 2v^2/g *cos(a)sin(a)
where v=initial velocity
a=angle
g=gravitational acceleration
You can use this python script to find the answer:
from math import cos
from math import sin
from math import radians
from math import fabs
a=0 # angle in degrees
target=10 # How far you want it to go in m
v=12 # initial velocity in m/s
g=9.81 #gravitational acceleration m/s/s
best_angle=None
nearest_answer=None
while a<45: # we only need to check up to 45 degrees
r = 2*v*v/g*cos(radians(a))*sin(radians(a))
if not nearest_answer or fabs(r-target)<fabs(nearest_answer-target):
nearest_answer = r
best_angle = a
print("{0} -> {1}".format(a,r))
a+=.1 # try increasing the angle a bit. The lower this is the more accurate the answer will be
print("Best angle={}".format(best_angle))

Calculating area of a segment in a circle

You are given the diameter across, and the length of the segment or chord. The diameter for my question is 12, and the chord is 10. You have to find the height of the shaded segment, and then print the area. The original formula is A=2/3ch + h^3/2c. My classmates got 18 for the area, but when I use my code I get 41.
This is the closest picture representation I can find. However there is a dashed line from ϴ to s.
from math import sqrt
diamStr=input("Enter the length of the diameter: ")
diameter=int(diamStr)
chordStr = input( " Enter the chord length: ")
chord = int(chordStr)
radius = (diameter/2)
s = sqrt (diameter**2+chord**2)
h = (s/2-radius)
i= (2/3*chord*h)
j=(h**3/2*chord)
area = (i+j)
print (area)
Unfortunately there's something wrong with your formula but if look at the problem with some elementary mathematics you may notice that the angle ϴ can be found using the cosine rule since we know the 3 lengths (the two radius and chord length)
In Python it would be:
theta = math.acos((radius**2 + radius**2 - chord**2)/(2*radius**2))
Since the variable theta is already in radians we can use this formula to calculate the area of the segment :
which in python would be area = 1/2 * (theta - math.sin(theta)) * radius**2
Therefore after merging all of these we come up with a elegant solution:
import math
diamStr=input("Enter the length of the diameter: ")
diameter=int(diamStr)
chordStr = input( " Enter the chord length: ")
chord = int(chordStr)
radius = (diameter/2)
theta = math.acos((radius**2 + radius**2 - chord**2)/(2*radius**2))
area = 1/2 * (theta - math.sin(theta)) * radius**2
#print(round((area),2))
print(area)
If you enter diameter as 12cm and chord length as 10 you'll get 18.880864248381847 but you can round it to any number of decimal places you want by the round() function.
eg: print(round((area),2)) prints 18.88

Categories