В настоящее время я учусь программировать на Python, столкнулся с этой задачей и пытаюсь ее решить. Но я думаю, что где-то допустил ошибку, и мне было интересно, может быть, кто-нибудь поможет мне с ней. Задача — написать код, который будет: Импортируйте четыре 2D-координаты (A, B, C и X) из текстового файла. Проверьте, могут ли A, B, C быть точками прямоугольника. Проверьте, находится ли X внутри прямоугольника ABC. Вычислите диагональ прямоугольника.
Пока у меня есть это:
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")
Код работает, но я думаю, что он неправильно рассчитывает диагональ. Например, возьмем на вход следующие точки: A(0, 0), B(5,0), C(0, 5) и X(2, 2). Там говорится, что они могут быть точками прямоугольника и что диагональ равна 5. Когда я помещаю эти точки на бумагу, четвертая точка может быть D(5, 5), а тогда диагональ равна 7,07 (квадратный корень из 50). Или это может быть D(-5, 5), но тогда это параллелограмм и одна диагональ равна 5, но она не максимальная. Также я пытаюсь написать функцию, которая будет проверять, являются ли все данные в текстовом файле целыми числами. Допустим, B равно (m, k), тогда он должен вернуть false, и если все данные являются целыми числами, продолжить код. Есть идеи по этому поводу?
Привет. Не могли бы вы уточнить, что вы подразумеваете под «точкой прямоугольника»? Означает ли предложение «A — точка прямоугольника (R)» (1) A — одна из четырех вершин прямоугольника (R); (2) A находится на одной из сторон (R); (3) A находится внутри прямоугольника (R)?
Привет @Stef, это (1) A — одна из четырех вершин прямоугольника.
«Код работает» — Нет, не работает. Например, is_rectangle((0, 0), (1, 0), (0, 2))
возвращает False
.
Обратите внимание, что здесь не один прямоугольник. Пока три точки A, B и C не лежат на одной прямой, может существовать бесконечное количество прямоугольников, на которых лежат эти точки, при этом «тривиальный» прямоугольник имеет две точки, которые находятся дальше всего друг от друга, как две вершины с краем. E между ними, две стороны, параллельные вектору проекции P третьей точки на E, и последнее ребро, параллельное E, проходящее через вашу третью точку.
Давайте посмотрим на логику вашей функции is_rectangle
.
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
Вы проверяете, равны ли две наименьшие стороны треугольника ABC и отличаются ли они от наибольшей стороны.
Эффективно отвечая на вопрос: «Является ли ABC тупоугольным равнобедренным треугольником?»
Но вам следует задаться вопросом: «Является ли ABC прямоугольным треугольником?»
Есть несколько способов проверить, является ли треугольник ABC прямоугольным.
z**2 == x**2 + y**2
, когда x,y,z = sorted(map(distance,itertools.combinations(points,2)))
PS: В общем, когда пишешь if condition: return True else: return False
, можно и напрямую return condition
.
Имея это в виду, код, который вы написали на Python для этой функции, эквивалентен:
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])
Спасибо чувак, твой совет сработал!
В дополнение к ответу @Stef вы можете упростить логику, используя наклоны :
def find_fourth(*points): # 3
from itertools import combinations
zs = next(
(
comb
for comb in combinations(points, 2)
if comb[0][1] == comb[1][1]
),
None,
)
if zs and (diff := {*points}.difference(zs)):
x, y = diff.pop()
m = abs(zs[0][0] - zs[1][0])
return (x + m, y), (x - m, y)
Выход :
A = (0, 0)
B = (5, 0)
C = (0, 5)
find_fourth(A, B, C) # ((5, 5), (-5, 5))
Десмос :
Вы задаете слишком много вопросов за один раз. Они могут быть частью прямоугольника, если для двух пар точек их соединяющие линии расположены под углом 90 градусов. Диагональ — это длина линии, соединяющей необщую точку. Чтобы узнать, находится ли X внутри, вы можете повернуть его, чтобы совместить с осями координат, и просто проверить границы. (В качестве альтернативы существует аргумент, основанный на площади, который работает с обычными многоугольниками.) В вашем примере диагональ действительно должна быть 5.sqrt(2). Целые числа — это совсем другой вопрос, и у меня закончилось место.