Arpoo pisteitä neliönmuotoiselle alueelle, katsoo kuuluuko arvottu piste ympyrän sisälle ja laskee näiden arpomalla saatujen tietojen perusteella piin likiarvoa.
Tämä metodi ei ole kovinkaan tarkka, eikä nopea, mutta onpahan kuitenkin... :)
EDIT: Koodia muutettu siten, että sen saa nyt myös pysäytettyä, eli nyt se ei edes jää jumiin (lue kommentit jos haluat tietää mitä se teki ennen...)
Valmis appletti on osoitteessa http://www.paivola.net/~sami/java/pii/pii.html
import java.awt.*; import java.awt.event.*; import java.applet.*; public class Pii extends Applet implements ActionListener { //Laskurit laskemaan sisälle ja ulos osuneita pisteitä int sisalla, ulkona; int arvottu; boolean stopped; Button stop; //Tekstikenttä likiarvon tulostamista varten Label pii; public void init() { //Koon asettaminen ja laskurien alustaminen //Laskennan kannalta koko on samantekevää, //mutta alueen pitää olla neliön muotoinen! this.setSize(500, 500); sisalla = 0; ulkona = 0; arvottu = 0; pii = new Label(); add(pii); //Piirtämisen pysäyttämiseen stopped = false; stop = new Button("stop/resume"); add(stop); stop.addActionListener(this); } //Pysäytetään/jatketaan nappulaa painettaessa public void actionPerformed(ActionEvent e) { if (e.getSource().equals(stop)) { stopped = !stopped; repaint(); } } //Ylikirjoitetaan update, jotta vanhat tavarat eivät pyyhkiytyisi pois public void update(Graphics g) { paint(g); } public void paint(Graphics g) { //Asetetaan tekstikenttä ja nappula sopivan kokoiseksi pii.setBounds(this.getWidth() / 2 - 75, 10, 150, 20); stop.setBounds(this.getWidth() / 2 - 40, 40, 80, 20); //Pyöritään silmukassa koko loppuelämä... Tai kunnes painetaan stop if (!stopped) { //Arvotaan uusi piste double x = Math.random() * this.getWidth(); double y = Math.random() * this.getHeight(); //Jos piste on alueen sisällä, maalataan se punaisella, //ulkopuolella olevat pisteet maalataan vihreällä if (onkoSisalla(x, y)) { int red, green, blue; red = (int)(Math.random() * 100) + 155; green = (int)(Math.random() * 100); blue = (int)(Math.random() * 100); g.setColor(new Color (red, green, blue)); } else { int red, green, blue; red = (int)(Math.random() * 100); green = (int)(Math.random() * 100) + 155; blue = (int)(Math.random() * 100); g.setColor(new Color (red, green, blue)); } //Piirretään piste g.drawLine((int)x, (int)y, (int)x, (int)y); arvottu++; //Näytetään piin arpomalla saatu likiarvo 10000 kierroksen välein //sekä konsolissa, että piirtopinnalla if (arvottu % 10000 == 0) { System.out.println((4.0 * sisalla) / (double)arvottu); pii.setText("" + (4.0 * sisalla) / (double)arvottu); } repaint(); } } //Metodi, joka tarkistaa kuuluuko piste ympyrän sisälle vai ei. //Laskemiseen käytetään perinteistä Pythagoraan lausetta, eli //a^2 + b^2 = c^2 public boolean onkoSisalla(double x, double y) { if (Math.sqrt(Math.pow(((this.getWidth() / 2) - x), 2) + Math.pow(((this.getHeight() / 2) - y), 2)) < this.getHeight() / 2) { sisalla++; return true; } else { ulkona++; return false; } } }
Vielä yksi pikkujuttu:
Kannattaa varoa hieman (tai ainakin olla tietoinen tästä asiasta), sillä tuo ikuinen silmukka saattaa aiheuttaa selaimen jämähtämisen appletin katsomisen jälkeen (selain saattaa kuluttaa yhä melkein 100% prosessoriajasta), mutta selaimen uudelleen käynnistäminen auttaa jos näin käy.
Tässä on vähän samantyylinen QBasic-ohjelma, tosin ilman grafiikkaa.
RANDOMIZE TIMER FOR i& = 1 TO 2147483647 IF SQR(RND ^ 2 + RND ^ 2) < 1 THEN j& = j& + 1 END IF LOCATE 1, 1: PRINT j& / i& * 4 NEXT
Toinen varoitus:
Minulla se ainakin jatkoi kuvan piirtämistä näytölle
vaikka selaimen sulkikin. Ja aina kun avasi jonkun
ponnahdusikkunan(esim. käynnistä-valikon), niin se piirti
sen päälle (vaikka se on eri kohdassa kuin appletti oli).
Siitä ei selvinnyt muuta kuin reset-napilla.
Minulla näkyy pelkkää harmaata(IE6, Java 1.4).
Tuolla appletti -linkissä
ezuli:
Aika mielenkiintoinen "feature"... Mutta luultavasti prosessin tappaminen lopettaisi sen piirtämisen. (Toisaalta eikös appletien ainakin pitäisi olla melko turvallisia suorittaa ilman sivuvaikutuksia?)
No just... kivoja ohjelmia kun kone menee tileen, ja minä menin avaamaan sen >:P
Poistakaa tuo linkki ettei muille käy samoin.
Linkki käännettyyn appletiin on
http://www.paivola.net/~sami/java/pii/pii.html
Ja muistithan lukaista ne pari pikkujuttua, mitä tämän kanssa on käynyt... ;)
Eikös kannattaisi tehdä vaikka silleen, et se kysyy kuinka monta desimaalia siihen haluaa...
Aika hyvä.
Pienen odottelun jälkeen 4 ensimmäistä desimaalia ovat oikein.
Heh nää koulun kirjaston 200mhz koneet tilttaa hyvin tällä :D
Ei se prosessi näkynyt koneella enää missään, ainakaan ctr+alt+del valikossa. Katsoin applettia n.2min ja odotin sammuttamisen jälkeen 5min, jonka jälkeen resettasin. Eli se luultavasti täyttää koneen muistin piirto käskyillä.
Siihen kannattaisi kyllä lisätä joko piste rajoitus, tai odotus käsky, ettei se anna koneelle enempää tekemistä kuin se ehtii tehdä.
'Varoitus' tai jotain jos on huono jäähdytin niin silloin ei ainakaan kannata kokeilla vielä tarkempia arvoja...
Ati Radeon (en muista mikä) ilman jäähdytintä 6 min. ja Ylikuumeni...
Unohdin sanoa: laski piin tarkkaa arvoa ilman takarajaa...
Ilmeisesti tähän oli todellakin syytä tehdä jonkinlainen pysäytys, jollaisen lisäsinkin siihen äsken...
Ja vielä kerran voisin pyytää anteeksi niitä muutamaa kaatunutta konetta, jotka tämä aiheutti ;)
Aihe on jo aika vanha, joten et voi enää vastata siihen.