/*
* Created on 12.02.2005
*/
package pi;
/**
* @author Bone
*/
public final class Pi {
private Pi() {} // Keine Instanz erlaubt
/**
* Eine Rechnung, welche von den alten Ägyptern
* benutzt wurde.
*
* Pi =~ (16/9)²
*/
public static double agypten_pi() {
return (((double)16 / 9) * ((double)16 / 9));
}
/**
* Eine Rechnung, welche im alten Babylon benutzt
* wurde. Sie leitet sich aus einem 12-Eck her, welches
* in einem Kreis ist.
* @see [url]http://magnet.atp.tuwien.ac.at/scholz/projects/fba/graf2.gif[/url]
*/
public static double babylonien_pi() {
// Grad Zahl in Radiant umwandeln
double rad =
2 *
Math.
PI /
360 *
(30 /
2);
double hoehe =
Math.
cos(rad
);
double seite =
Math.
sin(rad
);
return 12 * seite * hoehe;
}
/**
* Antiphon (430 v. Chr) war der Meinung, dass man
* Pi errechnen könnte, in dem man sich den Kreis
* einfach als ein Vieleck mit "unendlich" Ecken
* vorstellt.
*/
public static double griechenland_pi(int dreieck_anzahl) {
int anzahl = dreieck_anzahl;
double grad = ((double)360 / anzahl / 2);
// Grad -> Radiant
double rad =
2 *
Math.
PI /
360 * grad;
double hoehe =
Math.
cos(rad
);
double seite =
Math.
sin(rad
);
return anzahl * seite * hoehe;
}
/**
* Um 510 n.Chr. gab Aryabhatiya folgende Regel zur
* Bestimmung von pi an: "Addiere 4 zu 100,
* multipliziere mit 8, und addiere 62 000.
* Das Resultat ist der ungefähre Wert des
* Umfanges eines Kreises mit dem Durchmesser 20 000."
*/
public static double indien_pi() {
// sonst wird eine Ganzzahl zurückgegeben
double vier = 4;
return ((vier + 100) * 8 + 62000) / 20000;
}
/**
* @see [url]http://magnet.atp.tuwien.ac.at/scholz/projects/fba/fba.html#sec_Leibniz[/url]
*/
public static double leibniz_pi(int durchlauf) {
double pi = 1;
double eins = 1;
int nenner = 1;
for (int i = 1; i <= durchlauf; i++) {
nenner = nenner + 2;
if ((i % 2) == 1) { // ist die Zahl gerade?
pi = pi - (eins/nenner);
} else {
pi = pi + (eins/nenner);
}
}
return 4 * pi;
}
/**
* @see [url]http://magnet.atp.tuwien.ac.at/scholz/projects/fba/fba.html#sec_Wallis[/url]
*/
public static double wallis_pi(int zahlen) {
double pi = 1;
int zaehler = 0;
int nenner = 0;
for (int i = 2; i < zahlen+1; i++) { // mit 2 Anfangen
if ((i % 2) == 1) { // 0.5 er Zahl
zaehler =
new Double(((i/
2)-0.5)*
2).
intValue()+1;
nenner = i;
} else {
zaehler = i;
nenner =
new Double(((i/
2)-0.5)*
2).
intValue();
}
pi = pi * zaehler/nenner;
}
return pi*2;
}
/**
* WARNING: Die nenner und zaehler werden leicht gesprengt
* -> durchlauf darf maximal 31 sein
* @see [url]http://magnet.atp.tuwien.ac.at/scholz/projects/fba/fba.html#sec_Machin[/url]
*/
public static double machin_pi(int durchlauf) {
double pi = 0.5;
long hilfzahl2 = 1;
long nenner2 = 1;
long zaehler = 1;
long nenner = 1;
int hilfzahl = 1;
int y = 0;
for (int i = 1; i <= durchlauf; i++) {
y = 1;
zaehler = 1;
nenner = 1;
for (int a = 0; a < i; a++) {
zaehler = zaehler * y;
nenner = nenner * ++y;
y++;
}
hilfzahl = hilfzahl + 2;
hilfzahl2 = 1;
for (int z = 0; z < hilfzahl; z++) {
hilfzahl2 = hilfzahl2 * 2;
}
nenner2 = hilfzahl * hilfzahl2;
pi = pi + ((double)zaehler / nenner) * ((double)1 / nenner2);
}
return 6 * pi;
}
/**
* @see [url]http://magnet.atp.tuwien.ac.at/scholz/projects/fba/fba.html#sec_Euler[/url]
*/
public static double euler_pi(int durchlauf) {
// TODO: implementieren
return -1;
}
/**
* Yoshiaki Tamura und Tasumasa Kanada haben mit
* folgendem die meisten Stellen bisher von Pi
* berechnet.
*/
public static double tamura_pi(int durchlauf) {
double pi = 0;
double a = 1;
double x = 1;
double b =
1 /
Math.
sqrt(2);
double c = 1 / 4;
double y = 0;
for (int i = 0; i < durchlauf; i++) {
y = a;
a = (a + b) / 2;
c = c - x * ((a - y) * (a - y));
x = 2 * x;
}
// TODO: Fehler - es kommt immer etwa "-33.343" heraus
return ((a + b) * (a + b)) / (4 * c);
}
/**
* TODO: Herausfinden, wie dieser Berechnungsart heißt
*/
public static double nenner_pi(int durchlauf) {
double pi = 0;
for (int i = 1; i < durchlauf; i++) {
pi = pi + ((double)1/(i*i));
}
}
/**
* TODO: Herausfinden, wie dieser Berechnungsart heißt
*/
public static double nenner2_pi(int durchlauf) {
double pi = 0;
int hilfz = 2;
long nenner = 1;
for (int i = 0; i < durchlauf; i++) {
nenner = hilfz * ++hilfz * ++hilfz;
if ((i % 2) == 1) { // gerade Zahl?
pi = pi - ((double)1 / nenner);
} else {
pi = pi + ((double)1 / nenner);
}
}
return pi * 4 + 3;
}
/**
* Eine Monte-Carlo Methode, mit welcher man
* Pi "erschießen" kann.
*/
public static double erschiesse_pi(int tropfenzahl) {
double pi = 0;
int innerhalb = 0;
int gesamt = tropfenzahl;
while (tropfenzahl > 0) { // generiere Tropfen und addiere je nach Zugehörigkeit
double dotx =
2 *
Math.
random() -
1;
double doty =
2 *
Math.
random() -
1;
if (Math.
sqrt(dotx*dotx + doty*doty
) <=
1) { // Punkt liegt innerhalb des Kreises
innerhalb++;
} else {
// Punkt liegt außerhalb des Kreises
}
tropfenzahl--;
}
pi = 4*(double)innerhalb/gesamt;
return pi;
}
}