I have 2 values that are in radians, c[1] and c[3]. I need to turn the radians into degrees and I haven't the faintest idea what to do to these numbers to get degrees out of them. I have been searching the internet far and wide and I cant find anything that I can actually understand. I have tried devising my own way to do it but I'm sure I'm not even close. I have tried the following:
z = (((c[1] * 180) + 180) + ((c[3] * 180) + 180))
z = (((c[1] * math.pi) / 180) + ((c[3] * math.pi) / 180) / 2)
z = (c[1] * (90/math.pi) - (c[3] * (90/math.pi)))
z = math.atan2(c[3], c[1])
z = (math.degrees(c[1]) + math.degrees(c[3])) * 2
z = c[1]
z = (math.asin(c[3]) / math.acos(c[1]))
How do I get a value in degrees from 2 radians?
After going through your comment, I don't think that you are getting two angles in radians for c[1] and c[3]. Rather, you are getting direction cosines. If you were getting angles in radians, the value would range from -pi to pi. Rather, the value goes from -1 to 1 (i.e. cos(-pi) to cos(pi)).
You can change the value first to an angle in radians and then to degrees if that is what you want. Just as a caveat, the cosine of angles is symmetric ...
So for:
In [12]: zip(angles, (cos(angles)))
Out[12]:
[(-3.1415926535897931, -1.0),
(-2.8108986900540254, -0.94581724170063464),
(-2.4802047265182576, -0.78914050939639346),
(-2.1495107629824899, -0.5469481581224267),
(-1.8188167994467224, -0.24548548714079912),
(-1.4881228359109546, 0.082579345472332394),
(-1.1574288723751871, 0.40169542465296937),
(-0.82673490883941936, 0.67728157162574099),
(-0.49604094530365161, 0.87947375120648907),
(-0.16534698176788387, 0.98636130340272232),
(0.16534698176788387, 0.98636130340272232),
(0.49604094530365161, 0.87947375120648907),
(0.82673490883941891, 0.67728157162574132),
(1.1574288723751867, 0.40169542465296976),
(1.4881228359109544, 0.082579345472332616),
(1.8188167994467221, -0.2454854871407989),
(2.1495107629824899, -0.5469481581224267),
(2.4802047265182576, -0.78914050939639346),
(2.8108986900540254, -0.94581724170063464),
(3.1415926535897931, -1.0)]
But,
In [11]: zip(angles, arccos(cos(angles)))
Out[11]:
[(-3.1415926535897931, 3.1415926535897931),
(-2.8108986900540254, 2.8108986900540254),
(-2.4802047265182576, 2.4802047265182576),
(-2.1495107629824899, 2.1495107629824899),
(-1.8188167994467224, 1.8188167994467224),
(-1.4881228359109546, 1.4881228359109546),
(-1.1574288723751871, 1.1574288723751871),
(-0.82673490883941936, 0.82673490883941936),
(-0.49604094530365161, 0.49604094530365156),
(-0.16534698176788387, 0.16534698176788418),
(0.16534698176788387, 0.16534698176788418),
(0.49604094530365161, 0.49604094530365156),
(0.82673490883941891, 0.82673490883941891),
(1.1574288723751867, 1.1574288723751867),
(1.4881228359109544, 1.4881228359109544),
(1.8188167994467221, 1.8188167994467221),
(2.1495107629824899, 2.1495107629824899),
(2.4802047265182576, 2.4802047265182576),
(2.8108986900540254, 2.8108986900540254),
(3.1415926535897931, 3.1415926535897931)]
Which means that getting your angles from your direction cosines, you will need to do:
In [13]: def toAng(a): return sign(a)*arccos(a)
which will give you your correct angles:
In [19]: zip(angles, toAng(cos(angles)))
Out[19]:
[(-3.1415926535897931, -3.1415926535897931),
(-2.8108986900540254, -2.8108986900540254),
(-2.4802047265182576, -2.4802047265182576),
(-2.1495107629824899, -2.1495107629824899),
(-1.8188167994467224, -1.8188167994467224),
(-1.4881228359109546, 1.4881228359109546),
(-1.1574288723751871, 1.1574288723751871),
(-0.82673490883941936, 0.82673490883941936),
(-0.49604094530365161, 0.49604094530365156),
(-0.16534698176788387, 0.16534698176788418),
(0.16534698176788387, 0.16534698176788418),
(0.49604094530365161, 0.49604094530365156),
(0.82673490883941891, 0.82673490883941891),
(1.1574288723751867, 1.1574288723751867),
(1.4881228359109544, 1.4881228359109544),
(1.8188167994467221, -1.8188167994467221),
(2.1495107629824899, -2.1495107629824899),
(2.4802047265182576, -2.4802047265182576),
(2.8108986900540254, -2.8108986900540254),
(3.1415926535897931, -3.1415926535897931)]
Finally, if you need to convert it to degrees, you can just do:
In [20]: def toAng(a): return 180*sign(a)*arccos(a)/pi
In [21]: zip(angles, toAng(cos(angles)))
Out[21]:
[(-3.1415926535897931, -180.0),
(-2.8108986900540254, -161.05263157894737),
(-2.4802047265182576, -142.10526315789474),
(-2.1495107629824899, -123.1578947368421),
(-1.8188167994467224, -104.21052631578948),
(-1.4881228359109546, 85.263157894736835),
(-1.1574288723751871, 66.31578947368422),
(-0.82673490883941936, 47.368421052631582),
(-0.49604094530365161, 28.421052631578949),
(-0.16534698176788387, 9.4736842105263346),
(0.16534698176788387, 9.4736842105263346),
(0.49604094530365161, 28.421052631578949),
(0.82673490883941891, 47.368421052631554),
(1.1574288723751867, 66.315789473684191),
(1.4881228359109544, 85.263157894736835),
(1.8188167994467221, -104.21052631578947),
(2.1495107629824899, -123.1578947368421),
(2.4802047265182576, -142.10526315789474),
(2.8108986900540254, -161.05263157894737),
(3.1415926535897931, -180.0)]
Which gives you the right angles in degrees ...
Note I am using an environment where sign, pi etc are numpy objects. In your program, you might have ti import them separately.
degree to radian conversions are done with the equation (n deg)*(pi/180 deg).
z = (c[1]*(math.pi/180.0) + (c[1]*(math.pi/180)
if it's something you need to do regularly make a function.
def DegtoRad(deg):
return (deg)*(math.pi/180)
or as a lambda
DegtoRad = lambda x: x*(math.pi/180)
remember though if you havent imported math/math.pi none of this will work.
probably better to define pi with an actual literal variable up to your needs of precision.
This was not so very hard to find online? - was it?
http://www.mathwarehouse.com/trigonometry/radians/convert-degee-to-radians.php
The formula is the opposite of #user2913685 's formula: num*180/pi
(an easy mistake)
here is an example in python:
pi = 3.14159265
rad_val = 7
deg_val = rad_val*180/pi
print(deg_val)
which gives the output:
401.07045704986604
This uses pi as 3.14159265, and doesn't use the module math. Obviously you can do the same as in the other answer, but after changing the formula.
Related
I am working on the task in which I have to make a circle which is having n number of equal parts. I am provided with centre and radius of the circle which is (0,0) and 4 respectively. To achieve this task, I have written below code,
parts = 36 # desire number of parts of the circle
theta_zero = 360/parts
R = 4 # Radius
x_p = []
y_p = []
n = 0
for n in range(0,36):
x_p.append(R * math.cos(n*theta_zero))
y_p.append(R * math.sin(n*theta_zero))
However, after running this code, I got output like below which does not seem a coorect which I am suppose to have.
Kindly let me know what I am doing wrong and give some suggestion of correct code. Thank you
Aside from the fact that you are generating numbers in degrees and passing them to a function that expects radians, there's a much simpler and less error-prone method for generating evenly-spaced coordinates:
t0 = np.linspace(0, 2 * np.pi, parts, endpoint=False)
x0 = R * np.cos(t0)
y0 = R * np.sin(t0)
endpoint=False ensures that you end up with 36 partitions rather than 35, since otherwise 0 and 2 * np.pi would overlap.
If you wanted to connect the dots for your circle, you would want the overlap. In that case, you would do
t1 = np.linspace(0, 2 * np.pi, parts + 1)
x1 = R * np.cos(t1)
y1 = R * np.sin(t1)
Here is how you would plot a circle with the 36 sectors delineated:
plt.plot(x1, y1)
plt.plot(np.stack((np.zeros(parts), x0), 0),
np.stack((np.zeros(parts), y0), 0))
Finally, if you want your circle to look like a circle, you may want to run plt.axis('equal') after plotting.
Your circle is weird because math.cos and math.sin accept radians while you are passing degrees. You just need to convert the degrees to radians when calling the math functions.
Like this:
parts = 36
theta_zero = 360/parts
R = 4
x_p = []
y_p = []
for n in range(0,36):
x_p.append(R * math.cos(n*theta_zero /180*math.pi))
y_p.append(R * math.sin(n*theta_zero /180*math.pi))
Result:
Alternatively changing theta_zero to 2*math.pi/parts would also work and would be slightly faster but it might be a little less intuitive to work with.
Also as #Mad Physicist mentioned you should probably add plt.axis('equal') to unstretch the image.
I want to be able to calculate the exact length of an SVG Arc. I can do all the manipulations rather easily. But, I am unsure of whether there is a solution at all or the exact implementation of the solution.
Here's the exact solution for the circumference of the ellipse. Using popular libraries is fine. I fully grasp that there are no easy solution as they will all require hypergeometric functions to be exact.
from scipy import pi, sqrt
from scipy.special import hyp2f1
def exact(a, b):
t = ((a - b) / (a + b)) ** 2
return pi * (a + b) * hyp2f1(-0.5, -0.5, 1, t)
a = 2.667950e9
b = 6.782819e8
print(exact(a, b))
My idea is to have this as opt-in code if you happen to have scipy installed it'll use the exact super-fancy solution, else it'll fall back to the weaker approximation code (progressively smaller line segments until error is small). The problem is the math level here is above me. And I don't know if there's some ways to specify a start and stop point for that.
Most of the approximation solutions are for ellipses, but I only want the arc. There may also be a solution unknown to me, for calculating the length of an arc on an ellipse but since the start and end position can be anywhere. It doesn't seem to be instantly viable to say a sweep angle is 15% of the total possible angle therefore it's 15% of the ellipse circumference.
A more effective less fancy arc approximation might also be nice. There are progressively better ellipse approximations but I can't go from ellipse circumference to arc length, so those are currently not helpful.
Let's say the arc parameterization is the start and end points on the ellipse. Since that's how SVG is parameterized. But, anything that isn't tautological like arc_length parameterization is a correct answer.
If you want to calculate this with your bare hands and the std lib, you can base your calculation on the following formula. This is only valid for two points on the upper half of the ellipse because of the acos but we're going to use it with the angles directly.
The calculation consists in these steps:
Start with the SVG data: start point, a ,b rotation, long arc, sweep, end point
Rotate the coordinate system to match the horizontal axis of the ellipse.
Solve a system of 4 equations with 4 unknowns to get the centre point and the angles corresponding to the start and end point
Approximate the integral by a discreet sum over small segments. This is where you could use scipy.special.ellipeinc, as suggested in the comments.
Step 2 is easy, just use a rotation matrix (note the angle rot is positive in the clockwise direction):
m = [
[math.cos(rot), math.sin(rot)],
[-math.sin(rot), math.cos(rot)]
]
Step 3 is very well explained in this answer. Note the value obtained for a1 is modulo pi because it is obtained with atan. That means that you need to calculate the centre points for the two angles t1 and t2 and check they match. If they don't, add pi to a1 and check again.
Step 4 is quite straightforward. Divide the interval [t1, t2] into n segments, get the value of the function at the end of each segment, time it by the segment length and sum all this up. You can try refining this by taking the value of the function at the mid-point of each segment, but I'm not sure there is much benefit to that. The number of segments is likely to have more effect on the precision.
Here is a very rough Python version of the above (please bear with the ugly coding style, I was doing this on my mobile whilst traveling 🤓)
import math
PREC = 1E-6
# matrix vector multiplication
def transform(m, p):
return ((sum(x * y for x, y in zip(m_r, p))) for m_r in m)
# the partial integral function
def ellipse_part_integral(t1, t2, a, b, n=100):
# function to integrate
def f(t):
return math.sqrt(1 - (1 - a**2 / b**2) * math.sin(t)**2)
start = min(t1, t2)
seg_len = abs(t1 - t2) / n
return - b * sum(f(start + seg_len * (i + 1)) * seg_len for i in range(n))
def ellipse_arc_length(x1, y1, a, b, rot, large_arc, sweep, x2, y2):
if abs(x1 - x2) < PREC and abs(y1 - y2) < PREC:
return 0
# get rot in radians
rot = math.pi / 180 * rot
# get the coordinates in the rotated coordinate system
m = [
[math.cos(rot), math.sin(rot)],
[- math.sin(rot), math.cos(rot)]
]
x1_loc, y1_loc, x2_loc, y2_loc = *transform(m, (x1,y1)), *transform(m, (x2,y2))
r1 = (x1_loc - x2_loc) / (2 * a)
r2 = (y2_loc - y1_loc) / (2 * b)
# avoid division by 0 if both points have same y coord
if abs(r2) > PREC:
a1 = math.atan(r1 / r2)
else:
a1 = r1 / abs(r1) * math.pi / 2
if abs(math.cos(a1)) > PREC:
a2 = math.asin(r2 / math.cos(a1))
else:
a2 = math.asin(r1 / math.sin(a1))
# calculate the angle of start and end point
t1 = a1 + a2
t2 = a1 - a2
# calculate centre point coords
x0 = x1_loc - a * math.cos(t1)
y0 = y1_loc - b * math.sin(t1)
x0s = x2_loc - a * math.cos(t2)
y0s = y2_loc - b * math.sin(t2)
# a1 value is mod pi so the centres may not match
# if they don't, check a1 + pi
if abs(x0 - x0s) > PREC or abs(y0 - y0s) > PREC:
a1 = a1 + math.pi
t1 = a1 + a2
t2 = a1 - a2
x0 = x1_loc - a * math.cos(t1)
y0 = y1_loc - b * math.sin(t1)
x0s = x2_loc - a * math.cos(t2)
y0s = y2_loc - b * math.sin(t2)
# get the angles in the range [0, 2 * pi]
if t1 < 0:
t1 += 2 * math.pi
if t2 < 0:
t2 += 2 * math.pi
# increase minimum by 2 * pi for a large arc
if large_arc:
if t1 < t2:
t1 += 2 * math.pi
else:
t2 += 2 * math.pi
return ellipse_part_integral(t1, t2, a, b)
print(ellipse_arc_length(0, 0, 40, 40, 0, False, True, 80, 0))
The good news is that the sweep flag doesn't matter as long as you're just looking for the length of the arc.
I'm not 100% sure the modulo pi problem is handled correctly and the implementation above may have a few bugs.
Nevertheless, it gave me a good approximation of the length in the simple case of a half circle, so I dare calling it WIP. Let me know if this is worth pursuing, I can have a further look when I'll be seated at a computer. Or maybe someone can come up with a clean way of doing this in the meantime?
i plot an angle in python
here is the code
x = [0,0.5,1]
y = [0,0.5,0]
plt.scatter(x,y)
plt.plot(x,y)
plt.show()
is there a way to examine if the angle is a right angle programmatically?
The easiest way is to test if the dot product of the vectors is 0.
In your case, you simply compute:
v1 = ( (x[1]-x[0]), (y[1]-y[0]) ) <- (0.5, 0.5)
v2 = ( (x[2]-x[1]), (y[2]-y[1]) ) <- (0.5, -0.5)
dot_product = v1[0]*v2[0] + v1[1]*v2[1] <- 0.5² - 0.5² = 0
The other answers do not really care about possible inaccuracies and truncation errors, nor efficiency.
Rather than an exact comparison to 90° (or 0° in case of dot product), it is wiser to check for a small angle difference to 90° (resp. 0°).
Also wise to avoid divisions, square roots and trigonometric functions. The cross-product method is among the most attractive.
Compute the cross-product of the sides of the angle and their squared lengths, and compare
with a precomputed tolerance:
(ABx . BCy - ABy . BCx)² ≥ α.(ABx² + ABy²).(BCx² + BCy²)
with α = cos²δ where δ is the angle tolerance.
You can try to calculate the angle, but an easier way could be to check whether the Pythagorean Theorem applies. For that you'll need to calculate the size of the three edges and then check whether A^2 + B^2 ~= C^2
Yes, there is.
x = [0,0.5,1]
y = [0,0.5,0]
points = [np.array(point) for point in zip(x,y)]
a, b, c = points
ba = a - b
bc = c - b
cosine_angle = np.dot(ba, bc) / (np.linalg.norm(ba) * np.linalg.norm(bc))
angle_rad = np.arccos(cosine_angle)
angle_deg = np.rad2deg(angle_rad)
print(angle_deg) # 90.0
You can compute the angle between the two vectors as following: first, get the two vectors v1 and v2 and then use np.arccos() which returns the angle in radians. Convert it to degrees to check if it is 90 degrees. The formulae for computing angle between two vectors can be found on this Wiki link
import numpy as np
x = np.array([0,0.5,1])
y = np.array([0,0.5,0])
vecs = np.vstack((x, y))
v1 = vecs[:, 1] - vecs[:, 0]
v2 = vecs[:, 2] - vecs[:, 1]
angle_rad = np.arccos(np.dot(v1, v2) / (np.linalg.norm(v1) * np.linalg.norm(v2)))
angle_deg = np.rad2deg(angle_rad)
# 90.0
I have an algorithm in which I need to work out the signed angle (-180 to 180) between edges in a graph. I've done some research and found plenty of specific answers but can't figure out how to relate them to my situation (e.g. this question which uses atan2, however the OP wanted only positive angles)
I've tried implementing a few different ways (using atan2 or arccos) but I'm struggling to relate the examples to my specific problem. I've tried treating the edges as vectors but got strange results.
Given a graph with points (A, B, C, D, E), and the average of those points (avg)... how do I find the signed angle between one of those points (e.g. A) and the other points (e.g. B, C, D, E), taking the angle from the current origin (A) to the 'avg' point as equal to 0 degrees. Example below...
...in this example, the anti-clockwise angle from (A, avg) to (A, B) would be positive something (between 0 and 180), and the angle from (A, avg) to (A, E) would be negative something (between 0 and -180).
Ideally I want a formula which I could also apply to defining any of the points as the origin, for example taking point C as the origin.. the 'zero angle' would be (C, avg) and the angle between (C, avg) and (C, A) would be negative (0 to -180) and the angle between (C, avg) and (C, E) would be positive (0 to 180).
I haven't studied math beyond high-school so I find it hard to decipher equations with symbols I don't understand.
UPDATE: Thought I'd clean this up to make it more obvious what the conclusion was.
I made two small changes to the accepted answer, resulting in the below snippet:
def angle(vertex, start, dest):
AhAB = math.atan2((dest.y - vertex.y), (dest.x - vertex.x))
AhAO = math.atan2((start.y - vertex.y), (start.x - vertex.x))
AB = AhAB - AhAO
# in between 0-math.pi = do nothing, more than math.pi = +(-2 * math.pi), less than zero = do nothing
AB = math.degrees(AB + (-2 * math.pi if AB > math.pi else (2 * math.pi if AB < 0 - math.pi else 0)))
return AB
...the final one-liner may be a bit much to grok after a few months of not working on this, so I turned it into it's own function, taking the result of AB = AhAB - AhAO as it's argument...
def calc(ab):
if ab > math.pi:
return ab + (-2 * math.pi)
else:
if ab < 0 - math.pi:
return ab + (2 * math.pi)
else:
return ab + 0
I thought this was a little clearer to read, though more lines.
The final function in full:
def angle(vertex, start, dest):
"""Calculates the signed angle between two edges with the same origin.
Origin is the 'vertex' argument, 'start' is the bounding point of the edge to calculate the angle from.
Positively signed result means anti-clockwise rotation about the vertex."""
def calc_radians(ab):
if ab > math.pi:
return ab + (-2 * math.pi)
else:
if ab < 0 - math.pi:
return ab + (2 * math.pi)
else:
return ab + 0
AhAB = math.atan2((dest.y - vertex.y), (dest.x - vertex.x))
AhAO = math.atan2((start.y - vertex.y), (start.x - vertex.x))
res = calc_radians(AhAB - AhAO)
return math.degrees(res)
Note: The function assumes the three arguments will all be instances of a typical Point class with x and y attributes.
Also, the example graph above has only positive values, but I am fairly sure that this works with graphs that involve negative values too.
I read your problem statement as follows: given 2 points A and B, and a center O, find the angle A to B as the angle, positive if anticlockwise, between the vectors A→O and A→B.
If my premises are correct, then you can
find the angle between A→B and a horizontal, rightward line passing in A,
find the angle between A→O and a horizontal, rightward line passing in A,
find the angle A to B as the difference of said angles,
normalize the result range so that it's between -Ï€ and +Ï€.
What I've said can be visualized as follows
or in code (assuming a Point class with attributes x and y)
AhAB = math.atan2((B.y-A.y), (B.x-A.x)) # -π < AhAB ≤ +π
AhAO = math.atan2((O.y-A.y), (O.x-A.x)) # -π < AhA) ≤ +π
AB = AhAB - AhAO # -2π < AB ≤ +2π
AB = AB + ( 2*math.pi if AB < math.pi else (-2*math.pi if AB> math.pi else 0))
Addendum
Here it is a small code example, the position of the points is just similar to what you can see in the picture
In [18]: from math import atan2, pi
In [21]: class Point():
...: def __init__(self, x, y):
...: self.x, self.y = x, y
...: def __repr__(self):
...: return '(%s, %s)'%(self.x, self.y)
In [22]: A = Point(0.0, 0.0)
In [23]: B = Point(-2.0, 2.0)
In [24]: O = Point(0.0, -3.0)
In [25]: AhAB = atan2((B.y-A.y), (B.x-A.x)) ; print(3/4, AhAB/pi)
0.75 0.75
In [26]: AhAO = atan2((O.y-A.y), (O.x-A.x)) ; print(-1/2, AhAO/pi)
-0.5 -0.5
In [27]: AB = AhAB - AhAO ; print(5/4, AB/pi)
1.25 1.25
In [28]: AB = AB + ( 2*pi if AB < pi else (-2*pi if AB> pi else 0)) ; print(AB/pi)
-0.75
In [29]:
The last line normalize your result AB to be in the correct range -π < AB ≤ π, adding or subtracting 2π that doesn't change the meaning of the measured angle.
The definition of positive and negative angles is heavily depending on the reference system or reference point. Despite of its 'correct' definition, the basic calculation can be pretty much done based on the slope between two points and the resulting angle of incline which can be calculated by applying the inverse tan to the slope.
Applying the inverse tan in programming can be a bit annoying since many programming languages provide two different functions for this:
arctan or atan which is implemented in Python's math.atan() or numpy.atan()
arctan2 or atan2 which is delivered by math.atan2() or numpy.atan2()
Both of these functions, regardless of the implementation in the math module or numpy package, return the calculated angle in radians which is basically based on the number Pi instead of degrees which makes some further conversion necessary. This can either be done manually or by applying a function like numpy.rad2deg(). To get a basic idea of the data points and to get some eye-balled estimation for the calculated results, I suggest plotting the data point by using matplotlib.
Glueing all the before-mentioned considerations into code can look like this:
import pandas as pd
import matplotlib
import numpy as np
%matplotlib inline
import matplotlib.pyplot as plt
# Define some sample data points
coords = {
'A': (1.5, 3.0),
'B': (3.0, 5.0),
'C': (5.5, 4.5),
'D': (5.8, 2.2),
'E': (2.8, 1.2)
}
# Extract data values from `coords` dict
values = np.array(list(coords.values()))
# Calculate the averaged point of all data points
avg = np.mean(values, axis=0)
# Plot sample data for better overview
for k, v in coords.items():
plt.plot(*v, marker='o', linestyle='')
plt.text(*v, k)
plt.plot(*avg, marker='o', linestyle='')
plt.text(*avg, 'avg')
plt.show()
# For further information about slope and angle of incline
# see Wikipedia (https://en.wikipedia.org/wiki/Slope).
# Calculating the angle from `avg` to each point. Please adopt
# to your own needs if needed for other pairs of points.
# Calculate the distance in x- and y-direction from each point to point `avg`
distances_x_y = (values - avg)
# Depending on your definition of the 'reference point' consider using
# distances_x_y = (avg - values)
# For further explanation on `atan` and `atan2` see
# https://stackoverflow.com/q/35749246/3991125 and
# https://en.wikipedia.org/wiki/Atan2 .
# Using a for loop instead of numpy's array/vectors is not very elegant,
# but easy to understand and therefore has potential for improvements.
# Calculate angle from point `avg` to each other point based on distances
angle_radians = np.array([np.arctan2(element[1], element[0]) for element in distances_x_y])
# since `.arctan2()` or `.arctan()` return the angle in radians,
# we need to convert to degrees
angle_degrees = np.rad2deg(angle_radians)
# print results
print(angle_degrees)
If you consider the coordinates x0=xavg-xA, y0=yavg-yA and x=xPoint-xA,y=yPoint-yA, the formula f(x,y) gives the signed angle that is positive as counter clockwise.
f(x,y)=pi()/2*((1+sign(x0))* (1-sign(y0^2))-(1+sign(x))* (1-sign(y^2)))
+pi()/4*((2+sign(x0))*sign(y0)-(2+sign(x))*sign(y))
+sign(x0*y0)*atan((abs(x0)-abs(y0))/(abs(x0)+abs(y0)))
-sign(x*y)*atan((abs(x)-abs(y))/(abs(x)+abs(y)))
I'm trying to print out the x,y value for a line with a certain degree which intersects a circle with a specified radius.
Lets say for example that the line is pointing straight up at 90 degrees.
import math
degree = 90
radius = 10
x = radius * math.cos(degree)
y = radius * math.sin(degree)
print(x,y)
This prints out -4.480736161291701 8.939966636005579 but according to my calculator is supposed to print 0 10 on deg.
I have already tried adding math.radians and math.degrees before the degree var in the x = and y =, but it doesn't come out correctly any time I've tried. The link I found to the point where a line with degree intersects a circle is here, the sin/cos values are flipped 'tho for the x and y value in the solution.
Simply said, how would I make the 90 be in degrees instead of radians to get the correct x,y?
EDIT:
by adding math.radians:
x = radius * math.cos(math.radians(degree))
y = radius * math.sin(math.radians(degree))
it returned 6.123233995736766e-16 10.0
~~~
by adding math.degrees:
x = radius * math.cos(math.degrees(degree))
y = radius * math.sin(math.degrees(degree))
it returned -2.995153947555356 -9.540914674728182
In Python, you can use math.radians to convert from degrees to radians. Note that it is not just Python that defaults to radians, it is usually the standard in mathematics to talk about angles in radians.
Although, in general, you can always use the conversion formula
radians = pi * degrees / 180
You can use math.radians(degree) to convert to radians. All python's default trig functions work in radians. So your code becomes:
import math
degree = 90
radius = 10
x = radius * math.cos(math.radians(degree))
y = radius * math.sin(math.radians(degree))
print(x,y)
And this produces the correct result: 6.123233995736766e-16 10.0, with some odd floating point behavior you can fix with appropriate rounding.
All angles in most of the math libraries are in radians. The input to math.cos should be radians but you are passing in degrees.
import math
degree = 90
radius = 10
x = radius * math.cos(math.radians(degree))
y = radius * math.sin(math.radians(degree))
print x,y
>0, 10
math.radians is nothing more than doing (pi * degree / 180 )
If you're writing a somewhat longer code, you can make your code work in degrees by putting in the following lines in the beginning:
from math import sin, cos, tan, asin, acos, atan
def s(x):
return sin(rad(x))
def c(x):
return cos(rad(x))
def t(x):
return tan(rad(x))
def sa(x):
return deg(asin(x))
def ca(x):
return deg(acos(x))
def ta(x):
return deg(atan(x))
Then, throughout your code, instead of typing sin(90) you would type s(90), or for arcsin(90) you would type sa(90). (I couldn't make the code word as for arcsine, since as is already a Python word)
Now, you would just type up your code as though it were in degrees and everything should work out fine.