Co jest trudnego w narysowaniu dwóch zaokrąglonych rogów? – DSP#16

Dzisiaj skupimy się tylko i wyłącznie na rogach w kalendarzu. Tak konkretnie, to na dwóch, znajdujących się u góry, półokrągłych.. Nie brzmi skomplikowanie, prawda? Wbrew pozorom, sprawiło mi naprawdę sporo problemu. Ale po kolei.

Te rogi były przedostatnią rzeczą którą mamy do zrobienia (ostatnią są napisy z aktualną datą), najpierw wybór rozwiązania, czyli zajrzyjmy do klasy Path, jakie oferuje sposoby rysowania kątów. Spora część zawartych tam metod doszła w API21, a aplikacja wspiera także wcześniejsze (od API15), po analizie okazało się, że najlepiej będzie zrobić to ręcznie, korzystając z metody cubicTo. No i się zaczęło 😉

Pierwsza próba wyglądała obiecująco:

Co jest trudnego w narysowaniu dwóch zaokrąglonych rogów?

Parametry które po kolei przyjmuje ta funkcja:

  • startowyX
  • startowyY
  • środkowyX
  • środkowyY
  • końcowyX
  • końcowyY

Ok, czyli dwa pierwsze parametry to miejsce startu rysowania, dwa środkowe to punkt odniesienia, dwa końcowe, to miejsce gdzie funkcja się kończy. Nie brzmi najgorzej.

Podejście pierwsze

Mój plan był taki:

  1. Po lewej stronie punkt styku pomiędzy obramowaniem a wysokością paska
  2. Wartość stała na wysokości paska i lewa strona
  3. Krzywa do wartości stałej na górnym pasku, środkowy parametr to róg kalendarza
  4. Prosta do drugiej wartości stałej na pasku
  5. Krzywa do wartości stałej na wysokości paska i prawej strony, prawy róg kalendarza to środkowy parametr
  6. Prosta do wysokości paska i prawej strony

Czyli podsumowując, rysowanie ciągiem od lewej do prawej strony. Musiałem zmienić ten plan. Nie zadziałała tutaj jedna rzecz, mianowicie rysując ścieżkę z osi y i skręcając w prawo odnosząc się do lewego rogu kalendarza otrzymałem inny kąt niż rysując z osi x i skręcając również w prawo, tym razem odnosząc się do prawego rogu. Gołym okiem widać było, że rogi są zupełnie różne i nie tędy droga.

Podejście drugie

Trzeba było zmienić założenia, skoro te rogi rysują się inaczej, to narysuję róg po lewej, następnie użyję metody moveTo, aby przeskoczyć na prawą stronę i narysuję róg po prawej, to zadziałało tak jak chciałem:

Co jest trudnego w narysowaniu dwóch zaokrąglonych rogów?

Więc dorysuję jeszcze tą pionową linię, znowu użyję metody moveTo, zamknę ścieżkę i skończone, prawda?

Co jest trudnego w narysowaniu dwóch zaokrąglonych rogów?

Ghrrr…

Podejście trzecie

Noo dobra, ale kąty mi się zgadzają, a to najważniejsze, więc może utworzę drugą metodę, która dorysuje mi ten brakujący trójkąt? Powinno zadziałać prawda? Geometrycznie działa, niestety wizualnie powstały artefakty (pewnie z powodu pikseli, na które musiała być przeliczona linia prosta) (poniżej powiększona grafika)

Co jest trudnego w narysowaniu dwóch zaokrąglonych rogów?

 

Podejście czwarte

Całkiem to jest zabawne prawda? Niby tylko narysowanie pół okręgu, ale ile przygód może człowieka spotkać? Noo dobra, kolejna zmiana podejścia, jak wiadomo piksele to kwadraty ułożone jeden przy drugim, w związku z tym narysujmy lewą część, a osobną ścieżką prawą część, tylko niech mają pionowe linie styku. Tym razem się wreszcie się udało. Poniżej działający kodzik.

Jak widać pozmieniałem też trochę nazwy zmiennych.

  • barY to wysokość paska na nosi Y
  • angleY to miejsce gdzie zaczynamy rysować kąt
  • axngleX1 to miejsce gdzie kończymy rysować kąt po lewej
  • angleX2 to miejsce gdzie kończymy rysować kąt po prawej

Podsumowując, nie wiedziałem, że po tylu latach problem sprawi mi narysowanie dwóch półokręgów w Androidzie. To była całkiem ciekawa przygoda, trochę nauczyła mnie pokory. Dlatego też ten wpis pojawia się w sobotę, ponieważ te wszystkie przygody zajęły mi o wiele więcej czasu niż myślałem. Ale cóż, tak to właśnie jest z przygodami, w następnej części zajmiemy się wyświetlaniem aktualnej daty na kalendarzu. Kod w aktualnej wersji jest dostępny na githubie.