Issue with finding angle between 3 points in Python - python-3.x

I have 3 points p1(x1, y1), p2(x2, y2) and p3(x3, y3). I am trying to calculate angle (in anti-clockwise direction) between these 3 points. I am using following dot product method as provided in multiple blogs and SE sites (like this).
def angle_between(p1, p2, p3):
x1, y1 = p1
x2, y2 = p2
x3, y3 = p3
v21 = (x1 - x2, y1 - y2)
v23 = (x3 - x2, y3 - y2)
dot = v21[0] * v23[0] + v21[1] * v23[1]
det = v21[0] * v23[1] - v21[1] * v23[0]
theta = np.rad2deg(np.arctan2(det, dot))
print(theta)
It is giving me correct angle for any points which are not on the straight line. For example
p1 = (0, 0)
p2 = (1, 0)
p3 = (1, 1)
angle_between(p1, p2, p3) # Prints -90
angle_between(p3, p2, p1) # Prints +90
However, if points are on the straight line, it is giving me same answer
p1 = (0, 0)
p2 = (1, 0)
p3 = (2, 0)
angle_between(p1, p2, p3) # Prints +180
angle_between(p3, p2, p1) # Prints +180
Here I was expecting (p3, p2, p1) to give -180. What am I missing here? If the method I am using is not correct, can someone help me point towards the correct method?
I have tried to use direct cosine law (as given here) but it only provides me angle without any sense of direction of the angle.

Check out this solution. It always provides positive angles, measured in anti-clockwise direction:
from math import atan2, degrees
def angle_between(p1, p2, p3):
x1, y1 = p1
x2, y2 = p2
x3, y3 = p3
deg1 = (360 + degrees(atan2(x1 - x2, y1 - y2))) % 360
deg2 = (360 + degrees(atan2(x3 - x2, y3 - y2))) % 360
return deg2 - deg1 if deg1 <= deg2 else 360 - (deg1 - deg2)

Related

How do I calculate the fourth vertex of a tetrahedron given the other three?

I want to calculate the fourth vertex of a regular tetrahedron. I have the coordinates
{0, 0, Sqrt[2/3] - 1/(2 Sqrt[6])}, {-(1/(2 Sqrt[3])), -(1/2), -(1/(2
Sqrt[6]))} and {-(1/(2 Sqrt[3])), 1/2, -(1/(2 Sqrt[6]))}
Can anybody please help?
Find the center of face
cx = (x1 + x2 + x3)/3 and similar for y,z
Get two edge vectors
e2x = x2 - x1
e2y = y2 - y1
e2z = z2 - z1
e3x = x3 - x1
e3y = y3 - y1
e3z = z3 - z1
Calculate edge len
elen = sqrt(e2x*e2x+e2y*e2y+e2z*e2z)
Calculate vector product to get normal to this face
nx = e2y*e3z - e2z*e3y
ny = e2z*e3x - e2x*e3z
nz = e2x*e3y - e2y*e3x
Make unit normal
nlen = sqrt(nx*nx+ny*ny+nz*nz)
nx = nx / nlen
...
Make normal of needed length (tetrahedron height)
lnx = nx * sqrt(2/3) * elen
...
Add this normal to the face center
x4 = cx +/- lnx
y4 = cy +/- lny
z4 = cz +/- lnz
+/- signs correspond to two possible positions of the fourth vertex

How can I calculate the centre between two centre of rectangles in python 3?

I have two rectangles and I want to measure the distance between them. I have centre coordinates for both rectangle.
R1 = (908,1018) ## (x,y,width,height)=(595,11,627,2015)
R2 = (891,1019) ## (x,y,width,height)= (670,871,442,297)
I know, we can calculate it with help of Pythagoras Theory. But how can I do it with python in a simple way.
Like you said, Pythagoras works fine here. Try something like this
x1, y1 = R1
x2, y2 = R2
dx = x2 - x1
dy = y2 - y1
d = math.sqrt(dx * dx + dy * dy)
print(d)

How to find the third vertices of a triangle when lengths are unequal

I have two vertices of a triangle and the lengths are unequal. How to find the third vertex?
Translate all points so that P2 becomes the origin.
Then you solve
x² + y² = d2²
(x - x3)² + (y - y3)² = d3²
(mind the renumbering of d1).
By subtraction of the two equations,
(2x - x3).x3 + (2y - y3).y3 = d2² - d3²
which is a linear equation, of the form
a.x + b.y + c = 0
and in parametric form
x = x0 + b.t
y = y0 - a.t
where (x0, y0) is an arbitrary solution, for instance (- ac / (a² + b²), - bc / (a² + b²)).
Now solve the quadratic equation in t
(x0 + b.t)² + (y0 - a.t)² = d2²
which gives two solutions, and undo the initial translation.
function [vertex_1a, vertex_1b] = third_vertex(x2, y2, x3, y3, d1, d3)
d2 = sqrt((x3 - x2)^2 + (y3 - y2)^2); % distance between vertex 2 and 3
% Orthogonal projection of side 12 onto side 23, calculated unsing
% the Law of cosines:
k = (d2^2 + d1^2 - d3^2) / (2*d2);
% height from vertex 1 to side 23 calculated by Pythagoras' theorem:
h = sqrt(d1^2 - k^2);
% calculating the output: the coordinates of vertex 1, there are two solutions:
vertex_1a(1) = x2 + (k/d2)*(x3 - x2) - (h/d2)*(y3 - y2);
vertex_1a(2) = y2 + (k/d2)*(y3 - y2) + (h/d2)*(x3 - x2);
vertex_1b(1) = x2 + (k/d2)*(x3 - x2) + (h/d2)*(y3 - y2);
vertex_1b(2) = y2 + (k/d2)*(y3 - y2) - (h/d2)*(x3 - x2);
end

Unable to get the simplified coordinates using sympy - python

I have x2, x3, y2, y3, d1, d2, d3 values which is,
x2 = 0
x3 = 100
y2 = 0
y3 = 0
d1 = 100
d2 = 100
d3 = 87
When I use the below script,
from sympy import symbols, Eq, solve
x, y = symbols('x y')
eq1 = Eq((x - x2) ** 2 + (y - y2) ** 2 - d2 ** 2)
eq2 = Eq((x - x3) ** 2 + (y - y3) ** 2 - d3 ** 2)
sol_dict = solve((eq1, eq2), (x, y))
I got the ans as,
sol_dict = [(12431/200, -87*sqrt(32431)/200), (12431/200, 87*sqrt(32431)/200)]
How can I achieve the simplified solution like
sol_dict = [(62.155, -78.33), (62.155, 78.33)]
in python?
You can numerically evaluate the solution to get floats:
In [40]: [[x.evalf(3) for x in s] for s in sol_dict]
Out[40]: [[62.2, -78.3], [62.2, 78.3]]
I would only recommend doing that for display though. If you want to use the values in sol_dict for further calculations it's best to keep them as exact rational numbers.

Drawing regular Polygon

A regular polygon with N vertices. The lower side of the polygon is parallel to x axis. Given two point (x1, y1) and (x2, y2) if we draw a line through these points then the line would be parallel to the x axis. That means the lower side of the polygon is given. How to find the other n - 2 points. Each point could have floating value but it is grantee that x1, y1, x2, y2 is integer.
As example if N = 5 and (x1, y1) = (0, 0) and (x2, y2) = (5, 0)
I have to find these remaining 3 points (6.545085, 4.755283), (2.500000, 7.694209), (-1.545085 4.755283)
I am trying with vector rotation, but can't figure out any solution. How can I calculate ?
Given points x1, y1, x2, y2, number N.
Middle point of this edge is
xm = (x1 + x2) / 2
ym = y1
The center of polygon has coordinates
xc = xm
yc = y1 + Abs(x1 - x2)/2 * Ctg(Pi/N)
Radius of circumcircle is (Edit: 0.5 coefficient was missed)
R = 0.5 * Abs(x1 - x2) / Sin(Pi/N)
Kth (k=3..N) vertice of polygon has coordinates
xk = xc + R * Cos(-Pi/2 + Pi/N + (k - 2) * 2 * Pi/ N)
yk = yc + R * Sin(-Pi/2 + Pi/N + (k - 2) * 2 * Pi/ N)

Resources