Given a 90 degree angle, print the bisecting angle in degrees.
import math
#given angle
abc = 90
#m is midpoint of ac, therefor
abm = abc/2
mbc = abc - abm
degrees = math.degrees(mbc)
print(degrees)
but when I print it out, i get 2578.3100780887044
if I don't use math.degrees() then I get:
mbc = abc - abm
#degrees = math.degrees(mbc)
print(mbc)
45.0
but what I need is: 45°
I found math.radians() and math.degrees() but I feel like there is something I am missing. Any help?
Python 3 returns a float for every integer or float division. If you want you can floor the result writing: abm = int(abc/2). This will give you mbc as an integer.
On the other hand, math.degrees() converts an angle from radians to degrees, giving a float as a result. If you want to floor the result of the conversion you can do degrees = int(math.degrees(mbc)).
Related
I am trying to convert a quaternion to yaw pitch roll euler angles. I am experiencing problems with the gimbal lock. The first strange thing that occurs is that errors already start to appear when the pitch angle is in the neighbourhood of +-pi/2. I thought problems should only occur at exactly pi/2.
Secondly my code shows an incorrect yaw angle of 180 degrees at a pitch of -90 degrees.
I tried the code at this post and from this site but none of them worked. I also tried the pyquaternion library, but this one does not even attempt to compensate for gimbal lock. In the end I made the python equivalent of this section of a handbook.
This worked the best but still gives the above issues. It seems like a problem that must have been solved a 1000 times but I can't pinpoint the issue.
For the quaternion: [ 0.86169383 0.02081877 -0.5058515 0.03412598] the code returns the correct yaw pitch roll angles: [0.15911653941132517, -60.832556785346696, -9.335093630495875]
For the quaternion: [ 0.81154224 0.01913839 -0.58165337 0.05207959] the code returns the incorrect yaw pitch roll angles: [-173.53260107524108, -71.09657335881491, 0.0]
Here is my code:
def yaw_pitch_roll(self):
"""Get the equivalent yaw-pitch-roll angles aka. intrinsic Tait-Bryan angles following the z-y'-x'' convention
Returns:
yaw: rotation angle around the z-axis in radians, in the range `[-pi, pi]`
pitch: rotation angle around the y'-axis in radians, in the range `[-pi/2, pi/2]`
roll: rotation angle around the x''-axis in radians, in the range `[-pi, pi]`
The resulting rotation_matrix would be R = R_x(roll) R_y(pitch) R_z(yaw)
Note:
This feature only makes sense when referring to a unit quaternion. Calling this method will implicitly normalise the Quaternion object to a unit quaternion if it is not already one.
"""
self._normalise()
qw = self.q[0]
qx = self.q[1]
qy = self.q[2]
qz = self.q[3]
print(2*(qx*qz-qw*qy), self.q)
if 2*(qx*qz-qw*qy)>=0.94: #Preventing gimbal lock for north pole
yaw = np.arctan2(qx*qy-qw*qz,qx*qz+qw*qy)
roll = 0
elif 2*(qx*qz-qw*qy)<=-0.94: #Preventing gimbal lock for south pole
yaw = -np.arctan2(qx*qy-qw*qz,qx*qz+qw*qy)
roll = 0
else:
yaw = np.arctan2(qy*qz + qw*qx,
1/2 - (qx**2 + qy**2))
roll = np.arctan2(qx*qy - qw*qz,
1/2 - (qy**2 + qz**2))
pitch = np.arcsin(-2*(qx * qz - qw * qy))
return yaw, pitch, roll
Having given a Quaternion q, you can calculate roll, pitch and yaw like this:
yaw = atan2(2.0*(qy*qz + qw*qx), qw*qw - qx*qx - qy*qy + qz*qz);
pitch = asin(-2.0*(qx*qz - qw*qy));
roll = atan2(2.0*(qx*qy + qw*qz), qw*qw + qx*qx - qy*qy - qz*qz);
This should fit for intrinsic tait-bryan rotation of xyz-order. For other rotation orders, extrinsic and proper-euler rotations other conversions have to be used.
This works well for me in Autodesk Maya, where other solutions with pole exceptions had strange gimbal effects.
I manage to solve this question for only 1 case out of the 5 in the system. I'm certain that my method is correct, but for some reason it doesn't work out for other cases.
Below is my code
import math
AB = int(input("Enter a value for side AB: "))
while(AB>100 and AB<=0):
AB = input("Enter a value for side AB: ")
BC = int(input("Enter a value for side BC: "))
while(BC>100 and BC<=0):
BC = input("Enter a value for side BC: ")
hyp = math.sqrt(math.pow(AB,2) + math.pow(BC,2)) #find side AC
mhyp = hyp/2 #find side MC
sind = (mhyp/BC) #sin(deg)=opp/hypotenuse
degree = round(((math.asin(sind))/((math.pi)*2))*360,0) #find the angle
print("%d" %(degree) + "°")
For the case when AC and BC are 10, it did yield 45 degrees as the angle. But when AC=1 and BC=100, it produces an error since arcsine cannot accept value beyond 1.7 radians. Same goes for AC=20 and BC=10 and AC=100 and BC=1..
Is this question solvable?
It is a matter of primarily your angle coming in radians and then you converting it into degrees. Rest everything then will fall in place :)
Also, We can see that BM is equal to MC basis the median to hypotenuse property making the triangle MBC as isosceles and hence Angle MBC = Angle MCB.
import math
if __name__ == '__main__':
AB = input()
assert 0<int(AB)<=100
BC = input()
assert 0<int(BC)<=100
assert (int(AB) >= 0 and float(AB).is_integer() == True) and (int(BC) >= 0 and float(BC).is_integer() == True)
AC = math.sqrt((int(AB)**2) + (int(BC)**2))
tan_acb_rad = int(AB)/int(BC)
acb_rad = math.atan(tan_acb_rad) #the angle comes in radians
acb_deg = math.degrees(acb_rad) #you have to convert it into degrees
ang_mbc = acb_deg
print(str(int(round(ang_mbc,0)))+u"\N{DEGREE SIGN}") #adding the degree symbol at end
import math
AB =int(input())
BC =int(input())
degree=u'\N{DEGREE SIGN}'
print(str(int(round(math.degrees(math.atan(AB/BC)))))+degree)
I know this isn't exactly your case but it still might explain your issue
Inverse Sine of a Value Greater than One
Think about what the sine wave or curve looks like. As the angles
change, the sine of the angle goes up and down, but it never goes
above 1 or below -1. In other words, there is no angle with a sine
that is greater than 1.
When you use the sine key, you put in an angle and get out the sine of
that angle. For instance, when you do sin(30) you are finding the
sine of 30 degrees and the calculator says it's 0.5. When you use the
inverse sine (shift-sine) you put in the value of the sine and the
calculator tells you the angle. So, the inverse sine of 0.5 is 30
since a 30 degree angle has a sine of 0.5.
So when you ask the calculator to do the inverse sine of 1.732, you
are asking it what angle has a sine of 1.732. But as we said above,
there is no angle that has a sine greater than 1. The inverse sine or
arcsin of 1.732 does not exist. That's what the calculator is saying.
It sounds like your problem is asking you to try to find angle B in a
triangle with a = 40, b = 80, and A = 60 degrees. Try constructing
such a triangle, and see what happens. We make angle A and mark 80
units on one of its rays for side b, then swing an arc around the
resulting point C with a radius or length of 40, so that its
intersection with the other ray will give point B. What happens?
B
/
/
/
/
/
c / ooooooooo
/ oooo oooo
/ ooo \ ooo
/ oo \
/ o \ a=40
/ o \
/ o \
/ o \
/60 o \
A----------------o----------------C-----------
b=80
So the calculator is correct: there is no such triangle! Obviously we
can't measure angle B at the top if side 'a' is not long enough to
complete the triangle and form that angle.
You made mistake in geometry - BM is median, not a height to AC (they accidentally coincide for isoseles right-angle triangle, but differ in general case).
So angle BMC is not right in general case, and you cannot get sin(theta) as ratio of MC and BC
But there is well-known property of right triangle - center of circumcircle lies in the middle of hypotenuse, so M point in this case is circumcenter.
This fact immediately tells us that BM=MC (two radii), BMC triangle is isosceles and theta = ACB angle.
Solution is pretty simple (note atan using):
import math
AB = 1
BC = 1
theta = math.atan(AB / BC)
degrees = round(theta * 180 / math.pi)
print(degrees)
>> 45
AB = 3
BC = 4
...
>> 37
Part 2 - Determination of Number Density of Particles
If we say that q is the production rate of particles of a specific size, then in an interval dt the total number of particles produced is just q dt. To make things concrete in what follows, please adopt the case:
a = 0.9amax
q = 100000
Consider this number of particles at some distance r from the nucleus. The number density of particles will be number divided by volume, so to find number density we must compute the volume of a shell of radius r with a thickness that corresponds to how far the particles will travel in our time interval dt. Obviously that’s just the velocity of the particle at radius r times the time interval v(r) dt, so the volume of our shell is:
Volume = Shell Surface Area×Shell Thickness = 4πr2v(r)dt
Therefore, the number density, n, at radius r is:
n(r) = q dt /4πr2v(r)dt = q /4πr2v(r) (equation5)
You will note that our expression above will have a singularity for the number density of particles right at the surface of the nucleus, since at that position the outward velocity, v(R), is 0. Obviously this is an indication that we expect the particle density n to drop very rapidly as the dust is accelerated away from the surface. For now, let’s not worry about this point — we don’t need it later — and just graph how the number density varies with distance from the nucleus, starting with the 1st point after the surface value
• Evaluate Eqaution 5 for all calculated points using the parameters for q and a given above.
• Make a log-log graph of the number density versus radius. You should find that, after terminal velocity is achieved, the number density decreases as r−2, corresponding to a slope of -2 on a log-log plot
Current code:
% matplotlib inline
import numpy as np
import matplotlib.pyplot as pl
R = 2000 #Nucleus Radius (m)
GM_n = 667 #Nucleus Mass (m^3 s^-2)
Q = 7*10**27 #Gas Production Rate (molecules s^-1)
V_g = 1000 #Gas Velocity (m s^-1)
C_D = 4 #Drag Coefficient Dimensionless
p_d = 500 #Grain Density (kg m^-3)
M_h2o = .01801528/(6.022*10**23) #Mass of a water molecule (g/mol)
pi = np.pi
p_g_R = M_h2o*Q/(4*np.pi*R**2*V_g)
print ('Gas Density at the comets nucleus: ', p_g_R)
a_max = (3/8)*C_D*(V_g**2)*p_g_R*(1/p_d)*((R**2)/GM_n)
print ('Radius of Maximum Size Particle: ', a_max)
def drag_force(C_D,V_g,p_g_R,pi,a,v):
drag = .5*C_D*((V_g - v)**2)*p_g_R*pi*a**2
return drag
def grav_force(GM_n,M_d,r):
grav = -(GM_n*M_d)/(r**2)
return grav
def p_g_r(p_g_R,R,r):
p_g_r = p_g_R*(R**2/r**2)
return p_g_r
dt = 1
tfinal = 100000
v0 = 0
t = np.arange(0.,tfinal+dt,dt)
npoints = len(t)
r = np.zeros(npoints)
v = np.zeros(npoints)
r[0]= R
v[0]= v0
a = np.array([0.9,0.5,0.1,0.01,0.001])*a_max
for j in range(len(a)):
M_d = 4/3*pi*a[j]**3*p_d
for i in range(len(t)-1):
rmid = r[i] + v[i]*dt/2.
vmid = v[i] + (grav_force(GM_n,M_d,r[i])+drag_force(C_D,V_g,p_g_r(p_g_R,R,r[i]),pi,a[j],v[i]))*dt/2.
r[i+1] = r[i] + vmid*dt
v[i+1] = v[i] + (grav_force(GM_n,M_d,rmid)+drag_force(C_D,V_g,p_g_r(p_g_R,R,rmid),pi,a[j],vmid))*dt
pl.plot(r,v)
pl.show()
a_2= 0.9*a_max
q = 100000
I have never programmed anything like this before, my class is very difficult for me and I don't understand it. I have developed the above code with the help of the professor, and I am nearly out of time to finish this project. I just want help understanding the problem.
How do I find v(r) when I only have v(t), r(t)?
What do I do to calculate the r values and what r values do I even use?
You have v as a known function of time and also r as another known function of time. You can invert these to get t vs. v and t vs. r. To get v as a function of r, eliminate t.
I have two given lat and lon points. For example, lets assume I have two positions (point_1 and point_2) at coordinates (lat1, lon1) and (lat2, lon2).
I would like to calculate a third point, that is on the same latitude as that of point_2, but x km to the east or west of point_2. So the third point will have the same latitude as point_2, but a different longitude depending on distance x (in kilometers), in other words point_3 will be (lat2, lon?).
I am writing this in IDL, but any other language or formulas would be very welcome.
Thanks
You don't use point 1 anywhere, do you? Let's say our point is P = (lat, lon)
The first rule of problems like this: draw a picture! From a cross-section of the earth, you can see that the radius of the circle centered on the earth's axis, going through your two points, is R*cos(lat). (R is the earth's radius. I hope you don't need to consider the earth an ellipsoid here.) The length x therefore takes up an angle (in degrees) of 360*x/(2*pi*R*cos(lat)). The new point you want is then:
P' = ( lat, lon +- 180*x/(2Rcos(lat)) )
I'm assuming you're using -180 to 0 for west longitude, so you have +/- for east/west. You'll have to check if you need to wrap around. Pseudo-code:
if (lon < -180)
lon += 360
else if (long > 180)
lon -= 360
Just for fun: if you do care about the earth being ellipsoidal, the radius of the circle is (instead of R*cos(lat)):
1/sqrt(tan^2 lat / Rp^2 + 1 / Re^2)
where Rp is the polar radius and Re is the equatorial radius. If Rp = Re, this reduces to the original formula, since 1 + tan^2 lat = sec^2 lat
import math
R = 6378.1 #Radius of the Earth
brng = 1.57 #Bearing is 90 degrees converted to radians.
d = 15 #Distance in km
#lat2 52.20444 - the lat result I'm hoping for
#lon2 0.36056 - the long result I'm hoping for.
lat1 = math.radians(52.20472) #Current lat point converted to radians
lon1 = math.radians(0.14056) #Current long point converted to radians
lat2 = math.asin( math.sin(lat1)*math.cos(d/R) +
math.cos(lat1)*math.sin(d/R)*math.cos(brng))
lon2 = lon1 + math.atan2(math.sin(brng)*math.sin(d/R)*math.cos(lat1),
math.cos(d/R)-math.sin(lat1)*math.sin(lat2))
lat2 = math.degrees(lat2)
lon2 = math.degrees(lon2)
print(lat2)
print(lon2)
It has been quite some time since I've had to compute the theta of an angle. But given a right angle:
|
|
b |
-----------------
a
I'm trying to compute theta (the slope of the angle). My understanding of trigonometry (as rusty as it is) is that theta = arctan(b/a). So if b = 50 and a = 1811. Then using the windows calculator, 50 / 1811 = 0.027609055770292655991165102153506. Therefore the arctan(b/a) = 1.5814806205083755492980816356377. If my math is correct, how do I translate this value into the slope of the angle? It should be around 30-40 degrees, right?
atan2(y, x)
will return you the angle in radians (and successfully cope with the cases where x and/or y are 0).
To convert to degrees apply the following formula:
double degrees = radians * (180 / PI)
Where PI is 3.141592... or math.pi in c#
If you use a C dialect then there a useful function for just this purpose
atan2(y, x);