To nie jest tak, że to nie ma sensu, ale po prostu działa niezręcznie w 99% przypadków.
Często w grafice 2D prostokąty są inicjalizowane, przechowywane i przetwarzane jako para punktów. W żadnym konkretnym języku
class Rect:
p1, p2: point
Bardziej sensowne jest zdefiniowanie prostokąta jako dwóch wartości x i dwóch wartości y, takich jak to:
class Rect
xleft, xright: int
ytop, ybottom: int
Z dwoma punktami, jeśli w pewnym miejscu w kodzie źródłowym chcesz użyć wartości y dla góry, musisz powiedzieć rect.p1.y (hmmm, zatrzymaj się i pomyśl, czy to p1 czy p2), ale z czterema wartościami jako zwykłymi elementami danych, jest to jasne i bezpośrednie: rect.ytop (nie wymaga myślenia!) Użycie dwóch punktów oznacza, że w przypadku pionu musisz splątać poziomo; istnieje zależność między niezależnymi elementami.
Jak powstał ten dwupunktowy pomysł i dlaczego się utrzymuje? Czy ma to jakąś zaletę w stosunku do samych współrzędnych xiy?
DODATKOWA UWAGA: To pytanie jest w kontekście wyrównanych prostokątów XY, takich jak menedżery okien i zestawy narzędzi GUI, a nie w kontekście dowolnych kształtów w aplikacji do rysowania i malowania.
źródło
Odpowiedzi:
Czy uważasz, że jest mniej podatny na błędy?
Jeśli użyjesz (Point1, Point2), wtedy bardzo jasne jest, co określasz . Jeśli podasz 2 punkty, jedynym możliwym błędem jest to, że użytkownik pomieszał swoje xiy podczas konstruowania punktów, ponieważ kolejność punktów nie ma znaczenia.
Jeśli podasz 4 liczby całkowite, to jeśli ktoś nie zwraca uwagi, może podać (x1, x2, y1, y2), kiedy chcesz (x1, y1, x2, y2) lub odwrotnie. Ponadto niektóre interfejsy API, takie jak struktura Rect z WCF, definiują prostokąt jako (x, y, szerokość, wysokość), co może powodować zamieszanie w kwestii tego, co oznaczają (1, 2, 3, 4). Czy to (x, y, w, h) lub (x1, y1, x2, y2) lub (x1, x2, y1, y2)?
Podsumowując, (Punkt 1, Punkt 2) wydaje mi się nieco bezpieczniejszy.
źródło
Zawsze lubiłem definiować prostokąt jako punkt + szerokość i wysokość, gdzie punkt jest lewym górnym rogiem prostokąta.
A następnie dodaj wszelkie potrzebne metody, aby pobrać inne metryki. Podobnie jak wersja Java
źródło
W rzeczywistości prostokąt nie jest zdefiniowany przez 2 punkty. Prostokąt można zdefiniować tylko za pomocą dwóch punktów, jeśli jest równoległy do osi.
Istnieje kilka sposobów reprezentowania prostokątów równoległych do osi:
W przypadku (1) wiele bibliotek używa konwencji, aby określić, które dwa punkty są używane - na przykład topLeft i bottomRight.
Wybór reprezentacji może wynikać z pierwotnego celu definicji prostokąta, ale wyobrażam sobie, że często jest to arbitralne . Reprezentacje są równoważne w informacjach, które niosą. Różnią się one jednak łatwością, z jaką można obliczyć właściwości prostokąta, oraz wygodą, z jaką operacje mogą być wykonywane na prostokącie.
Korzyści z definicji (1) w porównaniu do innych obejmują:
źródło
No cóż,
p1: Point
czyp2: Point
każda z nich będzie miała dwieint
współrzędne , więc czy twoja klasa nie sprowadza się do tego samego?A jeśli przechowujesz te dwa punkty jako obiekty pierwszej klasy
Point
, czy nie zyskujesz z nich trochę więcej użyteczności? W większości graficznych układów współrzędnych, które znam, punkty są podklasowane w ten sposób, aby stworzyć hierarchię obiektówpoint -> circle -> ellipse
i tak dalej.Jeśli więc tworzysz obiekt, który nie korzysta z
Point
klasy, oddzieliłeś ten obiekt od reszty hierarchii klas.źródło
ytop
/ybottom
, musiałaby istnieć gwarancja gdzieś, coybottom
faktycznie znajduje się poniżejytop
.Dlatego lubię Delphi
TRect
. Jest zdefiniowany jako rekord wariantowy (struktura ujednolicona w C-speak), który można interpretować jako punkt TopLeft i BottomRight lub liczby całkowite Top, Left, Bottom i Right, w zależności od tego, który z nich jest dogodniejszy.źródło
Z pewnością jeśli zdefiniujesz prostokąt jako:
wtedy od razu wiesz, który punkt jest który.
Jeszcze lepiej byłoby dodać dodatkowe właściwości, które pozwoliłyby ci manipulować prostokątem w dowolne sposoby potrzebne dla twojej aplikacji. Po prostu zaktualizują one podstawową strukturę danych.
Dodając transformację do kształtu, możesz ustawić prostokąt w dowolny sposób. Nadal będziesz potrzebować wyrównanego do osi obwiedni, aby szybko sprawdzić / odrzucić :)
Jeśli jednak Twój model dopuszcza prostokąty w dowolnej orientacji bez zastosowania transformacji, wówczas „dolny lewy” i „górny prawy” nie mają znaczenia, co prowadzi z powrotem do „p1” i „p2” (lub czegoś równoważnego).
źródło
myślę, że bardziej sensowne jest, aby prostokąt był reprezentowany przez zasięg xiy i punkt; możesz nawet ustawić punkt położenia na środku prostokąta, aby był niezależny od obrotu
ale prawdopodobnie najłatwiej było go zakodować jako dwa punkty!
źródło
Nie podoba mi się to, ponieważ wyrzuciliśmy potencjalny stopień swobody, który zasadniczo pozwala na dowolną rotację. Ogólny prostokąt 2D ma pięć niewiadomych (stopnie swobody). Możemy określić je jako współrzędne punktu, długości dwóch boków, które tworzą wierzchołek z tym punktem, oraz kąt względem poziomu pierwszej linii (przy założeniu, że drugi ma kąt o 90 stopni większy). Można również zastosować nieskończoną liczbę innych możliwości, ale należy podać pięć niezależnych wielkości. Niektóre wybory doprowadzą do łatwiejszej algebry niż inne, w zależności od tego, co się z nimi zrobi.
źródło
Czy to nie to samo, co 2 punkty? Jak to jest niezręczne ... większość procedur rysowania wymaga punktów, a nie oddzielnych komponentów x / y.
źródło
Definiowanie prostokątów jako par punktów pozwala ponownie wykorzystać punkt jako wierzchołek dla innego kształtu. Tylko myśl ...
źródło
Uważam, że chodzi głównie o ustalenie jednorodności wszystkich prymitywów kształtu.
Jasne, że możesz zdefiniować prostokąt na wiele różnych sposobów, ale jak zdefiniować trójkąt, gwiazdę lub okrąg w sposób, który może wykorzystywać podobne struktury danych?
Wszystkie wielokąty można zdefiniować według ich punktów, z niewielką logiką, aby określić, co zrobić z punktami.
Biblioteki graficzne działają przede wszystkim na tych wielokątach pod względem wierzchołków i krawędzi, więc punkty i linie między nimi, wszystkie obliczenia działają na tych dwóch elementach, dobrze i na ściankach, ale to samo jest tylko funkcją krawędzi.
źródło
W dwóch wymiarach zapisanie prostokąta jako dwóch punktów jest wyraźniejsze niż zdefiniowanie konkretnego narożnika oraz szerokości i wysokości - rozważ ujemną szerokość lub wysokość lub obliczenia wymagane do określenia każdej opcji z drugiej.
Wykonywanie obrotów na prostokącie zdefiniowanym przez punkty jest również znacznie prostsze niż zdefiniowane przez punkt plus szerokość i wysokość.
Spodziewałbym się, że enkapsulacja sprawi, że to zróżnicowanie nie będzie ważne jako użytkownik klasy.
Prostokąt powinien być zdefiniowany jako trzy punkty, które będą dobrze zdefiniowane w 3 wymiarach. Nie jestem całkowicie pewien wymogu definiowania prostokąta w 4 lub więcej wymiarach.
źródło
To jest całkowicie arbitralne. Potrzebujesz czterech informacji, aby narysować prostokąt. Projektanci bibliotek postanowili przedstawić go za pomocą dwóch punktów (każdy ze współrzędną xy), ale z łatwością mogliby to zrobić za pomocą x / y / w / h lub góra / dół / lewo / prawo.
Przypuszczam, że prawdziwym pytaniem PO jest: dlaczego dokonano tego konkretnego wyboru?
źródło
Wybór parametrów jest ważny tylko dla projektantów / programistów niskiego poziomu.
Użytkownicy wysokiego poziomu muszą tylko pomyśleć o:
Uwaga: Aby zminimalizować utratę precyzji podczas skalowania transformacji, czasami właściwe jest zaimplementowanie drugiej klasy Rect, która używa współrzędnych zmiennoprzecinkowych, aby wyniki pośrednie mogły być dokładnie zapisane w sekwencji transformacji i zaokrąglone do liczby całkowitej w ostatni krok.
źródło
Jak mówi @Steven, myślę, że powinno być w kategoriach jednego (x, y) punktu i wektora wielkości (w, h). To dlatego, że łatwo wpaść w dwuznaczność. Załóżmy, że masz następujący wypełniony prostokąt zaczynający się w punkcie (0,0).
Oczywiście jego szerokość, wysokość to (3,3), ale co to jest drugi punkt? Czy to (2,2) czy (3,3)?
Ta dwuznaczność może powodować różnego rodzaju problemy.
Dowiedziałem się w przykry sposób rok temu, że lepiej myśleć o współrzędnych graficznych jako linie między pikselami, nie jako linie piksele są na . W ten sposób nie ma dwuznaczności.
źródło
Możemy zdefiniować zarówno Pb, jak i Pc w ten sposób:
i
Dlatego nie ma potrzeby definiowania wszystkich czterech punktów ze względu na symetrię
źródło