A nemzetközi Pi nap alkalmából (március 14) Java programmal grafikusan ábrázoljuk a π számjegyeit. Kiindulunk egy négyzet alakú grafikus felület középpontjából. Ezt tekintjük origónak. Sorra vesszük a π első néhány számjegyét: 100, 1000, 10000 paraméterezhető módon. Minden számjegyet egy rövid szakasszal ábrázolunk. A szakaszok egymást követik. Az előző végpontja megegyezik a következő kezdőpontjával. A rajzolás elejét és végét kör jelzi.
Tervezés
Az alábbi szabály alapján döntjük el, hogy a π előforduló számjegyei esetén melyik irányba és milyen színnel rajzolunk szakaszt:
A π első 100000 db számjegyét tároljuk egy szövegfájlban. Ömlesztve, sortörés, tizedesvessző nélkül. Így a π első 30 számjegye: 314159265358979323846264338327. A szövegfájl helyét a String PI_FILE konstans jegyzi meg. A paraméternek megfelelően ebből vesszük az első N db számjegyet. Ezt a Java program beolvassa egy String típusú pi szövegobjektumba. A számjegyek összetartozó adatait egy Digit osztály rendeli egymáshoz. Ennek három adattagja van: melyik számjegy: int digit, melyik irányba kell szakaszt rajzolni java.awt.Point direction, milyen színnel kell szakaszt rajzolni java.awt.Color color. A tízféle színt egy konstans tömb tárolja: Color[] COLORS.
Részletek a Java forráskódból
A π tízféle számjegyéből az alábbi forráskód-részlettel létrejön egy tömb adatszerkezet: Digit[] digits. A koordináták/vektorok kiszámítása követi az analóg óra számlapjának 36 fokonként való felosztását.
1 2 3 4 5 6 7 |
for(int i=0; i<10; i++) { Point p=new Point( (int)(Math.cos(Math.toRadians(i*36-90))*LINE_LENGTH), (int)(-Math.sin(Math.toRadians(i*36-90))*LINE_LENGTH) ); digits[i]=new Digit(i, p, COLORS[i]); } |
A rajzoláshoz szükséges még néhány konstans: milyen vastag vonalat kell rajzolni: double PEN_RADIUS, mekkora átmérőjű kör jelzi a rajzolás kezdő- és végpontját: double POINT_RADIUS, milyen hosszú vonalat kell rajzolni: int LINE_LENGTH, a rajzterületet mekkorára kell méretezni/skálázni: int SCALE.
Mindezek alapján az alábbi forráskód-részlet vizualizálja a π számjegyeit:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
private void piDraw() { StdDraw.setScale(-SCALE, SCALE); StdDraw.setPenRadius(PEN_RADIUS); Point p1=new Point(0, 0); StdDraw.setPenColor(digits[3-1].getColor()); StdDraw.circle(p1.x, p1.y, POINT_RADIUS); for(int i=0; i<PI.length(); i++) { int digit=Integer.parseInt(""+PI.charAt(i)); Point p2=new Point( p1.x+digits[digit].getDirection().x, p1.y+digits[digit].getDirection().y); StdDraw.setPenColor(digits[digit].getColor()); StdDraw.line(p1.x, p1.y, p2.x, p2.y); p1=p2; } StdDraw.circle(p1.x, p1.y, POINT_RADIUS); } |
Eredmény
Eredményül ezek az ábrák készíthetők el:
A rajzoláshoz felhasználtuk az StdDraw osztályt, amely ennek a tankönyvnek a példatárából származik: Robert Sedgewick, Kevin Wayne: Computer Science: An Interdisciplinary Approach, 1st edition, Princeton University, Addison-Wesley Professional, 2016, ISBN 978-0134076423. Az osztály metódusaival könnyen beállítható a nézőpont, a vízszintes/függőleges skála, a rajzoláshoz használt toll mérete/színe és a grafikai primitívek közül csak a kör és szakasz ábrázolása szükséges.
Korábban is megemlékeztünk néhány közelítő algoritmus – Viète-féle sor, Leibniz-féle sor, Wallis-formula, Csebisev-sor – implementálásával erről az ünnepnapról: Nemzetközi Pi nap. Ajánljuk korábbi blog bejegyzéseinket rajzolás, animáció, grafika címkékkel, illetve ASCII művészet Java-ban.
A bejegyzéshez tartozó teljes forráskódot ILIAS e-learning tananyagban tesszük elérhetővé tanfolyamaink résztvevői számára.
A feladat a Java SE szoftverfejlesztő tanfolyam szakmai moduljának 5-8. óra: Vezérlési szerkezetek, 13-16. óra: Tömbök, 17-28. óra: Objektumorientált programozás, 29-36. óra: Grafikus felhasználói felület, 37-44. óra: Fájlkezelés alkalmaihoz kötődik.
A témához kötődik rövid beszámolóm a Vasarely Múzeum látogatásomról: Múzeumok Éjszakája 2023.
Sándor: kipróbáltam az StdDraw osztályt. Köszönöm az ötletet. Hasznos lesz majd, ha ilyen könnyen tudok majd vele látványos grafikát vagy esetleg animációt készíteni.
Örülök Pali, hogy inspirált az
StdDraw
osztály Pi napra készült alkalmazásra. Javaslom, hogy nézd meg az ILIAS-on Balázs projektjének teljes forráskódját is, ami szintén használja ezt az osztályt: Szívgörbe ábrázolása.Köszönöm, hétvégén kattintom.