Wielokąty foremne

Z Wiki Mistrzowie Kodowania
Wersja Iwona Brzózka-Złotnicka (dyskusja | edycje) z dnia 12:03, 14 kwi 2017

(różn.) ← poprzednia wersja | przejdź do aktualnej wersji (różn.) | następna wersja → (różn.)
Skocz do: nawigacji, wyszukiwania

Założenia projektu:

Projekt rysuje wielokąty foremne, korzystając m.in. z funkcji trygonometrycznych, funkcji do rysowania wielokątów: drawPolygon, tworzenia losowego koloru...



Opis projektu:

“Wielokąty foremne” to projekt służący do rysowania wielokątów foremnych, które wypełnione zostają różnymi kolorami zmieniającymi się losowo. Występują 3 klasy:

  • Start (obiekt: start), który pojawia się po uruchomieniu programu. Gdy zostanie kliknięty - znika.
  • Rysunek (obiekt: rysunek), który pojawia się po odpowiedzi na pytanie o liczbę boków. Gdy powstanie, nieustannie zmienia kolor, aż zostanie kliknięty. Wtedy program zostanie zatrzymany.
  • Ground - podklasa Świata, w którym dzieje się wszystko. Odpowiada za pojawianie się w nim obiektów oraz zadaje pytanie o liczbę boków wielokąta.

Realizacja: Tworzenie klas



Klasa Ground

Zacznijmy od przygotowania sceny. Klikamy prawym przyciskiem myszy w klasę World i wybieramy “New subclass...”. Tworzymy klasę Ground, nie przypisując jej żadnego obrazka, aby później rysunki były dobrze widoczne.

Klasa Start

Tworzymy klasę Start (w nadklasie Actor), przypisując jej dowolny obrazek, który wcześniej przygotowaliśmy. Obrazek ten importujemy, klikając przycisk “Import from file...” i wskazując lokalizację naszego pliku.

Klasa Rysunek

Tworzymy klasę Rysunek i nie przypisujemy jej żadnego obrazka, gdyż tutaj powstanie nasz wielokąt. Na razie nie tworzymy programu w tej klasie. Zrobimy to za chwilę.


Realizacja: Tworzenie obiektów oraz metod

Skoro utworzyliśmy klasy, czas na stworzenie konkretnych obiektów i umieszczenie ich w naszym świecie. W klasie Ground tworzymy nowe obiekty: start klasy Start oraz rysunek klasy Rysunek. Jednocześnie w konstruktorze klasy Ground tworzymy kod umieszczający obiekt start na środku naszego ekranu:

       Start start=new Start();

Rysunek rysunek=new Rysunek(); addObject (start, 300,200);


Po skompilowaniu zobaczymy taki widok:


rys. 1 Przycisk na ekranie

Co powinien zrobić teraz program? Cały czas oczekiwać na naciśnięcie przycisku. W takim razie powinniśmy umieścić w nieustannie wykonującej się metodzie act sprawdzanie, czy nie został naciśnięty obiekt start

if(Greenfoot.mousePressed(start))

Gdy obrazek zostanie kliknięty, powinien zniknąć, a program powinien przejść do pytania o rodzaj wielokąta, jaki ma być narysowany.

         	removeObject(start);	// usuwa obiekt start
                  Greenfoot.delay(50);	// oczekuje chwilę
         	    ileBokow();	// przechodzi do metody pytającej o boki
   	

Metoda ileBokow() zapyta o liczbę boków wielokąta. Będzie to liczba całkowita, więc powinniśmy zadeklarować zmienną całkowitą int ile. Aby umożliwić wpisanie przez użytkownika danych do programu, wywołujemy odpowiednie okienko. Znajduje się ono w bibliotece Javy - JOptionPane. Aby móc z niej korzystać, należy ją na początku tej klasy zaimportować, używając polecenia:

     import javax.swing.JOptionPane;

Metoda showInputDialog spowoduje ukazanie się okna dialogowego i program będzie oczekiwał na wpisanie wartości oraz zatwierdzenie jej przyciskiem OK. Wpisana wartość jest odczytywana przez tę metodę jako tekst, więc odczytaną wartość zapisujemy w zmiennej tekstowej String boki i zamieniamy ją na liczbę całkowitą ile, używając metody parseInt z klasy Integer. Następnie umieszczamy obiekt rysunek (chwilowo pusty) na środku ekranu i polecamy obiektowi rysunek w klasie Rysunek wykonanie metody wielokat(ile), gdzie ile jest parametrem metody, a jednocześnie wartością wpisaną przez użytkownika. Ciało metody wygląda następująco:

rys. 2  Metoda ileBokow()

Po uruchomieniu programu i kliknięciu przycisku start pojawi się taki widok:

rys. 3 Okno do wpisania liczby boków

Zaprogramowanie klasy Rysunek

Zadaniem tej klasy będzie stworzenie rysunku. Użyjemy do tego metody drawPolygon z greenfootowej klasy GreenfootImage. Metoda ta potrzebuje 3 parametrów:

  • tablicy zawierającej współczynniki x kolejnych wierzchołków
  • tablicy zawierającej współczynniki y kolejnych wierzchołków
  • liczby wierzchołków

Zadeklarujemy więc na początku potrzebne elementy:

        int[] xWiel;
        int[] yWiel;
         int bok;

Jak wyznaczyć współrzędne poszczególnych wierzchołków? Jeśli wyobrazimy sobie, że nasz wielokąt będzie wpisany w okrąg o promieniu r i środku w początku układu współrzędnych to współrzędne każdego wierzchołka możemy obliczyć za pomocą funkcji trygonometrycznych:

sin = yr czyli y=r sin oraz cos = xr czyli x=r cos


rys. 4 Współrzędne wierzchołka

Załóżmy, że promień okręgu będzie miał długość 150, a środek okręgu będzie w punkcie (300, 200), współrzędne wierzchołka będą wyrażały się wzorami:

x=300 + 150 cos y=200 + 150 sin

Ponieważ wierzchołki muszą być równomiernie rozłożone na okręgu, więc kąt alfa będzie wielokrotnością kąta pełnego podzielonego przez liczbę boków. Żeby obliczać współrzędne poszczególnych wierzchołków, musimy wykonać kilka czynności:

  • zaimportować bibliotekę Javy - Math
  • funkcja sinus i cosinus wymaga argumentu w radianach, więc zamienimy miarę kąta ze stopni na radiany np. za pomocą metody toRadians
  • współrzędne muszą być liczbami całkowitymi, więc należy przekonwertować wynik na liczbę typu int
  • umieścimy otrzymane współrzędne w tablicach xWiel, yWiel

rys. 5 Fragment odpowiedzialny za wyznaczenie i zapisanie współrzędnych wierzchołków

Teraz wystarczy już tylko umieścić naszą figurę na ekranie. W tym celu: setImage(new GreenfootImage(600,400)); - stwarzamy nowy obrazek Greenfoota GreenfootImage rys; - deklarację umieszczamy na początku klasy rys = getImage(); - przypisujemy rys nowy obrazek rys.setColor(Color.RED); - ustawiamy kolor rysowania na czerwony (aby móc ustawić kolor, należy na początku klasy zaimportować bibliotekę Color) import java.awt.Color; Rysujemy wielokąt za pomocą metody drawPolygon: rys.drawPolygon(xWiel, yWiel, bok);


Dodatki: Kolory i zabezpieczenia

Możemy sprawić, że kolor wypełnienia wielokąta będzie się losowo zmieniał. Przed narysowaniem wielokąta ustawiliśmy kolor rysowania na czerwony. Istnieje też możliwość stworzenia własnego koloru wg standardu RGB, ustawiając trzy wartości na liczby z zakresu 0-255

Color nowy = new Color (Greenfoot.getRandomNumber(256), Greenfoot.getRandomNumber(256), Greenfoot.getRandomNumber(256)); Następnie ustawiamy kolor rysowania na nowo stworzony rys.setColor(nowy); i po chwili Greenfoot.delay(50); wypełniamy wnętrze naszego wielokąta za pomocą metody fillPolygon rys.fillPolygon(xWiel, yWiel, xWiel.length); Aby zmiany kolorów dokonywały się nieustannie, umieszczamy ten kod w metodzie act. Czy te kolory powinny się zmieniać zawsze? Na pewno nie ma sensu zmieniać kolorów, jeśli wielokąt jeszcze nie jest cały widoczny i niewątpliwie przydałoby się umożliwić użytkownikowi zatrzymanie zmian. W związku z tym możemy stworzyć zmienną logiczną widoczny. Początkowo nadać jest wartość false. Po narysowaniu wielokąta zmienić na true, a po np. kliknięciu wielokąta ponownie zmienić na false. Dodatkowo wykonywanie zmian koloru wypełnienia uzależnić od wartości zmiennej widoczny:

       if(Greenfoot.mousePressed(this)) Greenfoot.stop();
   	if(widoczny){zmieniaj kolory} 

Ostatecznie cały kod klasy Rysunek będzie wyglądał następująco:


rys. 6 Klasa Rysunek

Zabezpieczenia podczas podawania liczby boków

Zakładaliśmy, że użytkownik poda właściwą odpowiedź na pytanie o liczbę boków, czyli liczbę naturalną nie mniejszą od 3. A co w innym przypadku? Możemy zabezpieczyć nasz program, nakazując mu ponownie zadawać pytanie, jeśli odpowiedź jest liczbą mniejszą od 3. W tym celu można zastosować pętlę do-while. Jej składnia jest następująca:

do{wykonywana czynność} while(warunek);

Pętla wykonywana jest co najmniej raz, dopóki spełniony jest warunek. Nasze zastosowanie mogłoby wyglądać tak:

do{String boki = JOptionPane.showInputDialog("Ile boków ma mieć wielokąt? (Nie mniej niż 3)"); ile = Integer.parseInt(boki);}while(ile<3);

A co w sytuacji, gdy użytkownik poda zamiast liczby całkowitej ułamek lub inny ciąg znaków. Program zgłosi błąd/wyjątek. Można przewidzieć taką sytuację. W Javie istnieje tzw. obsługa wyjątków za pomocą procedury try-catch:

try{wykonaj to, jeśli wszystko przebiega bezbłędnie} catch(Exception ex){w przypadku pojawienia się błędu wykonaj to}

Korzystając z tej możliwości, możemy przyjąć, że program narysuje wielokąt, jeśli wpisaliśmy prawidłową wartość, a w przypadku zaistnienia błędu ukaże się okno komunikatu, że mieliśmy wpisać liczbę całkowitą oraz ustawi wartość wpisu na zero czyli zapyta nas ponownie (gdyż 0 < 3). Do ustawienia okienka komunikatu służy inna metoda z zastosowanej wcześniej biblioteki JOptionPane, a mianowicie showMessageDialog. Ten fragment kodu będzie po modyfikacji wyglądał tak:

rys. 7 Zabezpieczenie przed nieprawidłowymi wpisami