Kirjautuminen

Haku

Tehtävät

Keskustelu: Koodit: Java: Piin likiarvon selvittäminen kokeilemalla

Sivun loppuun

Sami [30.03.2004 01:47:08]

#

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;
		}
	}
}

Sami [30.03.2004 01:55:20]

#

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.

Antti Laaksonen [30.03.2004 13:19:12]

#

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

ezuli [30.03.2004 13:26:54]

#

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.

peki [30.03.2004 14:46:50]

#

Minulla näkyy pelkkää harmaata(IE6, Java 1.4).
Tuolla appletti -linkissä

Sami [30.03.2004 14:54:34]

#

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?)

T.M. [30.03.2004 15:25:38]

#

No just... kivoja ohjelmia kun kone menee tileen, ja minä menin avaamaan sen >:P
Poistakaa tuo linkki ettei muille käy samoin.

Sami [30.03.2004 15:38:21]

#

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... ;)

Meitsi [30.03.2004 17:26:02]

#

Eikös kannattaisi tehdä vaikka silleen, et se kysyy kuinka monta desimaalia siihen haluaa...

Heikki [31.03.2004 07:31:24]

#

Aika hyvä.
Pienen odottelun jälkeen 4 ensimmäistä desimaalia ovat oikein.

sooda [31.03.2004 09:33:20]

#

Heh nää koulun kirjaston 200mhz koneet tilttaa hyvin tällä :D

ezuli [31.03.2004 10:20:02]

#

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ä.

Wukkopi [31.03.2004 14:05:33]

#

'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...

Wukkopi [31.03.2004 14:06:04]

#

Unohdin sanoa: laski piin tarkkaa arvoa ilman takarajaa...

Sami [31.03.2004 22:42:04]

#

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 ;)


Sivun alkuun

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta