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

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)

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

Issue with finding angle between 3 points in Python

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)

(Tkinter, py3) How to make a rotation animation?

I want to rotate an oval around it's center. Currently I can display the static object witohut rotation, and I can't seem to find what to do wit it.
EDIT: I made a rotation function based on complex number multiplication, which seemed to work on lower polygons but the ellipse kinda looks the same.
A potato-level noob C.S. student.
also, the code:
from tkinter import*
import cmath, math
import time
def poly_rot(tup, deg):
rad=deg*0.0174533
crot=cmath.exp(rad*1j)
rotpol=[]
i=0
while i < len(tup):
x=tup[i]
y=tup[i+1]
z=crot*complex(x,y)
rotpol.append(400+z.real)
rotpol.append(400+z.imag)
i=i+2
return rotpol
def poly_oval(x0,y0, x1,y1, steps=60, rotation=0):
"""return an oval as coordinates suitable for create_polygon"""
# x0,y0,x1,y1 are as create_oval
# rotation is in degrees anti-clockwise, convert to radians
rotation = rotation * math.pi / 180.0
# major and minor axes
a = (x1 - x0) / 2.0
b = (y1 - y0) / 2.0
# center
xc = x0 + a
yc = y0 + b
point_list = []
# create the oval as a list of points
for i in range(steps):
# Calculate the angle for this step
# 360 degrees == 2 pi radians
theta = (math.pi * 2) * (float(i) / steps)
x1 = a * math.cos(theta)
y1 = b * math.sin(theta)
# rotate x, y
x = (x1 * math.cos(rotation)) + (y1 * math.sin(rotation))
y = (y1 * math.cos(rotation)) - (x1 * math.sin(rotation))
point_list.append(round(x + xc))
point_list.append(round(y + yc))
return point_list
inp= input("We need an ellipse. One to fit in a 800*800 window. Give the size of it's axes separated by ','-s (ex: lx,ly)!\n")
inpu= inp.split(',')
lx=int(inpu[0])
ly=int(inpu[1])
x0=400-lx//2
x1=400+lx//2
y0=400-ly//2
y1=400+ly//2
deg= float(input("Let's rotate this ellipse! But how much, in degrees, should we?"))
pre=poly_oval(x0, y0, x1, y1)
post=poly_rot(poly_oval(x0, y0, x1, y1), deg)
root =Tk()
w = Canvas(root, width=801, height=801)
w.config(background="dark green")
w.pack()
w.create_polygon(tuple(post), fill="yellow", outline="yellow" )
root.mainloop()

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)

Line Segment Circle Intersection

I am trying to determine the point at which a line segment intersect a circle. For example, given any point between P0 and P3 (And also assuming that you know the radius), what is the easiest method to determine P3?
Generally,
find the angle between P0 and P1
draw a line at that angle from P0 at a distance r, which will give you P3
In pseudocode,
theta = atan2(P1.y-P0.y, P1.x-P0.x)
P3.x = P0.x + r * cos(theta)
P3.y = P0.y + r * sin(theta)
From the center of the circle and the radius you can write the equation describing the circle.
From the two points P0 and P1 you can write the equation describing the line.
So you have 2 equations in 2 unknowns, which you can solved through substitution.
Let (x0,y0) = coordinates of the point P0
And (x1,y1) = coordinates of the point P1
And r = the radius of the circle.
The equation for the circle is:
(x-x0)^2 + (y-y0)^2 = r^2
The equation for the line is:
(y-y0) = M(x-x0) // where M = (y1-y0)/(x1-x0)
Plugging the 2nd equation into the first gives:
(x-x0)^2*(1 + M^2) = r^2
x - x0 = r/sqrt(1+M^2)
Similarly you can find that
y - y0 = r/sqrt(1+1/M^2)
The point (x,y) is the intersection point between the line and the circle, (x,y) is your answer.
P3 = (x0 + r/sqrt(1+M^2), y0 + r/sqrt(1+1/M^2))
Go for this code..its save the time
private boolean circleLineIntersect(float x1, float y1, float x2, float y2, float cx, float cy, float cr ) {
float dx = x2 - x1;
float dy = y2 - y1;
float a = dx * dx + dy * dy;
float b = 2 * (dx * (x1 - cx) + dy * (y1 - cy));
float c = cx * cx + cy * cy;
c += x1 * x1 + y1 * y1;
c -= 2 * (cx * x1 + cy * y1);
c -= cr * cr;
float bb4ac = b * b - 4 * a * c;
// return false No collision
// return true Collision
return bb4ac >= 0;
}
You have a system of equations. The circle is defined by: x^2 + y^2 = r^2. The line is defined by y = y0 + [(y1 - y0) / (x1 - x0)]·(x - x0). Substitute the second into the first, you get x^2 + (y0 + [(y1 - y0) / (x1 - x0)]·(x - x0))^2 = r^2. Solve this and you'll get 0-2 values for x. Plug them back into either equation to get your values for y.
MATLAB CODE
function [ flag] = circleLineSegmentIntersection2(Ax, Ay, Bx, By, Cx, Cy, R)
% A and B are two end points of a line segment and C is the center of
the circle, % R is the radius of the circle. THis function compute
the closest point fron C to the segment % If the distance to the
closest point > R return 0 else 1
Dx = Bx-Ax;
Dy = By-Ay;
LAB = (Dx^2 + Dy^2);
t = ((Cx - Ax) * Dx + (Cy - Ay) * Dy) / LAB;
if t > 1
t=1;
elseif t<0
t=0;
end;
nearestX = Ax + t * Dx;
nearestY = Ay + t * Dy;
dist = sqrt( (nearestX-Cx)^2 + (nearestY-Cy)^2 );
if (dist > R )
flag=0;
else
flag=1;
end
end

Resources