Reputation: 1
I need to find the other two points of a rectangle given two points shown in black in the attached drawing. The missing points are showed in yellow width is in red which I do have as well. The rectangle can be arbitrarily rotated.
I also know if the points are on the same side or on opposite sides of the rectangle.
There are four possible arrangements each of which I need to solve for as shown.
Upvotes: 0
Views: 984
Reputation: 174
As you have added the python tag to your question, I assume you want to solve this problem using python.
Diagonal Approach Sketch (Right here, we use the the theorem of Thales. If you don't know it, just look it up. It's quite useful.)
This is pure calculation. Just change the properties at the very end of this script.
import math
import numpy as np
# lovely method by mujjiga
# from https://stackoverflow.com/questions/55816902/finding-the-intersection-of-two-circles
# returns intersections of two circles
def get_intersections(x0, y0, r0, x1, y1, r1):
# circle 1: (x0, y0), radius r0
# circle 2: (x1, y1), radius r1
d = math.sqrt((x1-x0)**2 + (y1-y0)**2)
# non intersecting
if d > r0 + r1:
return None
# One circle within other
if d < abs(r0-r1):
return None
# coincident circles
if d == 0 and r0 == r1:
return None
else:
a = (r0**2-r1**2+d**2)/(2*d)
h = math.sqrt(r0**2-a**2)
x2 = x0+a*(x1-x0)/d
y2 = y0+a*(y1-y0)/d
x3 = x2+h*(y1-y0)/d
y3 = y2-h*(x1-x0)/d
x4 = x2-h*(y1-y0)/d
y4 = y2+h*(x1-x0)/d
return (x3, y3, x4, y4)
# returns None or 4 possible points
def get_unknown_points(p1, p2, width, is_diagonal):
# convert tuples/lists to nummpy arrays
p1 = np.array(p1, dtype=float)
p2 = np.array(p2, dtype=float)
# vector from p1 to p2
p1_to_p2 = p2 - p1
# magnitude/length of this vector
length = np.linalg.norm(p2 - p1)
if is_diagonal:
mid = p1 + 0.5 * p1_to_p2
mid_radius = length * 0.5
points = get_intersections(
p1[0], p1[1], width, mid[0], mid[1], mid_radius)
# no intersections found
if points is None:
return None
other_points = get_intersections(
p2[0], p2[1], width, mid[0], mid[1], mid_radius)
# return the two different possibilities
possibilities = []
possibilities.append(
((points[0], points[1]), (other_points[0], other_points[1])))
possibilities.append(
((points[2], points[3]), (other_points[2], other_points[3])))
return possibilities
# p1 and p2 do not represent the diagonal
else:
# get a perpendicular vector regarding p1_to_p2 (taken from https://stackoverflow.com/questions/33658620/generating-two-orthogonal-vectors-that-are-orthogonal-to-a-particular-direction)
perpendicular_vector = np.random.randn(2)
perpendicular_vector -= perpendicular_vector.dot(
p1_to_p2) * p1_to_p2 / np.linalg.norm(p1_to_p2)**2
# make length of vector correspond to width
perpendicular_vector /= np.linalg.norm(perpendicular_vector)
perpendicular_vector *= width
# add this vector to p1 and p2 and return both possibilities
possibilities = []
possibilities.append(
((p1[0] + perpendicular_vector[0], p1[1] + perpendicular_vector[1]), (p2[0] + perpendicular_vector[0], p2[1] + perpendicular_vector[1])))
possibilities.append(
((p1[0] - perpendicular_vector[0], p1[1] - perpendicular_vector[1]), (p2[0] - perpendicular_vector[0], p2[1] - perpendicular_vector[1])))
return possibilities
# change these properties
p1 = (4, 5)
p2 = (5, 1)
diagonal = True
width = 1
points = get_unknown_points(p1, p2, width, diagonal)
# output
if points is None:
print("There are no points that can be calculated from the points given!")
else:
print(
f"Possibilty 1: \n\tPoint1: {points[0][0]} \n\tPoint2: {points[0][1]}")
print(
f"Possibilty 2: \n\tPoint1: {points[1][0]} \n\tPoint2: {points[1][1]}")
If you want to see the results visually, just append these lines of code to the end of the upper script.
import matplotlib.pyplot as plt
# displaying results
if points is not None:
p1 = np.array(p1, dtype=float)
p2 = np.array(p2, dtype=float)
fig, ax = plt.subplots()
ax.set_xlim((-1, 10))
ax.set_ylim((-1, 10))
if diagonal:
dist = np.linalg.norm(p2 - p1)
mid = p1 + 0.5 * (p2 - p1)
mid_radius = dist * 0.5
circle2 = plt.Circle(mid, mid_radius, color='orange', fill=False)
circle3 = plt.Circle(p1, width, color='g', fill=False)
circle1 = plt.Circle(p2, width, color='g', fill=False)
ax.add_artist(circle1)
ax.add_artist(circle2)
ax.add_artist(circle3)
plt.plot(p1, p2, '.', color='black')
print(points[0][1])
plt.plot([points[0][0][0], points[0][1][0]], [
points[0][0][1], points[0][1][1]], '.', color='red')
plt.plot([points[1][0][0], points[1][1][0]], [
points[1][0][1], points[1][1][1]], '.', color='blue')
plt.gca().set_aspect('equal', adjustable='box')
plt.show()
Upvotes: 1
Reputation: 163
In the rectangle, where the rectangle perfectly cuts into two equal triangle.
By applying Pythagoras theorem {hypotenuse^2=base^2+perpendicular^2}.
`base = width of rectangle
perpendicular = length of rectangle
hypotenuse = unknown/desired`
For length of rectangle: Length of a rectangle = Area ÷ breadth.
If this is not requested please tell.
Upvotes: 1