I am trying to make a program that will find the x and y components of an applied force at an angle. Here is what I have so far. When I run it I get an error that basically says that you cannot take the cosine of a variable and that it has to be a real number. How would I make this type of program work?
Import math
Angle = input("Enter angle:")
Force = input("Enter applied force:")
X = math.cos(angle)
Y = x * force
Print("The x component of the applied force is", y)
B = math.cos(angle)
A = b * force
Print("The y component of the applied force is", A)
Here's code after fixing capitalization and changing type of inputted values to floats:
import math
angle = float(input("Enter angle:"))
force = float(input("Enter applied force:"))
x = math.cos(angle)
y = x * force
print("The x component of the applied force is", y)
b = math.cos(angle)
a = b * force
print("The y component of the applied force is", a)
Related
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.
I'm trying to write a program that will take a set of longitude & latitude coordinates from the user, convert them to x & y coordinates for a Mollweide projection map, and then report the value of the pixel at those coordinates (in this case, a noise temperature).
The map/data I'm using is the Haslam 408 MHz All Sky Survey which is provided as a Mollweide projection map. This data is in .fits format and is a large all-sky survey of noise in the 408 MHz band.
According to the Mollweide projection Wikipedia page, it is possible to use a Newton-Raphson iteration to convert from longitude/latitude to x/y map coordinates. I based the iteration scheme in my program largely on the methods from the Wikipedia page and in this GitHub post.
However, my program does not appear to be reporting the correct values for the longitude and latitude that I'm inputting. I largely suspect that one of two (or both) factors are contributing to this error:
The way that I'm implementing the iteration scheme is incorrect, and thus resulting in incorrect values being reported.
I don't properly understand what the radius value, R, represents in the iteration scheme. I can't find any literature on how to determine the proper R value beyond that "R is the radius of the globe to be projected." I assumed that this would be based upon the size of the map in pixels; in this case, the map image is 4096x2048 pixels, so I've tried using 2048, 1024, and simply 1 as the R values, to no avail.
Below I have provided my code for review:
from math import sin, cos, pi, sqrt, asin
from astropy.io import fits
hdulist = fits.open('data.fits')
hdulist.info()
data = hdulist[1].data
sqrt2 = sqrt(2)
def solveNR(lat, epsilon=1e-6): #this solves the Newton Raphson iteration
if abs(lat) == pi / 2:
return lat # avoid division by zero
theta = lat
while True:
nexttheta = theta - (
(2 * theta + sin(2 * theta) - pi * sin(lat)) /
(2 + 2 * cos(2 * theta))
)
if abs(theta - nexttheta) < epsilon:
break
theta = nexttheta
return nexttheta
def checktheta(theta, lat): #this function is also currently unused while debugging
return (2 * theta + sin(2 * theta), pi * sin(lat))
def mollweide(lat, lon, lon_0=0, R=1024):
lat = lat * pi / 180
lon = lon * pi / 180
lon_0 = lon_0 * pi / 180 # convert to radians
theta = solveNR(lat)
return (R * 2 * sqrt2 * (lon - lon_0) * cos(theta) / pi,
R * sqrt2 * sin(theta))
def inv_mollweide(x, y, lon_0=0, R=1024, degrees=True): # inverse procedure (x, y to lat, long). Currently unused
theta = asin(y / (R * sqrt2))
if degrees:
factor = 180 / pi
else:
factor = 1
return (
asin((2 * theta + sin(2 * theta)) / pi) * factor,
(lon_0 + pi * x / (2 * R * sqrt(2) * cos(theta))) * factor
)
def retrieve_temp(lat, long): #retrieves the noise temp from the data file after calling the mollweide function
lat = int(round(lat))
long = int(round(long))
coords = mollweide(lat, long)
x, y= coords
x = int(round(x))
y= int(round(y))
x = x-1
y = y-1
if x < 0:
x = x*(-1)
if y < 0:
y = y*(-1)
print("The noise temperature is: ",data[y, x],"K")
def prompt(): #this is the terminal UI
cont = 1
while cont == 1:
lat_cont = 1
while lat_cont == 1:
lat = float(input('Please enter the latitude: '))
lat_val = 1
while lat_val == 1:
if lat > 180 or lat < -180:
lat = float(input('Invalid input. Make sure your latitude value is in range -180 to 180 degrees \n'
'Please enter the latitude: '))
else:
lat_val = 0
lat_cont = 0
long_cont = 1
while long_cont == 1:
long = float(input('Please enter the longitude: '))
long_val = 1
while long_val == 1:
if long > 90 or long < -90:
long = float(input('Invalid input. Make sure your latitude value is in range -90 to 90 degrees \n'
'Please enter the latitude: '))
else:
long_val = 0
long_cont = 0
retrieve_temp(lat, long)
valid = 1
while valid == 1:
ans = input('Would you like to continue? Y or N: ').lower()
ans_val = 1
while ans_val ==1:
if not (ans == 'y' or ans == 'n'):
ans = input('Invalid input. Please answer Y or N to continue or exit: ')
elif ans == 'y':
ans_val = 0
cont = 1
valid = 0
elif ans == 'n':
ans_val = 0
cont = 0
valid = 0
prompt()
hdulist.close()
Apologies if I failed to follow typical Python conventions in the above code; I'm new to Python.
Your code looks reasonable. My advice about figuring out what's wrong:
(1) Try evaluating your mollweide and inv_mollweide functions at points for which you know what the results are supposed to be. E.g. points on the equator or prime meridian or something easy like that.
(2) Are your mollweide and inv_mollweide actually inverses? i.e. if you take your output from the one and put it into the other, you should get the original input back again.
(3) How do results change as you move around on the map? Do you get correct results in some areas (e.g. near middle of map) and not others? What happens as you get nearer to the edges? Does it gradually become more inaccurate or is there some threshold, beyond which you get grossly incorrect answers?
I think a feature of Newton's method is that it converges only if you're close enough to a solution to begin with, otherwise you can get anything. I don't know how close you have to be, for this problem.
This seems like a great problem. Good luck and have fun.
so this is going to sound really strange, but as far as I know there aren't actually any good Python libraries for Mollweide conversions, at least for Mollweide maps that span the entire earth. The EPSG system is bizarrely incomplete, which makes Pyproj more or less unusable for this purpose. I plan on using your code as part of a project of my own, but if you'd like to setup a github library and maybe even some kind of pip functionality (I'm fairly new to Python myself, so I'm really not who to ask on how to do that), I'm happy to give you credit.
The program calculates the points of an end-effector with forward kinematics using the equation,
x = d1cos(a1) + d2cos(a1+a2)
y = d1sin(a1) + d2sin(a1+a2)
where d1 is the length of the first joint, d2 is the length of the second joint, a1 is the angle of the first joint and a2 is the angle of the second joint.
It calculates inverse kinematics by this equation
So, by entering the input required for forward kinematics I should get the points of the end effector. By entering in the same input and the points found in forward kinematics for inverse kinematics, I should get the angles I entered in as input for forward kinematics. But I do not get them back.
Here is my code,
'''
Created on Oct 5, 2015
#author: justin
'''
import math
def getOption():
print('Select an option:\n')
print('\t1) Forward Kinematics\n')
print('\t2) Inverse Kinematics\n')
option = input()
try:
option = int(option)
if option == 1:
fowardKinematics()
elif option == 2:
inverseKinematics()
else:
print('Not an option')
return
except ValueError:
print('Not an integer/Point cannot be reached')
return
def fowardKinematics():
'''
Ask user for input and computing points of end-effector
'''
length1 = input('Enter length of joint 1 (a1):\n') # Getting input from keyboard
angle1 = input('Enter angle of joint 1 (theta1):\n')
length2 = input('Enter length of joint 2 (a2):\n')
angle2 = input("Enter angle of join 2 (theta2)\n")
try:
length1 = float(length1) # Testing to see if user entered a number
length2 = float(length2) # Testing to see if user entered a number
angle1 = float(angle1) # Testing to see if user entered a number
angle2 = float(angle2) # Testing to see if user entered a number
except ValueError:
print('Invalid input, check your input again')
return
x = (length1 * math.cos(math.radians(angle1))) + (length2 * math.cos((math.radians(angle1 + angle2)))) # a1c1 + a2c12
y = (length1 * math.sin(math.radians(angle1))) + (length2 * math.sin((math.radians(angle1 + angle2)))) # a1s1 + a2s12
print('The position of the end-effector P(x,y) is:\n')
print('X: ' + str(x)) # Convert x to string
print('Y: ' + str(y)) # Convert y to string
def inverseKinematics():
length1 = input('Enter length of joint 1 (a1):\n')
length2 = input('Enter length of joint 2 (a2):\n')
x = input('Enter position of X:\n')
y = input('Enter position of Y:\n')
try:
length1 = float(length1)
length2 = float(length2)
x = float(x)
y = float(y)
except ValueError:
print('Invalid input, check your input again')
return
# Computing angle 2 Elbow up/down
numerator = ((length1 + length2)**2) - ((x**2) + (y**2))
denominator = ((x**2) + (y**2)) - ((length1 - length2)**2)
angle2UP = math.degrees(math.atan(math.sqrt(numerator/denominator)))
angle2DOWN = angle2UP * -1
# Angle 1 Elbow up
numerator = (length2 * math.sin(math.radians(angle2UP)))
denominator = ((length1 + length2) * math.cos(math.radians(angle2UP)))
angle1UP = math.degrees(math.atan2(numerator, denominator))
# Angle 1 Elbow down
numerator = (length2 * math.sin(math.radians(angle2DOWN)))
denominator = ((length1 + length2) * math.cos(math.radians(angle2DOWN)))
angle1DOWN = math.degrees(math.atan2(numerator, denominator))
print("Angle 1 Elbow up: " + str(angle1UP))
print("Angle 1 Elbow down: " + str(angle1DOWN))
print("Angle 2 Elbow up: " + str(angle2UP))
print("Angle 2 Elbow down: " + str(angle2DOWN))
if __name__ == '__main__':
getOption()
pass
I think the problem is when the trig functions get introduced. The parameters for them are supposed to be in radians, they return the answer is degrees. Somewhere I am mixing up the two. I just don't know where. Thanks
There is, I'm afraid, quite a bit wrong with this, either in your code or in the equations you're using. Your equation for theta2 doesn't make any sense to me if x and y are distances and a1 and a2 are angles (check your equation or give a source). Even if these should be d1 and d2, this equation involves subtracting two quantities with different dimensions (length^4 and length^2).
Then check your implementation of it, which does not evaluate the equation as given.
My advice about radians / degrees is to use radians throughout: accept the angles in degrees if you want, but then immediately convert to radians for the calculations, and convert angular results back to degrees for output.
Some more advice:
you don't need to cast your floats to strings for output using print, just use print('x: ', x) and so on.
Give your variables the same names as the symbols they represent in your formula. This would make it easier to debug (well, it would if the equations were correct).
Hope that helps.
Here is my code thus far. I don't know why it doesn't print anything. I hope it isn't because of some stupid mistake.
y = float(raw_input("Enter a number you want square rooted: "))
x = 0
# Newton's Method: y = (x+y)/x + 2
while y > x:
x += 0.1
if x == y/(2*y-1):
print x
else:
pass
Any suggestions or alternatives?
Any help would be greatly appreciated.
Your code doesn't resemble Newton's method at all. Here is code with rewritten logic:
y = float(raw_input("Enter a number you want square rooted: "))
# Solve f(x) = x^2 - y = 0 for x.
# Newton's method: Iterate new_x = x - f(x)/f'(x).
# Note that f'(x) = 2x. Thus new_x = x - (x^2 - y)/(2x).
prevx = -1.0
x = 1.0
while abs(x - prevx) > 1e-10: # Loop until x stabilizes
prevx = x
x = x - (x*x - y) / (2*x)
print(x)
Side note: An alternate but similar way of iteratively approximating the square root is the Babylonian method.
So I am new to python, but have successfully created programs that can calculate area,volume,convert Celsius to Fahrenheit, etc... however, I seem to be having some trouble with this 'slope of a line' program.
# A simple program which prompts the user for two points
# and then computes and prints the corresponding slope of a line.
# slope(S): (R*R)*(R*R) -> R
# If R*R is a pair of real numbers corresponding to a point,
# then slope(S) is the slope of a line.
def x1(A):
def y1(B):
def x2(C):
def y2(D):
def slope(S):
return (D-B)/(C-A)
# main
# Prompts the user for a pair of points, and then computes
# and prints the corresponding slope of the line.
def main():
A = eval(input("Enter the value of x1:"))
B = eval(input("Enter the value of y1:"))
C = eval(input("Enter the value of x2:"))
D = eval(input("Enter the value of y2:"))
S = slope(S)
print("The slope of a line created with those points\
is: {}{:.2f}".format(S,A,B,C,D))
main()
The slope function could be something like the following - a function taking four parameters representing the four coordinates of those two points:
def slope(x1, y1, x2, y2):
return (y1 - y2) / (x1 - x2)
But obviously it should not be this simple, you have to refine it and consider the situation that x1 == x2.
Slope = rise / run. Here is a very simple solution:
- Create a class Point with x and y members.
- Create a method getSlope which takes two points as arguments
- Instantiate two point variables with their x and y coordinates.
- Print the result (which in this case is the return value of the getSlope method.
class Point:
def __init__ (self, x, y):
self.x = x
self.y = y
# This could be simplified; more verbose for readability
def getSlope(pointA, pointB):
rise = float(pointA.y) - float(pointB.y)
run = float(pointA.x) - float(pointB.x)
slope = rise/run
return slope
def main():
p1 = Point(4.0, 2.0)
p2 = Point(12.0, 14.0)
print getSlope(p1, p2)
return 0
if __name__ == '__main__':
main()
If you want to guess the best fit slope from two arrays this is the most textbook answer if X and Y are arrays:
import numpy as np
from __future__ import division
x = np.array([1,2,3,4]
y = np.array([1,2,3,4])
slope = ((len(x)*sum(x*y)) - (sum(x)*sum(y)))/(len(x)*(sum(x**2))-(sum(x)**2))