Czy punkt P(x,y) należy do kwadratu wyznaczonego przez współrzędne ABCD?

0

Hejka, mam dylemat z pewnym matematycznym zadankiem z Pythona, mianowicie:

Napisz program, który sprawdza, czy punkt P = (x,y) należy do kwadratu o wierzchołkach:
A = (2, 0); B = (0, 2); C = (4, 2); D = (2, 4)

Korzystając z algorytmu z tej strony: https://math.stackexchange.com/questions/190111/how-to-check-if-a-point-is-inside-a-rectangle,
napisałem prosty szkielet programu.

from math import sqrt

Px = float(input('Podaj współrzędną x punktu P: '))
Py = float(input('Podaj współrzędną y punktu P: '))

print('\n')

print('Długości boków trójkąta ABP:')
długość_boku_AB = sqrt((0 - 2) ** 2 + (2 - 0) ** 2)
print(długość_boku_AB)
długość_boku_BP = sqrt((Px - 0) ** 2 + (Py - 2) ** 2)
print(długość_boku_BP)
długość_boku_PA = sqrt((2 - Px) ** 2 + (0 - Py) ** 2)
print(długość_boku_PA)

print('\n')

print('Długości boków trójkąta APC:')
długość_boku_AC = sqrt((4 - 2) ** 2 + (2 - 0) ** 2)
print(długość_boku_AC)
długość_boku_CP = sqrt((Px - 4) ** 2 + (Py - 2) ** 2)
print(długość_boku_CP)
print(długość_boku_PA)

print('\n')

print('Długości boków trójkąta CPD:')
długość_boku_CD = sqrt((2 - 4) ** 2 + (4 - 2) ** 2)
print(długość_boku_CD)
długość_boku_DP = sqrt((Px - 2) ** 2 + (Py - 4) ** 2)
print(długość_boku_DP)
print(długość_boku_CP)

print('\n')

print('Długości boków trójkąta DPB:')
długość_boku_DB = sqrt((0 - 2) ** 2 + (2 - 4) ** 2)
print(długość_boku_DB)
print(długość_boku_BP)
print(długość_boku_DP)

print('\n')

print('Pole trójkąta ABP:')
pABP = (długość_boku_AB + długość_boku_BP + długość_boku_PA) / 2
print('P = {}'.format(pABP))
pole_trójkąta_ABP = sqrt(pABP * (pABP - długość_boku_AB) * (pABP - długość_boku_BP) \
                               * (pABP - długość_boku_PA))
print('Pole = {}'.format(pole_trójkąta_ABP))

print('\n')

print('Pole trójkąta APC:')
pAPC = (długość_boku_AC + długość_boku_CP + długość_boku_PA) / 2
print('P = {}'.format(pAPC))
pole_trójkąta_APC = sqrt(pABP * (pABP - długość_boku_AC) * (pABP - długość_boku_CP) \
                               * (pABP - długość_boku_PA))
print('Pole = {}'.format(pole_trójkąta_APC))

print('\n')

print('Pole trójkąta CPD:')
pCPD = (długość_boku_CD + długość_boku_DP + długość_boku_CP) / 2
print('P = {}'.format(pCPD))
pole_trójkąta_CPD = sqrt(pABP * (pABP - długość_boku_CD) * (pABP - długość_boku_DP) \
                               * (pABP - długość_boku_CP))
print('Pole = {}'.format(pole_trójkąta_CPD))

print('\n')

print('Pole trójkąta DPB:')
pDPB = (długość_boku_DB + długość_boku_BP + długość_boku_DP) / 2
print('P = {}'.format(pDPB))
pole_trójkąta_DPB = sqrt(pABP * (pABP - długość_boku_DB) * (pABP - długość_boku_BP) \
                               * (pABP - długość_boku_DP))
print('Pole = {}'.format(pole_trójkąta_DPB))

print('\n')

print('Pole kwadratu ABCD:')
pole_kwadratu_ABCD = długość_boku_AB ** 2
print('Pole = {}'.format(pole_kwadratu_ABCD))

print('\n')

if round(pole_trójkąta_ABP + pole_trójkąta_APC + pole_trójkąta_CPD + pole_trójkąta_DPB, 10) > \
round(pole_kwadratu_ABCD, 10):
    print('Punkt P(x,y) leży poza kwadratem')
elif round(pole_trójkąta_ABP + pole_trójkąta_APC + pole_trójkąta_CPD + pole_trójkąta_DPB, 10) == \
round(pole_kwadratu_ABCD, 10):
    if (pole_trójkąta_ABP == 0) or (pole_trójkąta_APC == 0) or (pole_trójkąta_CPD == 0) or \
    (pole_trójkąta_DPB == 0):
        print('Punkt P(x,y) znajduje się na kwadracie')
    else:
        print('Punkt P(x,y) znajduje się wewnątrz kwadratu')

Jednak dla niektórych przypadków tj. zmieniających się współrzędnych P(x,y) program podaje nieprawidłowe informacje.
I tu moje pytanie, czy to ja coś źle napisałem, czy ten algorytm działa tylko dla prostokąta? :P

0

Wybrałeś złe rozwiązanie, znaczy się algorytm jest poprawny, ale bezużyteczny (przed copy - paste trzeba było przeczytać cały wątek :P). Lepsze i czytelniejsze, jest rozwiązanie z iloczynami skalarnymi:

def dot(a, b):
    """Dot product, 2 dim only!!"""
    return a[0] * b[0] + a[1] * b[1]

def is_inside_poly(a, b, c, d, p):
    """p point to check. a, b, c, d: polygon"""
    ab = [b[0] - a[0], b[1] - a[1]]
    ad = [d[0] - a[0], d[1] - a[1]]
    ap = [p[0] - a[0], p[1] - a[1]]
    tmp0 = 0 < dot(ap, ab) < dot(ab, ab)
    tmp1 = 0 < dot(ap, ad) < dot(ad, ad)
    return tmp0 and tmp1    

assert is_inside_poly([-1, 0], [0, 1], [1, 0], [0, -1], [0, 0])
assert is_inside_poly([5, 0], [0, 2], [1, 5], [6, 3], [4, 2])
assert not is_inside_poly([2, 0], [0, 2], [4, 2], [2, 4], [0, 0])

1 użytkowników online, w tym zalogowanych: 0, gości: 1