Search code examples
pythonmathcoordinates

Can three given coordinates be points of a rectangle


I am currently learning how to code in Python and I came across this task and I am trying to solve it. But I think I got a mistake somewhere and I was wondering can maybe someone help me with it. The task is to write a code that will: Import four 2D coordinates (A, B, C and X) from a text file Check can A, B, C be points of a rectangle Check if X is inside the ABC rectangle Calculate the diagonal of the rectangle.

So far I have this:

import math

def distance(point1, point2):
    return math.sqrt((point2[0] - point1[0])**2 + (point2[1] - point1[1])**2)

def is_rectangle(point1, point2, point3):
    distances = [
        distance(point1, point2),
        distance(point2, point3),
        distance(point3, point1)
    ]

    distances.sort()

    if distances[0] == distances[1] and distances[1] != distances[2]:
        return True
    else:
        return False
def is_inside_rectangle(rectangle, point):
    x_values = [vertex[0] for vertex in rectangle]
    y_values = [vertex[1] for vertex in rectangle]

    if (min(x_values) < point[0] < max(x_values)) and (min(y_values) < point[1] < max(y_values)):
        return True
    else:
        return False

with open('coordinates.txt', 'r') as file:
    coordinates = []
    for line in file:
        x, y = map(int, line.strip()[1:-1].split(','))
        coordinates.append((x, y))

rectangle = [coordinates[0], coordinates[1], coordinates[2]]
diagonal1 = distance(coordinates[0], coordinates[2])
diagonal2 = distance(coordinates[1], coordinates[3])
if is_rectangle(coordinates[0], coordinates[1], coordinates[2]) and is_inside_rectangle(rectangle, coordinates[3]):
    print("True")
    print(f"Diagonal of the rectangle is: {max(diagonal1, diagonal2)}")

else:
    print("False")

The code works but I think it calculates the diagonal wrong. For example lets take this points for input: A(0, 0), B(5,0), C(0, 5) and X(2, 2). It says they can be points of a rectangle and that the diagonal is 5. When I put this points on paper, the fourth point can be D(5, 5) and then the diagonal is 7.07 (square root of 50). Or it can be D(-5, 5) but then it is a parallelogram and one diagonal is 5 but it is not the max one. Also I am trying to write a function that will check if all data in the text file are integers. Let's say B is (m, k), then it should return false and if all data are integers, then continue with the code. Any ideas on that one?


Solution

  • Let's look at the logic for your is_rectangle function.

    def is_rectangle(point1, point2, point3):
        distances = [
            distance(point1, point2),
            distance(point2, point3),
            distance(point3, point1)
        ]
    
        distances.sort()
    
        if distances[0] == distances[1] and distances[1] != distances[2]:
            return True
        else:
            return False
    

    You are testing if the two smallest sides of triangle ABC are equal, and different from the largest side.

    Effectively answering the question: "Is ABC an obtuse isosceles triangle?"

    But the question you should be asking is: "Is ABC a right triangle?"

    There are several ways to test whether a triangle ABC is a right triangle.

    • One way is to check if one of the three pairs of vectors (AB,AC), (BA,BC), (CA, CB) is orthogonal, ie if its dot product is 0.
    • Another way is to check if the three distances AB, AC, BC form a Pythagorean triplet, ie if z**2 == x**2 + y**2 is true when x,y,z = sorted(map(distance,itertools.combinations(points,2)))

    PS: In general when you write if condition: return True else: return False, you might as well write directly return condition.

    With that in mind, the code you wrote in python for this function is equivalent to:

    from itertools import combinations
    
    def is_acute_isosceles_triangle(point1, point2, point3):
        distances = sorted(map(distance, combinations((point1,point2,point3), 2)))
        return (distances[0] == distances[1] and distances[1] != distances[2])