// ************************************************************************************************
//
// ROOT-Skript zum zentralen Grenzwertsatz
//
// 1) Erstellung eines 2D-Histogramms
// 2) Plotten einer Weihnachtsbaum-Verteilung
// 3) Überlagerung mehrerer Tannenbäume => Gaussverteilung
//
// Heruntergeladen von: www.jb-electronics.de
//

// ************************************************************************************************
// Globale Variablen beschreiben das Aussehen des Baumes
const double	h0			=	1;				// Basishöhe eines Segmentes
const double	w			=	2;   			// Basisbreite
const double	stamm		=	0.05 * w; 		// Dicke des Stammes
const int		nh			=	5;       		// Anzahl der Tannensegmente
const double	hn			=	(nh + 1) * h0;  // Gesamthoehe inklusive Stammm (+1)
const double	abnahme_x 	= 	0.9;			// Die Breite des Baumes nimmt exponentiell nach oben ab

// ************************************************************************************************
// Die Häufigkeitsverteilung entsprechend einer Tanne
void tanne (TRandom *r, double &x, double &y) {

	// Endlosschleife, bis ein passendes Wertepaar im Baum gefunden wird
	do {  

		// noch kein Wertepaar gefunden
		bool fertig = false;

		// Gleichverteiltes Zahlentupel würfeln
		x = r->Uniform(-w, w);
		y = r->Uniform(0, hn * h0);

		// Ist das Zahlentupel im Baum?
		for (int i = 0; i <= nh; i++) {

			// momentane Breite des Baumes
			double wtemp = w * TMath::Power(abnahme_x, i);

			// innerhalb des Stamms?
			if (i == 0) {

				if ((x >= -stamm) && (x <= stamm)) {
					if ((y >= 0) && (y <= h0)) {
						fertig = true;
					}
				}


			// im Tannensegment?
			} else {
					
				if ((x >= -wtemp) && (x <= wtemp)) {

					if ((y >= i * h0) && (y <= (i + 1) * h0)) {

						double d = y - i * h0;
						if (d >= 0) {

							if (x == 0) {
								if (d <= h0) {
									fertig = true;
								}

							} else {

								// Tannensegment?
								if (d <= h0 - h0 / wtemp  * TMath::Abs(x)) {
									fertig = true;
								}

							}

						}	

					}

				}
			}

		}

	} while (!fertig);

}

// ************************************************************************************************
// Hauptprogramm
void tannenbaum (int Ndata = 5000, int Ntanne = 100) {

	// Darstellungsart setzen
    gROOT->SetStyle("Plain");
	
	// Binning des Histogramms
    int Nbins = 200;
	
	// Zufallsgenerator initialisieren
    TRandom *r = new TRandom(11235813);

	// Erzeugung eines 2D-Histograms
    TH2D *hx2 = new TH2D("tanne1", "Tannenbaum", Nbins, -w * 1.3, w * 1.3, Nbins, 0, hn * 1.1);

    TColor DarkGreen(1337,0.,0.7,0.1);
    hx2->SetFillColor(1337);
	//hx2->SetFillColor(kGreen);

	// Zufallswerte würfeln und ins Histogramm füllen
    for (int i = 1; i <= Ndata; i++) {
      
		double x, y;
		tanne(r, x, y);
		hx2->Fill(x, y);

	}
	
	// Canvas erzeugen und in zwei Bereiche aufteilen
    TCanvas *c1 = new TCanvas("Tannenbaum-Überlagerung"); 
	c1->SetWindowSize(700, 400);
	c1->Divide(2);

	// Einfache Tanne in den linken Teil aufzeichnen	
	c1->cd(1);
    hx2->Draw();

	// Zweites Histogramm erzeugen
    TH2D *hx2_add = new TH2D("tanne1_überlagert", "Tannenbäume", Nbins, -w * 1.3, w * 1.3, Nbins, 0, hn * 1.1);

	// Ndata mal Tannenbaumtupel überlagern
    for (int i = 1; i <= Ndata; i++) {
    
		// Variablen für addierte Zahlentupel
		double x_add = 0, y_add = 0;

		// Ntanne mal Überlagern
		for (int j = 1; j <= Ntanne; j++) {
			
			double x = 0, y = 0;
			tanne(r, x, y);
			x_add = x_add + x;
			y_add = y_add + y;

		}

		// Zahlentubel ins Histogramm füllen
		// (auf Ntanne normieren, damit Skala der beiden Histogramme gleich bleibt)
		hx2_add->Fill(x_add / Ntanne, y_add / Ntanne);

    }

    // Überlagerung in den zweiten Teil des Canvas plotten
    c1->cd(2);
    hx2_add->Draw();

}
