#include "TCanvas.h"
#include "TApplication.h"
#include "TMarker.h"
#include "TLine.h"
#include "TEllipse.h"
#include "TPave.h"
#include "TLatex.h"
#include "TCurlyArc.h"
#include "TMath.h"
#include <iostream>
#include <unistd.h>
#include "TROOT.h"
#include "TColor.h"
#include "TColorGradient.h"
#include "TStyle.h"
#include "TArrow.h"
#include "TImage.h"
#include "TSystem.h"
#include <sys/time.h>
#include <unistd.h>

Int_t    screenX = 800;
Int_t    screenY = 600;

//Timing
long ShowExperiments = 20;
long ParticlesTime = 22;
long StarsTime = 25;
long StarsLeaveTime = 27;
long QuarksTime = 41;
long QuarksLeaveTime = 44;
long AtomTime = 57;
long AtomLeaveTime = 59;
long GridTime = 69;
long GridLeaveTime = 70;
long ScrewTime = 73;
long DanceTimeV1 = 81;
long DanceTimeV2 = 89;
long DanceTimeV3 = 96;
long DanceTimeV4 = 103;
long RobotBlowTime = 106;
long BackScrewTime = 109;
long BackAtomTime = 112;
long BackQuarksTime = 116;
long BackSpaceTime = 120;
long TatataTime = 132;
long DadaTime = 140;
long EndTime = 145;

Double_t facY; //factor for R2 in ellipse
TLine *proton;
TLine *blei;
TEllipse *boost;
TMarker *boost_ps;
TEllipse *ps;
TLine *ps_sps;
TEllipse *sps;
TLine *sps_lhc_c;
TLine *sps_lhc_cc;
TEllipse *lhc;
Int_t mColor;
Int_t mColorInvi;
Int_t bg;
struct timeval time_start;

typedef TColorGradient::Point point_type;
//______________________________________________________________________
struct Point {
  Double_t x;
  Double_t y;
  
  Point()
	 : x(0.), y(0.)
  {
  }
  
  Point(Double_t x, Double_t y)
	 : x(x), y(y)
  {
  }
};
//______________________________________________________________________
struct vec3 {
  Double_t x;
  Double_t y;
  Double_t z;
  
  vec3()
	 : x(0.), y(0.), z(0.)
  {
  }
  
  vec3(Double_t x, Double_t y, Double_t z)
	 : x(x), y(y), z(z)
  {
  }
};
//_______________________________________________________________________
struct Marker {
 TMarker *m;
 Double_t t;  //gives the parametrization parameter
 Int_t state;    //gives the current place of the marker
				 //0 proton, 1 boost, 2 ps, 3 ps_sps, 4 sps, 5 sps_lhc_c, 6 sps_lch_cc, 7 lhc
 bool type;  //0: läuft clockwise im lhc, 1: läuft counter clockwise im lhc
};
//______________________________________________________________________	
struct LuckyRobot {
  TEllipse *armr;
  TEllipse *arml;
  TEllipse *bauch;
  TArrow *antenne1;
  TArrow *antenne2;
  TMarker *augel;
  TMarker *auger;
  TMarker *nase;
  Double_t x;
  Double_t y;
  Int_t color;
  
  LuckyRobot(Double_t x, Double_t y, Int_t color)
	 :x(x), y(y), color(color)
  {
	 armr = new TEllipse(x+0.053,y+0.05,0.04,0.01,0,360,0);
	 armr->SetFillColor(color);
	 armr->SetLineColor(color);
	 
	 arml = new TEllipse(x-0.053,y+0.05,0.04,0.01,0,360,0);
	 arml->SetFillColor(color);
	 arml->SetLineColor(color);
	 
	 bauch = new TEllipse(x,y,0.04741379,0.1255319,5,360,0);
	 bauch->SetFillColor(color);
	 bauch->SetLineColor(color);
	 bauch->Draw();
	 
	 antenne1 = new TArrow(x+0.017,y+0.12,x+0.03,y+0.18,0.03,"|>");
	 antenne1->SetFillColor(color);
	 antenne1->SetFillStyle(1001);
	 antenne1->SetLineColor(color);

	 antenne2 = new TArrow(x-0.017,y+0.1,x-0.034,y+0.16,0.03,"|>");
	 antenne2->SetFillColor(color);
	 antenne2->SetFillStyle(1001);
	 antenne2->SetLineColor(color);

	 augel = new TMarker(x-0.013,y+0.075,4);
	 auger = new TMarker(x+0.0158,y+0.08,4);
	 nase = new TMarker(x,y+0.04,23);
  }
};
//_______________________________________________________________________
struct Quark {
  TEllipse *qaround;
  TEllipse *qtopleft;
  TEllipse *qtopright;
  TEllipse *qbottom;
  TLine *lleft;
  TLine *lright;
  TLine *ltop;
  Double_t x;
  Double_t y;
  Double_t size;
  
  Quark(Double_t x, Double_t y, Double_t size)
	 : x(x), y(y), size(size)
  {
	 qaround = new TEllipse  (x,            y,             size*0.1,     size*0.1*facY,0,360,0); 
	 qtopleft = new TEllipse (x-size*0.05,  y+size*0.04,   size*0.03,    size*0.04*facY,0,360,0);
	 qtopright = new TEllipse(x+size*0.05,  y+size*0.04,   size*0.03,    size*0.04*facY,0,360,0);
	 qbottom = new TEllipse  (x,            y-size*0.08,   size*0.03,    size*0.04*facY,0,360,0);
	 ltop = new TLine(x-size*0.02,y+size*0.04,x+size*0.02,y+size*0.04);
	 ltop->SetLineWidth(2);
	 lleft = new TLine(x-size*0.02,y-size*0.035,x-size*0.035,y);
	 lleft->SetLineWidth(2);      
	 lright = new TLine(x+size*0.02,y-size*0.035,x+size*0.035,y);
	 lright->SetLineWidth(2); 
  }
};
//______________________________________________________________________
struct robot {
	TBox *oberarm1;
	TBox *oberarm2;
	TBox *ellbogen1;
	TBox *ellbogen2;
	TBox *unterarm1;
	TBox *unterarm2;
	TBox *hand1;
	TBox *hand2;
	TBox *bein1;
	TBox *bein2;
	TBox *fuss1;
	TBox *fuss2;
	TBox *kopf;
	TBox *koerper;
	TBox *hals;
	TMarker *auge1;
	TMarker *auge2;
	TEllipse *mund;
	Double_t x;
	Double_t y;

	robot(float x, float y):x(x),y(y)
	{
		oberarm1 = new TBox(x+0.09,y+0.48,x+0.17,y+0.53);
		oberarm2= new TBox(x-0.09,y+0.48,x-0.17,y+0.53);
		ellbogen1= new TBox(x+0.175,y+0.48,x+0.21,y+0.53);
		ellbogen2= new TBox(x-0.175,y+0.48,x-0.21,y+0.53);
		unterarm1= new TBox(x+0.175,y+0.53,x+0.21,y+0.63);
		unterarm2= new TBox(x-0.175,y+0.53,x-0.21,y+0.63);
		hand1= new TBox(x+0.165,y+0.64,x+0.215,y+0.69);
		hand2= new TBox(x-0.165,y+0.64,x-0.215,y+0.69);
		bein1= new TBox(x+0.04,y+0.06,x+0.08,y+0.27);
		bein2= new TBox(x-0.04,y+0.06,x-0.08,y+0.27);
		fuss1= new TBox(x+0.04,y,x+0.12,y+0.05);
		fuss2= new TBox(x-0.04,y,x-0.12,y+0.05);
		kopf= new TBox(x-0.05,y+0.61,x+0.05,y+0.72);
		koerper= new TBox(x-0.08,y+0.28,x+0.08,y+0.56);
		hals= new TBox(x-0.03,y+0.57,x+0.03,y+0.60);
	    auge1 = new TMarker(0.4798995,0.6916376,4);
	    auge2 = new TMarker(0.5125628,0.6933798,4);
	    mund = new TEllipse(0.5,0.6437282,0.02386935,0.01655052,180,360,0);
	}
};

void MarkerStep(Marker *m);
Point LineStep(Double_t next_t, TLine *line, bool direction);
Point EllipseStep(Double_t next_t, TEllipse *ellipse, bool direction);
Double_t Dist(Point a, Point b);
void Particles();
void DrawCollider();
void Stars();
void AnimateStars(std::vector <TMarker *> marker, Int_t sec);
void AnimateStarsLeave(std::vector <TMarker *> marker, Int_t sec);
void DrawQuark(Quark q);
void Quarks(std::vector<TMarker *> marker);
void MoveQuark(Quark q, Double_t dx, Double_t dy);
void DeleteQuark(Quark q);
void Proton();
void PlopEllipse(TEllipse e);
void Grid();
Point ProjectToPlane(vec3 p);
vec3 Rotate(vec3 v, Double_t alpha);
void ScrewIt();
void LuckyRobots();
void MoveLuckyRobot(LuckyRobot r, Double_t dx, Double_t dy);
void DrawLuckyRobot(LuckyRobot r);
void LuckyRobotsDance(Int_t i, std::vector<LuckyRobot> &robots);
long Time();
void AnimateParticles(std::vector<Marker> markers);
void drawrobot(robot heinz);
void Robot();
void Back();
std::vector<TMarker *> BackStars(Int_t sec);
void MoveBox(TBox *b, Double_t dx, Double_t dy);
void BackAnimateStars(std::vector <TMarker *> marker, Int_t sec);
void BackAnimateStarsLeave(std::vector <TMarker *> marker, Int_t sec);
void Monolit();
vec3 moRotate(vec3 v, Double_t alpha);

//______________________________________________________________________
int main(int argc, char ** argv)
{
   TApplication app("HeinzImWeltraum", &argc, argv);
   gStyle->SetCanvasPreferGL(kTRUE);
   const Color_t colorIndices[3] = {kBlack, TColor::GetColor(50,0,50)};
   const Double_t lengths[2] = {0.7, 1.};
   TLinearGradient *grad = new TLinearGradient(1030, 2, lengths, colorIndices);
   const point_type start(0., 0.);
   const point_type end(0., 1.);
   grad->SetStartEnd(start, end);
   bg = 1030;
   
   //make white transparent
   gROOT->GetColor(0)->SetAlpha(0.5);
   //make transparent color
   gROOT->GetColor(kMagenta)->SetAlpha(0.);
   
   TCanvas *c1 = new TCanvas("2000Heinz", "2000Heinz", 0, 49, screenX, screenY);
   screenX = c1->GetWw();
   screenY = c1->GetWh();
   facY = (Double_t)screenX/(Double_t)screenY;
   
   gettimeofday(&time_start, NULL);
   
   c1->Range(0,0,1,1);
   c1->SetFillColor(bg);
   c1->SetFillStyle(4000);
   c1->SetBorderMode(0);
   c1->SetBorderSize(2);
   c1->SetFrameBorderMode(0);
   DrawCollider();
   Particles();
   Stars(); //calls Quarks()
   Proton();
   Grid();
   ScrewIt();
   Robot();
   Back();
   app.Run();
}
//______________________________________________________________________
long Time()
{
    struct timeval end;
    gettimeofday(&end, NULL);
    long seconds  = end.tv_sec  - time_start.tv_sec;
    long useconds = end.tv_usec - time_start.tv_usec;
    long mtime = seconds * 1000 + useconds/1000.0 + 0.5;
    return mtime;
}
//______________________________________________________________________
void DrawCollider()
{   
   const Color_t colorIndices[2] = {kMagenta, kWhite};
   const Double_t lengths[3] = {0.2, 1.};
   TRadialGradient *grad = new TRadialGradient(1001, 2, lengths, colorIndices);
   grad->SetRadialGradient(TColorGradient::Point(0.5,0.5), 0.5);
   Int_t gradient = 1001;
   proton = new TLine(0.3505747,0.2723404,0.3856784,0.244);  //x1,y1,x2,y2
   proton->SetLineColor(0);
   proton->SetLineWidth(2);
   proton->Draw();

   blei = new TLine(0.3764368,0.2829787,0.3831658,0.246);
   blei->SetLineColor(0);
   blei->SetLineWidth(2);
   blei->Draw();   
   
   boost = new TEllipse(0.420977,0.2542553,0.03735632,0.02446809); //x1, y1, r1, r2
   boost->SetLineWidth(4);
   boost->SetLineColor(0);
   boost->SetFillStyle(0);
   boost->Draw();
   
   ps = new TEllipse(0.5251437,0.2765957,0.07255747,0.04042553);
   ps->SetLineWidth(0);
   ps->SetLineColor(kMagenta);
   ps->SetFillColor(gradient);
   ps->Draw();

   ps_sps = new TLine(0.4547739,0.268,0.3542714,0.5021277);
   ps_sps->SetLineColor(0);
   ps_sps->SetLineWidth(2);
   ps_sps->Draw();

   TRadialGradient *grad2 = new TRadialGradient(1002, 2, lengths, colorIndices);
   grad2->SetRadialGradient(TColorGradient::Point(0.35,0.5), 0.5);
   Int_t gradient2 = 1002;

   sps = new TEllipse(0.4978448,0.5117021,0.1472701,0.06276596);
   sps->SetLineWidth(0);
   sps->SetLineColor(kMagenta);
   sps->SetFillStyle(4000);
   sps->SetFillColor(gradient2);
   sps->Draw();

   sps_lhc_c = new TLine(0.3781407,0.4744681,0.3103015,0.518);
   sps_lhc_c->SetLineColor(0);
   sps_lhc_c->SetLineWidth(2);
   sps_lhc_c->Draw();

   sps_lhc_cc = new TLine(0.5791457,0.564,0.6821608,0.5595745);
   sps_lhc_cc->SetLineColor(0);
   sps_lhc_cc->SetLineWidth(2);
   sps_lhc_cc->Draw();
   
   lhc = new TEllipse(0.4590517,0.6095745,0.2406609,0.1138298);
   lhc->SetLineWidth(4);
   lhc->SetLineColor(0);
   lhc->SetFillStyle(0);
   lhc->Draw();
}
//______________________________________________________________________
void Stars()
{
   TVirtualPad *oldpad = gPad;
   TPad *stars = new TPad("stars", "stars", 0,0,1,1);
   stars->SetFillStyle(0);
   stars->SetFillColor(0);
   stars->Draw();
   stars->cd();
   
   Int_t nStars = 30;
   Double_t x, y;
   std::vector < TMarker * > marker;
   for(Int_t i=0; i<floor((Double_t)nStars/(Double_t)2); i++)
   {
      x = (Double_t)rand()/RAND_MAX;
      y = (Double_t)rand()/RAND_MAX;
      
      TMarker *s = new TMarker(x, y, 29);
      s->SetMarkerSize((Double_t)rand()/RAND_MAX/2+2);
      s->SetMarkerColor(TColor::GetColor((Float_t)rand()/RAND_MAX, (Float_t)rand()/RAND_MAX, (Float_t)rand()/RAND_MAX));
      s->Draw();
      
      x = (Double_t)rand()/RAND_MAX;
      y = (Double_t)rand()/RAND_MAX;
      
      TMarker *c = new TMarker(x, y, 29);
      c->SetMarkerSize((Double_t)rand()/RAND_MAX/2+2);
      c->SetMarkerColor(TColor::GetColor((Float_t)rand()/RAND_MAX, (Float_t)rand()/RAND_MAX, (Float_t)rand()/RAND_MAX));
      c->Draw();
      
      marker.push_back(s);
      marker.push_back(c);
   }
   
   AnimateStars(marker, StarsTime*1000);
   oldpad->Clear();
   oldpad->cd();
   
   Quarks(marker);
}
//______________________________________________________________________
void AnimateStars(std::vector <TMarker *> marker, Int_t sec) 
{
   while (Time() < sec)
   {
      for(Int_t j=0; j<marker.size(); j++)
      {
         marker[j]->SetMarkerSize(marker[j]->GetMarkerSize()+(Double_t)6/(Double_t)(sec/1000));
      }
      gPad->Modified(kTRUE);
      gPad->Update();
   }
}
//______________________________________________________________________
void AnimateStarsLeave(std::vector <TMarker *> marker, Int_t sec)
{
   while (Time() < sec)
   {
      for(Int_t j=0; j<marker.size(); j++)
      {
         marker[j]->SetX(marker[j]->GetX()*1.03);
         marker[j]->SetY(marker[j]->GetY()*1.03);
      }
      gPad->Modified(kTRUE);
      gPad->Update();
   }
   
   //marker vorsichtshalber löschen
   for(Int_t i=0; i<marker.size(); i++)
   {
      marker[i]->Delete();
   }
   marker.clear();
}
//______________________________________________________________________
void MarkerStep(Marker *marker)
{
   Double_t stepsize = 0;
   Point nextpos;
   Double_t start_boost = 1.25;
   Double_t end_boost = 4;
   Double_t start_ps = 0.9;
   Double_t end_ps = 2.9;
   Double_t start_sps = 1;
   Double_t end_sps_clockwise = 2.8;
   Double_t end_sps_cclockwise = 3.6;
   Double_t start_lhc_clockwise = 0.75;
   Double_t start_lhc_cclockwise = 1.9;
   Double_t lhc_rounds = 2;
   Double_t lineSpeed = 0.05;
   Double_t ellipseSpeed = 0.06;
   switch (marker->state)
   {
      case -1: //warteschleife
         marker->t = marker->t+1;
         if (marker->t == 0)
         {
            marker->state = 0;
         }
         break;
      case 0: //proton
         stepsize = lineSpeed;
         nextpos = LineStep(marker->t+stepsize, proton, true);
         marker->t = marker->t+stepsize;
         marker->m->SetX(nextpos.x);
         marker->m->SetY(nextpos.y);
         if (marker->t >=1)
         {
            marker->state = 1;
            marker->t = TMath::Pi()*start_boost;
         }
         break;
      case 1: //boost
         stepsize = ellipseSpeed;
         nextpos = EllipseStep(marker->t+stepsize, boost, true);
         marker->t = marker->t+stepsize;
         marker->m->SetX(nextpos.x);
         marker->m->SetY(nextpos.y);
         if (marker->t >= TMath::Pi()*end_boost)
         {
            marker->state = 2;
            marker->t = start_ps*TMath::Pi();
         }
         break;
      case 2: //ps
         stepsize = ellipseSpeed;
         nextpos = EllipseStep(marker->t+stepsize, ps, false);
         marker->t = marker->t+stepsize;
         marker->m->SetX(nextpos.x);
         marker->m->SetY(nextpos.y);
         if (marker->t >= end_ps*TMath::Pi()) {
            marker->state = 3;
            marker->t = 0;
         }
         break;
      case 3: //ps_sps
         stepsize = lineSpeed;
         nextpos = LineStep(marker->t+stepsize, ps_sps, true);
         marker->t = marker->t+stepsize;
         marker->m->SetX(nextpos.x);
         marker->m->SetY(nextpos.y);
         if (marker->t >= 1) {
            marker->state = 4;
            marker->t = TMath::Pi()*start_sps;
         }
         break;
      case 4: //sps
         stepsize = ellipseSpeed;
         nextpos = EllipseStep(marker->t+stepsize, sps, false);
         marker->t = marker->t+stepsize;
         marker->m->SetX(nextpos.x);
         marker->m->SetY(nextpos.y);
         if ((marker->type)&&(marker->t >= end_sps_clockwise*TMath::Pi())) { //type = 0-> clockwise
            marker->state = 5;
            marker->t = 0;
         }
         if ((!marker->type)&&(marker->t >= end_sps_cclockwise*TMath::Pi())) {
            marker->state = 6;
            marker->t = 0;
         }
         break;
      case 5: //sps_lhc_c
         stepsize = lineSpeed;
         nextpos = LineStep(marker->t+stepsize, sps_lhc_c, true);
         marker->t = marker->t+stepsize;
         marker->m->SetX(nextpos.x);
         marker->m->SetY(nextpos.y);
         if (marker->t >= 1) {
            marker->state = 7;
            marker->t = start_lhc_clockwise*TMath::Pi();
         }
         break;
      case 6: //sps_lhc_cc
         stepsize = lineSpeed;
         nextpos = LineStep(marker->t+stepsize, sps_lhc_cc, true);
         marker->t = marker->t+stepsize;
         marker->m->SetX(nextpos.x);
         marker->m->SetY(nextpos.y);
         if (marker->t >= 1) {
            marker->state = 8;
            marker->t = start_lhc_cclockwise*TMath::Pi();
         }
         break;
      case 7: //lhc clockwise
         stepsize = ellipseSpeed;
         nextpos = EllipseStep(marker->t+stepsize, lhc, false);
         marker->t = marker->t+stepsize;
         marker->m->SetX(nextpos.x);
         marker->m->SetY(nextpos.y);
         if (marker->t >= lhc_rounds*TMath::Pi()) {
            marker->state = 9;
         }
         break;
      case 8: //lhc counter clockwise
         stepsize = ellipseSpeed;
         nextpos = EllipseStep(marker->t+stepsize, lhc, true);
         marker->t = marker->t+stepsize;
         marker->m->SetX(nextpos.x);
         marker->m->SetY(nextpos.y);
         if (marker->t >= lhc_rounds*TMath::Pi()) {
            marker->state = 10;
         }
         break;
      case 9: //lhc clockwise
         stepsize = ellipseSpeed;
         nextpos = EllipseStep(marker->t+stepsize, lhc, false);
         marker->t = marker->t+stepsize;
         if(marker->t >= 2*TMath::Pi())
            marker->t = marker->t-2*TMath::Pi();
         marker->m->SetX(nextpos.x);
         marker->m->SetY(nextpos.y);
         break;
      case 10: //lhc counter clockwise
         stepsize = ellipseSpeed;
         nextpos = EllipseStep(marker->t+stepsize, lhc, true);
         marker->t = marker->t+stepsize;
         if(marker->t >= 2*TMath::Pi())
            marker->t = marker->t-2*TMath::Pi();
         marker->m->SetX(nextpos.x);
         marker->m->SetY(nextpos.y);
         break;
      case 11: //Collisions
         marker->t = marker->t + 0.1;
         marker->m->SetMarkerSize(floor(marker->t));
         break;
   }
}
//______________________________________________________________________
Point LineStep(Double_t next_t, TLine *line, bool direction)
{//parameter of the current marker, the line
   if (direction) //von (x1,y1) nach (x2,y2)
      return(Point(line->GetX1()*(1-next_t)+line->GetX2()*next_t, line->GetY1()*(1-next_t)+line->GetY2()*next_t));
   else
      return(Point(line->GetX2()*(1-next_t)+line->GetX1()*next_t, line->GetY2()*(1-next_t)+line->GetY1()*next_t));
}
//______________________________________________________________________
Point EllipseStep(Double_t next_t, TEllipse *ellipse, bool direction)
{
   if (direction) //counter clockwise
      return (Point(ellipse->GetR1()*TMath::Cos(next_t)+ellipse->GetX1(), ellipse->GetR2()*TMath::Sin(next_t)+ellipse->GetY1()));
   else
      return (Point(ellipse->GetR1()*TMath::Cos(next_t)+ellipse->GetX1(), (-1)*ellipse->GetR2()*TMath::Sin(next_t)+ellipse->GetY1()));
}
//______________________________________________________________________
Double_t Dist(Point a, Point b)
{
   return(TMath::Sqrt((a.x-b.x)*(a.x-b.x) + (a.y-b.y)*(a.y-b.y)));
}
//______________________________________________________________________
void Particles()
{
   Int_t nmarker = 40; //mind. 3
   mColor = TColor::GetColor(255, 103, 43);
   std::vector <Marker> markers;
   
   for (Int_t k=0; k<3; k++) {
      TMarker *tmarker = new TMarker(proton->GetX1(), proton->GetY1(), 20);
      tmarker->SetMarkerColor(mColor);
      tmarker->SetMarkerSize(1);
      Marker marker;
      marker.m = tmarker;
      marker.state = -1;
      marker.t = TMath::Floor((-1)*(Double_t)rand()/RAND_MAX*5);
      marker.m->Draw();
      marker.type = (k%2 == 0);
      
      markers.push_back(marker);
   }
   
   for (Int_t k=0; k<nmarker; k++) {
      TMarker *tmarker = new TMarker(proton->GetX1(), proton->GetY1(), 20);
      tmarker->SetMarkerColor(mColor);
      tmarker->SetMarkerSize(1);
      Marker marker;
      marker.m = tmarker;
      marker.state = -1;
      marker.t = TMath::Floor((-1)*(Double_t)rand()/RAND_MAX*800);
      marker.m->Draw();
      marker.type = (k%2 == 0);
      
      markers.push_back(marker);
   }
   gPad->Modified(kTRUE);
   gPad->Update();
   AnimateParticles(markers);
}
//______________________________________________________________________
void AnimateParticles(std::vector<Marker> markers) {
   TLatex *tex = 0; 
   Double_t alpha = 0;
   Int_t col;
   while (Time()<ParticlesTime*1000) 
   {
      if ((Time()>ShowExperiments*1000)&&(tex == 0))
      {
         col = TColor::GetColor(191,177,204);
         gROOT->GetColor(col)->SetAlpha(alpha);
         tex = new TLatex(0.4258794,0.7446809,"CMS");
         tex->SetTextColor(col);
         tex->Draw();
            tex = new TLatex(0.1633166,0.5170213,"ALICE");
         tex->SetTextColor(col);
         tex->Draw();
            tex = new TLatex(0.6758794,0.5170213,"LHCb");
         tex->SetTextColor(col);
         tex->Draw();
            tex = new TLatex(0.4170854,0.5148936,"ATLAS");
         tex->SetTextColor(col);
         tex->Draw();
            tex = new TLatex(0.3329146,0.5702128,"NA62");
         tex->SetTextColor(col);
         tex->SetTextSize(0.03);
         tex->Draw();
      }
      if ((Time()>ShowExperiments*1000)&&(tex != 0))
      {
         if(alpha<1)
         {
            alpha = alpha + 0.1;
            gROOT->GetColor(col)->SetAlpha(alpha);
         }
      }
      for(UInt_t k=0; k<markers.size(); k++)
      {
         MarkerStep(&markers[k]);
         if((markers[k].state == 11)&&(markers[k].t>15)) {
            markers[k].m->Delete();
            markers.erase(markers.begin()+k);
         }
      }
      for(UInt_t l=0; l<markers.size(); l++)
      {
         for(UInt_t m=0; m<markers.size(); m++)
         {
            if(((markers[l].state==9)&&(markers[m].state==10))||((markers[m].state==9)&&(markers[l].state==10)))
            {
               if((TMath::Abs(markers[l].m->GetX()-markers[m].m->GetX())<0.01)&&(TMath::Abs(markers[l].m->GetY()-markers[m].m->GetY())<0.01))
               {
                  markers[l].m->SetMarkerStyle(29);
                  markers[m].m->SetMarkerStyle(30);
                  markers[m].m->SetMarkerColor(TColor::GetColor(43,195,255));
                  markers[l].m->SetMarkerSize(5);
                  markers[m].m->SetMarkerSize(1);
                  markers[l].state = 11;
                  markers[m].state = 11;
                  markers[l].t = 5;
                  markers[m].t = 1;
                  markers[m].m->Draw();
               }
            }
         }
      }
      gPad->Modified(kTRUE);
      gPad->Update();
   }
}
//______________________________________________________________________
void DrawQuark(Quark q)
{
   q.qaround->Draw();
   q.qtopleft->Draw();
   q.qtopright->Draw();
   q.qbottom->Draw();
   q.lleft->Draw();
   q.lright->Draw();
   q.ltop->Draw();
}
//______________________________________________________________________
void MoveQuark(Quark q, Double_t dx, Double_t dy)
{
   q.qaround->SetX1(q.qaround->GetX1()+dx);
   q.qaround->SetY1(q.qaround->GetY1()+dy);
   q.qtopleft->SetX1(q.qtopleft->GetX1()+dx);
   q.qtopleft->SetY1(q.qtopleft->GetY1()+dy);
   q.qtopright->SetX1(q.qtopright->GetX1()+dx);
   q.qtopright->SetY1(q.qtopright->GetY1()+dy);
   q.qbottom->SetX1(q.qbottom->GetX1()+dx);
   q.qbottom->SetY1(q.qbottom->GetY1()+dy);
   q.lleft->SetX1(q.lleft->GetX1()+dx);
   q.lleft->SetX2(q.lleft->GetX2()+dx);
   q.lleft->SetY1(q.lleft->GetY1()+dy);
   q.lleft->SetY2(q.lleft->GetY2()+dy);
   q.lright->SetX1(q.lright->GetX1()+dx);
   q.lright->SetX2(q.lright->GetX2()+dx);
   q.lright->SetY1(q.lright->GetY1()+dy);
   q.lright->SetY2(q.lright->GetY2()+dy);
   q.ltop->SetX1(q.ltop->GetX1()+dx);
   q.ltop->SetX2(q.ltop->GetX2()+dx);
   q.ltop->SetY1(q.ltop->GetY1()+dy);
   q.ltop->SetY2(q.ltop->GetY2()+dy);
}
//______________________________________________________________________
void DeleteQuark(Quark q)
{
   q.qaround->Delete();
   q.qtopleft->Delete();
   q.qtopright->Delete();
   q.qbottom->Delete();
   q.lleft->Delete();
   q.lright->Delete();
   q.ltop->Delete();
}

Int_t qRgrad;
Int_t qGgrad;
Int_t qBgrad;
Int_t qBGgrad;
//______________________________________________________________________
void Quarks(std::vector<TMarker *>marker)
{
   Int_t qR = TColor::GetColor(250,71,0);
   Int_t qG = TColor::GetColor(10,78,7);
   Int_t qB = TColor::GetColor(59,0,209);
   Int_t qBG = TColor::GetColor(180,153,247);
   Int_t qBGo = TColor::GetColor(180,153,237);

   gROOT->GetColor(qBGo)->SetAlpha(0.);
   gROOT->GetColor(qBG)->SetAlpha(0.6);
   
   Color_t colorIndices[2] = {qR, kBlack};
   Double_t lengths[2] = {0., 1.};
   TRadialGradient *grad = new TRadialGradient(1000+qR, 2, lengths, colorIndices);
   grad->SetRadialGradient(TColorGradient::Point(0.5,0.5), 0.5);
   qRgrad = 1000+qR;
   
   colorIndices[0] = qG;
   grad = new TRadialGradient(1000+qG, 2, lengths, colorIndices);
   grad->SetRadialGradient(TColorGradient::Point(0.5,0.5), 0.5);
   qGgrad = 1000+qG;
   
   colorIndices[0] = qB;
   grad = new TRadialGradient(1000+qB, 2, lengths, colorIndices);
   grad->SetRadialGradient(TColorGradient::Point(0.5,0.5), 0.5);
   qBgrad = 1000+qB;
   
   colorIndices[0] = qBG;
   colorIndices[1] = qBGo;
   grad = new TRadialGradient(1000+qBG, 2, lengths, colorIndices);
   grad->SetRadialGradient(TColorGradient::Point(0.5,0.5), 0.5);
   qBGgrad = 1000+qBG;
   
   Int_t mfak = 120;
   
   Int_t nQuarks = 7;
   std::vector<Quark> Quarks;
   std::vector<Double_t> Directions;

   for(Int_t i=0; i<nQuarks-TMath::Floor(nQuarks/2); i++)
   {
      Quark q = Quark((Double_t)rand()/RAND_MAX, (Double_t)rand()/RAND_MAX, (Double_t) (i%3+1)*0.33);
      q.qtopleft->SetFillColor(qRgrad);
      q.qtopleft->SetLineColor(kBlack);
      q.qtopright->SetFillColor(qGgrad);
      q.qtopright->SetLineColor(kBlack);
      q.qbottom->SetFillColor(qBgrad);
      q.qbottom->SetLineColor(kBlack);
      q.qaround->SetFillColor(qBGgrad);
      q.qaround->SetLineColor(kMagenta);
      q.qaround->SetFillStyle(4000);
      Quarks.push_back(q);
      DrawQuark(q);
   }
   
   //smallone in the middle
   Quark singleq = Quark(0.5, 0.5, (Double_t) 1);
   singleq.qtopleft->SetFillColor(qRgrad);
   singleq.qtopleft->SetLineColor(kBlack);
   singleq.qtopright->SetFillColor(qGgrad);
   singleq.qtopright->SetLineColor(kBlack);
   singleq.qbottom->SetFillColor(qBgrad);
   singleq.qbottom->SetLineColor(kBlack);
   singleq.qaround->SetFillColor(qBGgrad);
   singleq.qaround->SetLineColor(kMagenta);
   DrawQuark(singleq);
   
   for(Int_t i=0; i<TMath::Floor(nQuarks/2); i++)
   {
      Quark q = Quark((Double_t)rand()/RAND_MAX, (Double_t)rand()/RAND_MAX, (Double_t) (i%2+2)*0.6);
      q.qtopleft->SetFillColor(qRgrad);
      q.qtopleft->SetLineColor(kBlack);
      q.qtopright->SetFillColor(qGgrad);
      q.qtopright->SetLineColor(kBlack);
      q.qbottom->SetFillColor(qBgrad);
      q.qbottom->SetLineColor(kBlack);
      q.qaround->SetFillColor(qBGgrad);
      q.qaround->SetLineColor(kMagenta);
      Quarks.push_back(q);
      DrawQuark(q);
   }

   Quarks.push_back(singleq);
   
   gPad->SetFillColor(1);   
   TImage *img = TImage::Open("CMSHiggs.png");
   if (img) {
      img->SetConstRatio(kFALSE);
      img->Draw("");
   }
   for(Int_t i=0; i<Quarks.size(); i++)
      DrawQuark(Quarks[i]);
   for(Int_t i=0; i<marker.size(); i++)
	  marker[i]->Draw();

   AnimateStarsLeave(marker, StarsLeaveTime*1000);
   
   for(Int_t j=0; j<(Quarks.size()-1)*2; j++)
   {
      Directions.push_back(0.0);
   }
   
   Int_t kmax = 40;
   
   while (Time() < QuarksTime * 1000)
   {
      for(Int_t j=0; j<(Quarks.size()-1)*2; j=j+1)
      {
         Directions[j] = (Double_t)rand()/RAND_MAX/mfak-0.49/mfak;
      }
      for(Int_t k=0; k<=kmax; k++)
      {
         for(UInt_t l=0; l<Quarks.size()-1; l++)
         {
            MoveQuark(Quarks[l], Directions[2*l]*TMath::Sin(k*TMath::Pi()/kmax)*TMath::Sin(k*TMath::Pi()/kmax)*(Quarks[l].size+0.7), Directions[2*l+1]*TMath::Sin(k*TMath::Pi()/kmax)*TMath::Sin(k*TMath::Pi()/kmax)*(Quarks[l].size+0.7));
         }
         gPad->Modified(kTRUE);
         gPad->Update();
      }
   }

   //Ausm Bild Laufen lassen
   Int_t col1 = TColor::GetColor(90,90,90);
   Int_t col2 = TColor::GetColor(135,135,135);
   
   Color_t colIndices[2] = {col1, kWhite};
   Double_t len[2] = {0.5, 1.};
   grad = new TRadialGradient(1000+col1, 2, len, colIndices);
   grad->SetRadialGradient(TColorGradient::Point(0.7,0.4), 0.6);
   Int_t metalGrad = 1000+col1;

   gROOT->GetColor(metalGrad)->SetAlpha(0.);
  
   for(Int_t j=0; j<(Quarks.size()-1)*2; j=j+2)
   {
      Double_t x = Quarks[j/2].x-0.5;
      Double_t y = Quarks[j/2].y-0.5;
      Directions[j] = x*1/TMath::Sqrt(x*x+y*y)*0.02;
      Directions[j+1] = y*1/TMath::Sqrt(x*x+y*y)*0.02;
   }

   kmax = 10;

   while (Time() < QuarksLeaveTime * 1000)
   {
      for(Int_t k=0; k<=kmax; k++)
      {
         for(UInt_t l=0; l<Quarks.size()-1; l++)
         {
            MoveQuark(Quarks[l], Directions[2*l]*(Quarks[l].size+0.4), Directions[2*l+1]*(Quarks[l].size+0.4));
         }
         gPad->Modified(kTRUE);
         gPad->Update();
      }
   }
   
   for(Int_t i=0; i<Quarks.size(); i++)
      DeleteQuark(Quarks[i]);
      
   img->Delete();
}
//______________________________________________________________________
Int_t metalGrad;

void Proton() {
   gPad->Clear();
   gPad->SetFillColor(bg);
   gPad->SetFillStyle(4000);
   
   Int_t col1 = TColor::GetColor(90,90,90);
   Int_t col2 = TColor::GetColor(135,135,135);
   
   Color_t colIndices[2] = {col1, kWhite};
   Double_t len[2] = {0.5, 1.};
   TRadialGradient *grad = new TRadialGradient(1000+col1, 2, len, colIndices);
   grad->SetRadialGradient(TColorGradient::Point(0.7,0.4), 0.6);
   metalGrad = 1000+col1;
   
   gROOT->GetColor(metalGrad)->SetAlpha(0.);
   
   TEllipse *Proton = new TEllipse(0.5, 0.5, 0.1, 0.1*facY, 0, 360, 0);
   Proton->SetFillColor(metalGrad);
   Proton->SetLineColor(kMagenta);
   Proton->Draw();
   
   Double_t dist_bahn_to_proton = 0.6;
   TEllipse *Bahn = new TEllipse(0.5, 0.5, dist_bahn_to_proton+0.1, (dist_bahn_to_proton+0.1)*facY, 0, 360, 0);
   Bahn->SetLineWidth(3);
   Bahn->SetLineColor(kWhite);
   Int_t BahnColor = TColor::GetColor(67, 90, 122);
   gROOT->GetColor(BahnColor)->SetAlpha(0.);
   Bahn->SetFillColor(BahnColor);
   //Bahn->SetFillStyle(0);
   Bahn->Draw();
   
   Int_t elColor = TColor::GetColor(250, 72, 22);
   Int_t elShadow = TColor::GetColor(135, 12, 3);
   TMarker *ElShadow = new TMarker(0.5+dist_bahn_to_proton+0.1, 0.5, 20);
   ElShadow->SetMarkerColor(elShadow);
   ElShadow->SetMarkerSize(3);
   ElShadow->Draw();
   TMarker *El = new TMarker(0.5+dist_bahn_to_proton+0.1, 0.5, 20);
   El->SetMarkerColor(elColor);
   El->SetMarkerSize(2);   
   El->Draw();
   
   Double_t t = 0;
   Double_t stepsize = 0.02;
   Point nextpos;
   
   //Shrink Proton
   while(Time()<AtomTime*1000)
   {
     if(Proton->GetR1()>0.)
     {
		  Proton->SetR1(Proton->GetR1()-0.0001);
		  Proton->SetR2(Proton->GetR2()-0.0001*facY);
	  }

	  if(Bahn->GetR1()>0.03)
	  {
		  Bahn->SetR1(Bahn->GetR1()-0.0009);
		  Bahn->SetR2(Bahn->GetR2()-0.0009*facY);
	  }

      t = t+stepsize;
      nextpos = EllipseStep(t, Bahn, true);

      El->SetX(nextpos.x);
      El->SetY(nextpos.y);

      ElShadow->SetX(nextpos.x);
      ElShadow->SetY(nextpos.y);

      gPad->Modified(kTRUE);
      gPad->Update();
   }
   
   //Shrink and fade metal in
   Float_t R, G, B;
   gROOT->GetColor(BahnColor)->GetRGB(R, G, B);
   while(Time()<AtomLeaveTime*1000)
   {  
      Double_t t2 = (Double_t)Time()/(Double_t)(AtomLeaveTime*1000);
      gROOT->GetColor(elColor)->SetAlpha(1-t2);
      gROOT->GetColor(elShadow)->SetAlpha(1-t2);
      
      //Linear interpolation between border color (white) and interior (BahnColor)
      Float_t r, g, b;
      r = (1-t2)*1+t2*R;
      g = (1-t2)*1+t2*G;
      b = (1-t2)*1+t2*B;
      TColor *lineColor = gROOT->GetColor(TColor::GetColor(r, g, b));
      lineColor->SetAlpha(0.5);
      Bahn->SetLineColor(lineColor->GetNumber());

      Double_t facProton = Proton->GetR2()/Proton->GetR1();
      
      if(Proton->GetR1()>0.)
      {
		Proton->SetR1(Proton->GetR1()-0.00015);
		Proton->SetR2(Proton->GetR2()-0.00015*facProton);
	  }

      Double_t facBahn = Bahn->GetR2()/Bahn->GetR1();

	  if(Bahn->GetR1()>0.03)
	  {
	     Bahn->SetR1(Bahn->GetR1()-0.0009);
	     Bahn->SetR2(Bahn->GetR2()-0.0009*facBahn);
	  }

      t = t+stepsize;
      nextpos = EllipseStep(t, Bahn, true);

      El->SetX(nextpos.x);
      El->SetY(nextpos.y);

      ElShadow->SetX(nextpos.x);
      ElShadow->SetY(nextpos.y);

      gPad->Modified(kTRUE);
      gPad->Update();
   }
   
   El->Delete();
   ElShadow->Delete();
   Proton->Delete();
   Bahn->Delete();
}

void PlopEllipse(TEllipse *e, Double_t endR)
{
   Double_t r;
   Double_t n = 2;
   for (Double_t t = 0; t < 10; t = t+0.1)
   {
      r = TMath::Exp((-1)*(t/n))*TMath::Sin(t)+(1-TMath::Exp((-1)*t)); //n höher-> höhere überschwingung endet bei 1, start bei 0*/
      e->SetR1(r*endR);
      e->SetR2(r*endR);
   }
}

std::vector<vec3> coords;
std::vector<Int_t> linecoords; //gives tupels of indizes of the points in coords that should be connected
//used again in Back()

Int_t FrontGrad;
Int_t BackGrad;
Int_t FrontColor;
Int_t BackColor;

//______________________________________________________________________
void Grid()
{  
   Color_t colorIndices[2] = {TColor::GetColor(189,51,74), kBlack};
   Double_t lengths[2] = {0., 1.};
   TRadialGradient *grad = new TRadialGradient(1259, 2, lengths, colorIndices);
   grad->SetRadialGradient(TColorGradient::Point(0.5,0.5), 0.4);
   Int_t FrontGrad = 1259;

   grad = new TRadialGradient(1260, 2, lengths, colorIndices);
   grad->SetRadialGradient(TColorGradient::Point(0.5,0.5), 0.2);
   Int_t BackGrad = 1260;
   
   Int_t FrontColor = TColor::GetColor(51,189,166);
   Int_t BackColor = TColor::GetColor(27,97,85);
   
   gROOT->GetColor(FrontColor)->SetAlpha(0.5);
   gROOT->GetColor(BackColor)->SetAlpha(0.5);
   
   std::vector<TEllipse *> dots;
   std::vector<TLine *> lines;
   Point p;
	
   TEllipse *Proton = new TEllipse(0.5, 0.5, 0.03, 0.03*facY);
   Proton->SetFillColor(metalGrad);
   Proton->SetLineColor(kMagenta);
   Proton->Draw();
   
   //Baue das Grid
   Double_t gridSize = 0.2;
   coords.push_back(vec3(0,gridSize,gridSize));
   coords.push_back(vec3(gridSize,0,gridSize));
   coords.push_back(vec3(0,(-1)*gridSize,gridSize));
   coords.push_back(vec3((-1)*gridSize,0,gridSize));
   
   coords.push_back(vec3((-1)*gridSize,gridSize,0));
   coords.push_back(vec3(gridSize,gridSize,0));
   coords.push_back(vec3(gridSize,(-1)*gridSize,0));
   coords.push_back(vec3((-1)*gridSize,(-1)*gridSize,0));
   
   coords.push_back(vec3(0,gridSize,(-1)*gridSize));
   coords.push_back(vec3(gridSize,0,(-1)*gridSize));
   coords.push_back(vec3(0,(-1)*gridSize,(-1)*gridSize));
   coords.push_back(vec3((-1)*gridSize,0,(-1)*gridSize));
   
   //Draw the Lines
   linecoords.push_back (9);
   linecoords.push_back (10);
   
   linecoords.push_back (10);
   linecoords.push_back (11);
   
   linecoords.push_back (11);
   linecoords.push_back (12);
   
   linecoords.push_back (12);
   linecoords.push_back (9);
   
   linecoords.push_back (12);
   linecoords.push_back (8);
   
   linecoords.push_back (12);
   linecoords.push_back (5);
   
   linecoords.push_back (11);
   linecoords.push_back (8);
   
   linecoords.push_back (11);
   linecoords.push_back (7);
   
   linecoords.push_back (10);
   linecoords.push_back (7);
   
   linecoords.push_back (10);
   linecoords.push_back (6);
   
   linecoords.push_back (9);
   linecoords.push_back (6);
   
   linecoords.push_back (9);
   linecoords.push_back (5);
   
   linecoords.push_back (4);
   linecoords.push_back (5);
   
   linecoords.push_back (4);
   linecoords.push_back (8);
   
   linecoords.push_back (3);
   linecoords.push_back (8);
   
   linecoords.push_back (3);
   linecoords.push_back (7);
   
   linecoords.push_back (2);
   linecoords.push_back (7);
   
   linecoords.push_back (2);
   linecoords.push_back (6);
   
   linecoords.push_back (1);
   linecoords.push_back (6);
   
   linecoords.push_back (1);
   linecoords.push_back (5);
   
   linecoords.push_back (4);
   linecoords.push_back (1);
   
   linecoords.push_back (3);
   linecoords.push_back (4);
   
   linecoords.push_back (2);
   linecoords.push_back (3);

   linecoords.push_back (1);
   linecoords.push_back (2);

   //Draw Lines behind Dots
   for(Int_t i=0; i<linecoords.size(); i=i+2)
   {
	  if(coords[linecoords[i]-1].z == (-1)*gridSize)
	  {
		  Point p1 = ProjectToPlane(coords[linecoords[i]-1]);
		  Point p2 = ProjectToPlane(coords[linecoords[i+1]-1]);
		  TLine *line = new TLine(p1.x+0.5, p1.y+0.5, p2.x+0.5, p2.y+0.5);
		  line->SetLineColor(BackColor);
		  line->Draw();
		  lines.push_back(line);
	  }
   }
   
   //Draw The Dots
   for(Int_t i=0; i<coords.size(); i++)
   {
      p = ProjectToPlane(coords[i]);
      TEllipse *dot = new TEllipse(p.x+0.5, p.y+0.5, 0.03, 0.03*facY);
      if(coords[i].z == gridSize)
         dot->SetFillColor(FrontGrad);
      else
         dot->SetFillColor(BackGrad);
      dot->SetLineColor(kMagenta);
      dot->Draw();
      dots.push_back(dot);
   }
   
   //Draw Lines in Fron of Dots
   for(Int_t i=0; i<linecoords.size(); i=i+2)
   {
	  if(coords[linecoords[i]-1].z != (-1)*gridSize)
	  {
		  Point p1 = ProjectToPlane(coords[linecoords[i]-1]);
		  Point p2 = ProjectToPlane(coords[linecoords[i+1]-1]);
		  TLine *line = new TLine(p1.x+0.5, p1.y+0.5, p2.x+0.5, p2.y+0.5);
		  line->SetLineColor(FrontColor);
		  line->Draw();
		  lines.push_back(line);
	  }
   }

   //Rotate
   Double_t alpha = 0.007;
   while(Time()<GridTime*1000)
   {
	   for(Int_t i=0; i<coords.size(); i++)
	   {
		  p = ProjectToPlane(Rotate(coords[i], alpha));
		  dots[i]->SetX1(p.x+0.5);
		  dots[i]->SetY1(p.y+0.5);
	   }
	   for(Int_t i=0; i<linecoords.size(); i=i+2)
	   {
		  Point p1 = ProjectToPlane(Rotate(coords[linecoords[i]-1], alpha));
		  Point p2 = ProjectToPlane(Rotate(coords[linecoords[i+1]-1], alpha));
		  lines[TMath::Floor(i/2)]->SetX1(p1.x+0.5);
		  lines[TMath::Floor(i/2)]->SetY1(p1.y+0.5);
		  lines[TMath::Floor(i/2)]->SetX2(p2.x+0.5);
		  lines[TMath::Floor(i/2)]->SetY2(p2.y+0.5);
	   }
	   alpha = alpha + 0.001;
	   gPad->Modified(kTRUE);
	   gPad->Update();
   }
   while(Time()<GridLeaveTime*1000)
   {
	  for(Int_t i=0; i<coords.size(); i++)
	  {
		  dots[i]->SetX1(dots[i]->GetX1() + (-0.05)*(dots[i]->GetX1()-0.5));
		  dots[i]->SetY1(dots[i]->GetY1() + (-0.05)*(dots[i]->GetY1()-0.5));
		  if(dots[i]->GetR1() > 0.01)
			dots[i]->SetR1(dots[i]->GetR1()-0.001);
		  if(dots[i]->GetR2() > 0.01)
			dots[i]->SetR2(dots[i]->GetR2()-0.001*facY);
	  }
      if(Proton->GetR1() > 0.01)
		Proton->SetR1(Proton->GetR1()-0.001);
	  if(Proton->GetR2() > 0.01)
		Proton->SetR2(Proton->GetR2()-0.001*facY);
	  for(Int_t i=0; i<linecoords.size(); i=i+2)
	  {
		  Point p1 = ProjectToPlane(Rotate(coords[linecoords[i]-1], alpha));
		  Point p2 = ProjectToPlane(Rotate(coords[linecoords[i+1]-1], alpha));
		  lines[TMath::Floor(i/2)]->SetX1(lines[TMath::Floor(i/2)]->GetX1() + (-0.05)*(lines[TMath::Floor(i/2)]->GetX1()-0.5));
		  lines[TMath::Floor(i/2)]->SetY1(lines[TMath::Floor(i/2)]->GetY1() + (-0.05)*(lines[TMath::Floor(i/2)]->GetY1()-0.5));
		  lines[TMath::Floor(i/2)]->SetX2(lines[TMath::Floor(i/2)]->GetX2() + (-0.05)*(lines[TMath::Floor(i/2)]->GetX2()-0.5));
		  lines[TMath::Floor(i/2)]->SetY2(lines[TMath::Floor(i/2)]->GetY2() + (-0.05)*(lines[TMath::Floor(i/2)]->GetY2()-0.5));
	  }
	  gPad->Modified(kTRUE);
	  gPad->Update();
   }
   gPad->Clear();
}
//______________________________________________________________________
void ScrewIt()
{
   //Virtual Line which holds the Ellipses:
   Point lineStart = Point(0.45, 0.55);
   Point lineEnd = Point(0.55, 0.45);
   
   Int_t nEllipses = 10;
   
   for(Int_t i=0; i<nEllipses; i++)
   {
	   Double_t t = (Double_t)(i)/(Double_t)(nEllipses);
	   TEllipse *ellipse = new TEllipse(lineStart.x*(1-t)+lineEnd.x*t, lineStart.y*(1-t)+lineEnd.y*t, 0.04+0.0013*i, (0.04+0.0013*i)*facY,0,360,0);
      ellipse->SetFillColor(metalGrad);
      ellipse->SetLineColor(kMagenta);
	   ellipse->Draw();
   }
   //Head
   TEllipse *head = new TEllipse(lineEnd.x, lineEnd.y, 0.08, 0.08*facY,0,360,0);
   head->SetFillColor(metalGrad);
   head->SetLineColor(kMagenta);
   head->Draw();
   TPave *schlitz = new TPave(lineEnd.x + 0.04,lineEnd.y - 0.01,lineEnd.x - 0.04,lineEnd.y + 0.01, 3, "br");
   schlitz->SetLineColor(kBlack);
   schlitz->SetLineWidth(3);
   schlitz->SetFillColor(kWhite);
   schlitz->Draw();
   
   while(Time()<ScrewTime*1000)
   {
	   gPad->Modified(kTRUE);
	   gPad->Update();
   }
}
//______________________________________________________________________
vec3 Rotate(vec3 v, Double_t alpha)
{
   vec3 w = vec3();
   w.x = TMath::Cos(alpha)*v.x - TMath::Sin(alpha)*v.y;
   w.y = TMath::Sin(alpha)*v.x + TMath::Cos(alpha)*v.y;
   w.z = v.z;
   return w;
}
//______________________________________________________________________
Point ProjectToPlane(vec3 v)
{
   Point p = Point();
   p.x = v.x+0.5*v.z*TMath::Sqrt(3)/2;
   p.y = v.y+0.5*v.z*0.5;
   return p;
}
//______________________________________________________________________
void LuckyRobots() {
   Int_t nRobots = 4;
   for(Int_t i=0; i<nRobots; i++)
   {
      LuckyRobot r = LuckyRobot(0.2*i, 0.5, i+2);
      DrawLuckyRobot(r);
   }
   gPad->Modified(kTRUE);
   gPad->Update();
}
//______________________________________________________________________
void MoveLuckyRobot(LuckyRobot r, Double_t dx, Double_t dy){
   r.armr->SetX1(r.armr->GetX1()+dx);
   r.armr->SetY1(r.armr->GetY1()+dy);
   r.arml->SetX1(r.arml->GetX1()+dx);
   r.arml->SetY1(r.arml->GetY1()+dy);
   r.bauch->SetX1(r.bauch->GetX1()+dx);
   r.bauch->SetY1(r.bauch->GetY1()+dy);
   r.antenne1->SetX1(r.antenne1->GetX1()+dx);
   r.antenne1->SetX2(r.antenne1->GetX2()+dx);
   r.antenne1->SetY1(r.antenne1->GetY1()+dy);
   r.antenne1->SetY2(r.antenne1->GetY2()+dy);
   r.antenne2->SetX1(r.antenne2->GetX1()+dx);
   r.antenne2->SetX2(r.antenne2->GetX2()+dx);
   r.antenne2->SetY1(r.antenne2->GetY1()+dy);
   r.antenne2->SetY2(r.antenne2->GetY2()+dy);
   r.augel->SetX(r.augel->GetX()+dx);
   r.augel->SetY(r.augel->GetY()+dy);
   r.auger->SetX(r.auger->GetX()+dx);
   r.auger->SetY(r.auger->GetY()+dy);
   r.nase->SetX(r.nase->GetX()+dx);
   r.nase->SetY(r.nase->GetY()+dy);
}
//______________________________________________________________________
void DrawLuckyRobot(LuckyRobot r){
   r.armr->Draw();
   r.arml->Draw();
   r.bauch->Draw();
   r.antenne1->Draw();
   r.antenne2->Draw();
   r.augel->Draw();
   r.auger->Draw();
   r.nase->Draw();
}
//______________________________________________________________________
void LuckyRobotsDance(Int_t i, std::vector<LuckyRobot> &robots) {
   for(Int_t j = 0; j < robots.size(); j++)
   {
      robots[j].armr->SetTheta(i);
   }
   gPad->Modified(kTRUE);
   gPad->Update();
}
//______________________________________________________________________
void drawrobot(robot heinz)
{
	Int_t col = TColor::GetColor(255,128,0);
	heinz.oberarm1->SetFillColor(col);
	heinz.oberarm2->SetFillColor(col);
	heinz.ellbogen1->SetFillColor(col);
	heinz.ellbogen2->SetFillColor(col);
	heinz.unterarm1->SetFillColor(col);
	heinz.unterarm2->SetFillColor(col);
	heinz.hand1->SetFillColor(col);
	heinz.hand2->SetFillColor(col);
	heinz.bein1->SetFillColor(col);
	heinz.bein2->SetFillColor(col);
	heinz.fuss1->SetFillColor(col);
	heinz.fuss2->SetFillColor(col);
	heinz.koerper->SetFillColor(col);
	heinz.kopf->SetFillColor(col);
	heinz.hals->SetFillColor(col);
    heinz.auge1->SetMarkerStyle(4);
    heinz.auge1->SetMarkerSize(1.4);
    heinz.auge2->SetMarkerStyle(4);
    heinz.auge2->SetMarkerSize(2.4);
    heinz.mund->SetFillColor(1);

	heinz.oberarm1->Draw();
	heinz.oberarm2->Draw();
	heinz.ellbogen1->Draw();
	heinz.ellbogen2->Draw();
	heinz.unterarm1->Draw();
	heinz.unterarm2->Draw();
	heinz.hand1->Draw();
	heinz.hand2->Draw();
	heinz.kopf->Draw();
	heinz.hals->Draw();
    heinz.auge1->Draw();
    heinz.auge2->Draw();
    heinz.mund->Draw();
	//Fehlt: Füße, Beine und Körper, die sollen vor den Lucky Robots
}
//______________________________________________________________________
void Robot()
{
	gPad->Clear();
	gPad->SetFillColor(7);
	gPad->SetFillStyle(3023);
	
   	float speed = 1e-3;

	//create robot
	robot peter = robot(0.5,0.0); 
	peter.bein1->Draw();
	peter.bein2->Draw();
	peter.koerper->Draw();
	peter.fuss1->Draw();
	peter.fuss2->Draw();

	// Many Robots!
	std::vector<LuckyRobot> LuckyRobots;

	Int_t nRobots = 4;
	for(Int_t j=0; j<nRobots; j++)
	{
		LuckyRobot r = LuckyRobot(0.2+0.2*j, 0.75, j+2);
   		DrawLuckyRobot(r);
		LuckyRobots.push_back(r);
	}
	
	//four at the edge
	LuckyRobot r = LuckyRobot(0.2, 0.4, nRobots+2);
	DrawLuckyRobot(r);
	LuckyRobots.push_back(r);
	
	r = LuckyRobot(0.8, 0.4, nRobots+3);
	DrawLuckyRobot(r);
	LuckyRobots.push_back(r);

	r = LuckyRobot(0.2, 0.1, nRobots+4);
	DrawLuckyRobot(r);
	LuckyRobots.push_back(r);
	
	r = LuckyRobot(0.8, 0.1, nRobots+5);
	DrawLuckyRobot(r);
	LuckyRobots.push_back(r);	
	
	//Rest Drawen
	drawrobot(peter);

	//dance!!
	float hands = 0.011*0.2; 
	float arms = 0.01*0.2;
	float ells = 0.0003*0.2;

	float H1Y1 = peter.hand1->GetY1();
	float H1Y2 = peter.hand1->GetY2() ;
	float U1Y2 = peter.unterarm1->GetY2();
	float F1X1 = peter.fuss1->GetX1();
	float F1X2 = peter.fuss1->GetX2();
	float F2X1 = peter.fuss2->GetX1();
	float F2X2 = peter.fuss2->GetX2();
	float Hrange = 0.145;
	float Urange = 0.11;
	float Frange = 0.02;

	while(Time()<DanceTimeV1*1000)
	{
		int i = Time() -ScrewTime*1000;
		peter.hand1->SetY1(H1Y1-Hrange-Hrange*(TMath::Sin(speed*i*2*TMath::Pi())));
		peter.hand1->SetY2(H1Y2-Hrange-Hrange*(TMath::Sin(speed*i*2*TMath::Pi())));

		peter.unterarm1->SetY2(U1Y2-Urange-Urange*(TMath::Sin(speed*i*2*TMath::Pi())));

		peter.hand2->SetY1(H1Y1-Hrange-Hrange*(TMath::Sin(speed*i*2*TMath::Pi()+TMath::Pi())));
		peter.hand2->SetY2(H1Y2-Hrange-Hrange*(TMath::Sin(speed*i*2*TMath::Pi()+TMath::Pi())));

		peter.unterarm2->SetY2(U1Y2-Urange-Urange*(TMath::Sin(speed*i*2*TMath::Pi()+TMath::Pi())));

		peter.fuss1->SetX1(F1X1-TMath::Abs(Frange*TMath::Sin(speed*(2*i+1.)*TMath::Pi())));
		peter.fuss1->SetX2(F1X2-TMath::Abs(Frange*TMath::Sin(speed*(2*i+1.)*TMath::Pi())));

		peter.fuss2->SetX1(F2X1+TMath::Abs(Frange*TMath::Sin(speed*(2*i+1.)*TMath::Pi())));
		peter.fuss2->SetX2(F2X2+TMath::Abs(Frange*TMath::Sin(speed*(2*i+1.)*TMath::Pi())));

		for(Int_t j=0; j<LuckyRobots.size(); j++)
		{
			LuckyRobots[j].antenne1->SetArrowSize(0.03+0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));
			LuckyRobots[j].antenne2->SetArrowSize(0.03-0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));
			LuckyRobots[j].armr->SetTheta(TMath::Sin(speed*(4*i)*TMath::Pi())*180);
			LuckyRobots[j].arml->SetTheta(TMath::Sin(speed*(4*i)*TMath::Pi())*180);
		}

		gPad->Modified(kTRUE);
		gPad->Update();
	}	
	gPad->SetFillColor(6);
	gPad->SetFillStyle(3011);	
	
	//dance Egypt!!
	peter.kopf->SetX1(0.45);
	peter.kopf->SetX2(0.55);
	peter.hand1->SetX1(0.665);
	peter.hand1->SetX2(0.74497);
	peter.hand2->SetX1(0.25503);
	peter.hand2->SetX2(0.335);
    peter.hand1->SetY1(0.665635);
    peter.hand1->SetY2(0.705735);
    peter.hand2->SetY1(0.348835);
    peter.hand2->SetY2(0.388935);
    peter.unterarm1->SetY2(0.652062);
    peter.unterarm2->SetY2(0.390702);

	float H1X2 = peter.hand1->GetX2() ;
	float H2X1 = peter.hand2->GetX1() ;
	H1Y2 = peter.hand1->GetY2();
	float H2Y1 = peter.hand2->GetY1();
	H1Y1 = peter.hand1->GetY1() ;
	H1Y2 = peter.hand1->GetY2() ;
	U1Y2 = peter.unterarm1->GetY2();
	float KX1 = peter.kopf->GetX1();
	float KX2 = peter.kopf->GetX2();
	float H1X1 = peter.hand1->GetX1();
	H1X2 = peter.hand1->GetX2();
	H2X1 = peter.hand2->GetX1();
	float H2X2 = peter.hand2->GetX2();
	float A1X = peter.auge1->GetX();
	float A1Y = peter.auge1->GetY();
	float A2X = peter.auge2->GetX();
	float A2Y = peter.auge2->GetY();
	float MX = peter.mund->GetX1();
	float MY = peter.mund->GetY1();

	while(Time()<DanceTimeV2*1000)
	{
		int i = Time() - DanceTimeV1*1000;
		peter.kopf->SetX1(KX1+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.kopf->SetX2(KX2+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.auge1->SetX(A1X+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.auge2->SetX(A2X+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.mund->SetX1(MX+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));

		peter.hand1->SetX1(H1X1+0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.hand1->SetX2(H1X2+0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));
		
		peter.hand2->SetX1(H2X1+0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.hand2->SetX2(H2X2+0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));

		for(Int_t j=0; j<LuckyRobots.size(); j++)
		{
			LuckyRobots[j].bauch->SetR1(LuckyRobots[j].bauch->GetR1()+0.0005*TMath::Sin(speed*(2*i)*TMath::Pi()));
			LuckyRobots[j].bauch->SetR2(LuckyRobots[j].bauch->GetR2()-0.0005*TMath::Sin(speed*(2*i)*TMath::Pi()));
			LuckyRobots[j].armr->SetTheta(TMath::Sin(speed*(4*i)*TMath::Pi())*20);
			LuckyRobots[j].arml->SetTheta(TMath::Sin(speed*(4*i)*TMath::Pi())*20);
		}
		
		gPad->Modified(kTRUE);
		gPad->Update();		
	}
	
	gPad->SetFillColor(9);
	gPad->SetFillStyle(3021);	
	
//Indian dance	
	peter.unterarm1->SetX1(0.4070352);
	peter.unterarm1->SetY1(0.7543554);
	peter.unterarm1->SetX2(0.4798995);
	peter.unterarm1->SetY2(0.8013937);
	
	peter.unterarm2->SetX1(0.5150754);
	peter.unterarm2->SetY1(0.7526132);
	peter.unterarm2->SetX2(0.5954774);
	peter.unterarm2->SetY2(0.8013937);
	
	peter.oberarm1->SetX1(0.3907035);
	peter.oberarm1->SetY1(0.5679443);
	peter.oberarm1->SetX2(0.428392);
	peter.oberarm1->SetY2(0.6933798);
	
	peter.oberarm2->SetX1(0.5690955);
	peter.oberarm2->SetY1(0.5696864);
	peter.oberarm2->SetX2(0.6067839);
	peter.oberarm2->SetY2(0.695122);
	
	peter.ellbogen1->SetX1(0.3831658);
	peter.ellbogen1->SetY1(0.6986063);
	peter.ellbogen1->SetX2(0.4183417);
	peter.ellbogen1->SetY2(0.7491289);
	
	peter.ellbogen2->SetX1(0.5791457);
	peter.ellbogen2->SetY1(0.6986063);
	peter.ellbogen2->SetX2(0.6143216);
	peter.ellbogen2->SetY2(0.7491289);
	
	peter.hand1->SetX1(0.4723618);
	peter.hand1->SetX2(0.4974874);
    peter.hand1->SetY1(0.804878);
    peter.hand1->SetY2(0.8832753);
    
	peter.hand2->SetX1(0.5050251);
	peter.hand2->SetX2(0.5301508);
    peter.hand2->SetY1(0.804878);
    peter.hand2->SetY2(0.8850174);
    
    peter.mund->SetPhimin(0);
    peter.mund->SetR1(0.005);   
    peter.mund->SetR2(0.01);
        
	float O1X2 = peter.oberarm1->GetX2();
	float O2X1 = peter.oberarm2->GetX1();
	U1Y2 = peter.unterarm1->GetY2();
	float U1Y1 = peter.unterarm1->GetY1();
	float U2Y2 = peter.unterarm2->GetY2();
	float U2Y1 = peter.unterarm2->GetY1();
	float U1X2 = peter.unterarm1->GetX2();
	float U1X1 = peter.unterarm1->GetX1();
	float U2X2 = peter.unterarm2->GetX2();
	float U2X1 = peter.unterarm2->GetX1();
	H1Y2 = peter.hand1->GetY2();
	H1Y1 = peter.hand1->GetY1();
	float H2Y2 = peter.hand2->GetY2();
	H2Y1 = peter.hand2->GetY1();
	KX1 = peter.kopf->GetX1();
	KX2 = peter.kopf->GetX2();

	while(Time()<DanceTimeV3*1000)
	{
		int i = Time() - DanceTimeV2*1000;

		peter.kopf->SetX1(KX1+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.kopf->SetX2(KX2+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.auge1->SetX(A1X+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.auge2->SetX(A2X+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.mund->SetX1(MX+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
			
		bool move = true;	
		for(Int_t j=0; j<LuckyRobots.size(); j++) 
		{
			Double_t dx, dy;
			if(Dist(Point(LuckyRobots[j].x, LuckyRobots[j].y), Point(0.5, 0.5)) > 0.3)
			{
				dx = (-0.01)*(LuckyRobots[j].x-0.5);
				dy = (-0.01)*(LuckyRobots[j].y-0.5);
				move = false;
			}
			else
			{
				if(move) {
					dx = (-0.01)*(LuckyRobots[j].y-0.5);
					dy = (LuckyRobots[j].x-0.5) * 0.01;
				}
				else {
					dx = dy = 0;
				}
			}
			MoveLuckyRobot(LuckyRobots[j], dx, dy);
			LuckyRobots[j].x = LuckyRobots[j].x+dx;
			LuckyRobots[j].y = LuckyRobots[j].y+dy;
		}

		gPad->Modified(kTRUE);
		gPad->Update();		
	}	
	
	gPad->SetFillColor(TColor::GetColor(232, 213, 0));
	gPad->SetFillStyle(3012);
	
	//last dance
	peter.kopf->SetX1(0.4497487);
	peter.kopf->SetX2(0.548995);
	peter.kopf->SetY1(0.6114983);
	peter.kopf->SetY2(0.7212544);
	
    peter.mund->SetPhimin(180);
    peter.mund->SetR1(0.02386935);   
    peter.mund->SetR2(0.01655052);
	
	peter.unterarm1->SetX1(0.2889447);
	peter.unterarm1->SetY1(0.5313589);
	peter.unterarm1->SetX2(0.3241206);
	peter.unterarm1->SetY2(0.630662);
	
	peter.unterarm2->SetX1(0.6746231);
	peter.unterarm2->SetY1(0.5313589);
	peter.unterarm2->SetX2(0.709799);
	peter.unterarm2->SetY2(0.630662);
	
	peter.oberarm1->SetX1(0.3291457);
	peter.oberarm1->SetY1(0.4808362);
	peter.oberarm1->SetX2(0.4095477);
	peter.oberarm1->SetY2(0.5313589);
	
	peter.oberarm2->SetX1(0.589196);
	peter.oberarm2->SetY1(0.4808362);
	peter.oberarm2->SetX2(0.669598);
	peter.oberarm2->SetY2(0.5313589);
	
	peter.ellbogen1->SetX1(0.2889447);
	peter.ellbogen1->SetY1(0.4808362);
	peter.ellbogen1->SetX2(0.3241206);
	peter.ellbogen1->SetY2(0.5313589);
	
	peter.ellbogen2->SetX1(0.6746231);
	peter.ellbogen2->SetY1(0.4808362);
	peter.ellbogen2->SetX2(0.709799);
	peter.ellbogen2->SetY2(0.5313589);
	
	peter.hand1->SetX1(0.2839196);
	peter.hand1->SetX2(0.3341709);
    peter.hand1->SetY1(0.641115);
    peter.hand1->SetY2(0.74);
    
	peter.hand2->SetX1(0.6645729);
	peter.hand2->SetX2(0.7148241);
    peter.hand2->SetY1(0.641115);
    peter.hand2->SetY2(0.74);

	H1Y1 = peter.hand1->GetY1() ;
	H1Y2 = peter.hand1->GetY2() ;
	U1Y2 = peter.unterarm1->GetY2();
	Double_t KY1 = peter.kopf->GetY1();
	Double_t KY2 = peter.kopf->GetY2();
	H1X1 = 	peter.hand1->GetX1() ;
	H1X2 = 	peter.hand1->GetX2() ;
	H2X1 = 	peter.hand2->GetX1() ;
	H2X2 = 	peter.hand2->GetX2() ;
   
   Int_t blaboxCol = TColor::GetColor(252, 71, 240);
   TPave *blabox = new TPave(0.5549623,0.82,0.955402,1.0175,4,"br");
   blabox->SetFillColor(blaboxCol);
   blabox->Draw();
   TLatex *greets1 = new TLatex(0.6664573,0.9333333,"Hi there,");
   greets1->SetLineWidth(2);
   greets1->Draw();
   TLatex *greets2 = new TLatex(0.584799,0.8611111,"AttentionWhores!");
   greets2->SetLineWidth(2);
   greets2->Draw();
   TArrow *arrow = new TArrow(0.5832286,0.8416667,0.56,0.7625,0.07,"|>");
   arrow->SetFillColor(blaboxCol);
   arrow->SetFillStyle(1001);
   arrow->SetLineColor(kMagenta);
   arrow->SetLineStyle(3);
   arrow->Draw();

	while(Time()<DanceTimeV4*1000)
	{
		int i = Time() - DanceTimeV1*1000;
		peter.kopf->SetY1(KY1+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.kopf->SetY2(KY2+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.auge1->SetY(A1Y+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.auge2->SetY(A2Y+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.mund->SetY1(MY+0.03*TMath::Sin(speed*(2*i)*TMath::Pi()));

		peter.hand1->SetX1(H1X1+0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.hand1->SetX2(H1X2+0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));
		
		peter.hand2->SetX1(H2X1+0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));
		peter.hand2->SetX2(H2X2+0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));

		for(Int_t j=0; j<LuckyRobots.size(); j++)
		{
			Double_t dx = (LuckyRobots[j].x-0.5) * 0.002;
			Double_t dy = (LuckyRobots[j].y-0.5) * 0.002;
			MoveLuckyRobot(LuckyRobots[j], dx, dy);
			
			LuckyRobots[j].antenne1->SetArrowSize(0.03+0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));
			LuckyRobots[j].antenne2->SetArrowSize(0.03-0.01*TMath::Sin(speed*(2*i)*TMath::Pi()));
			LuckyRobots[j].armr->SetTheta(TMath::Sin(speed*(4*i)*TMath::Pi())*40);
			LuckyRobots[j].arml->SetTheta(TMath::Sin(speed*(4*i)*TMath::Pi())*40);
		}
		
		gPad->Modified(kTRUE);
		gPad->Update();		
	}
	
   //go back
   TCurlyArc *boom = new TCurlyArc(0.5, 0.5, 0.03, 0, 360);
   TEllipse *boomBlack = new TEllipse(0.5, 0.5, 0.01, 0.01, 0, 360);
   boomBlack->SetFillColor(1);
   boomBlack->Draw();
   boom->Draw();
   while(Time()<RobotBlowTime*1000)
   {
	  boomBlack->SetR1(boomBlack->GetR1()+0.01);
	  boomBlack->SetR2(boomBlack->GetR2()+0.01*facY);
	  boom->SetRadius(boom->GetRadius()+0.01);
	  MoveBox(peter.koerper, 0.01, 0.002);
	  MoveBox(peter.oberarm1, 0.001, 0.01);
	  MoveBox(peter.oberarm2, -0.01, 0.003);
	  MoveBox(peter.ellbogen1, 0.01, 0.01);
	  MoveBox(peter.ellbogen2, -0.01, 0.01);
	  MoveBox(peter.unterarm1, -0.003, 0.02);
	  MoveBox(peter.unterarm2, 0.05, 0.08);
	  MoveBox(peter.hand1, -0.02, 0);
	  MoveBox(peter.hand2, 0.02, 0);
	  MoveBox(peter.bein1, 0.001, 0.02);
	  MoveBox(peter.bein2, 0.009, -0.02);
	  MoveBox(peter.fuss1, 0, -0.01);
	  MoveBox(peter.fuss2, 0.002, -0.089);
	  MoveBox(peter.kopf, 0, 0.016);
	  MoveBox(peter.hals, 0, 0.016);
      
      gPad->Modified(kTRUE);
      gPad->Update();
   }
}
//______________________________________________________________________
void MoveBox(TBox *b, Double_t dx, Double_t dy)
{
   b->SetX1(b->GetX1()+dx);
   b->SetX2(b->GetX2()+dx);
   b->SetY1(b->GetY1()+dy);
   b->SetY2(b->GetY2()+dy);
}

//Für den Monolit
Double_t gw = 0.1;
Double_t gh = 0.5;
Double_t gd = 0.02;
Double_t gx = 0.5;
Double_t gy = 0.5;

//______________________________________________________________________
void Back()
{
   std::vector<TMarker *> marker;
////Schraube
   //Virtual Line which holds the Ellipses:
   Point lineStart = Point(0.45, 0.55);
   Point lineEnd = Point(0.55, 0.45);
   
   Int_t nEllipses = 10;
   
   gPad->Clear();
   gPad->SetFillStyle(4000);
   gPad->SetFillColor(bg);
   
   for(Int_t i=0; i<nEllipses; i++)
   {
	   Double_t t = (Double_t)(i)/(Double_t)(nEllipses);
	   TEllipse *ellipse = new TEllipse(lineStart.x*(1-t)+lineEnd.x*t, lineStart.y*(1-t)+lineEnd.y*t, 0.04+0.0013*i, (0.04+0.0013*i)*facY,0,360,0);
      ellipse->SetFillColor(metalGrad);
      ellipse->SetLineColor(kMagenta);
	   ellipse->Draw();
   }
   //Head
   TEllipse *head = new TEllipse(lineEnd.x, lineEnd.y, 0.08, 0.08*facY,0,360,0);
   head->SetFillColor(metalGrad);
   head->SetLineColor(kMagenta);
   head->Draw();
   TPave *schlitz = new TPave(lineEnd.x + 0.04,lineEnd.y - 0.01,lineEnd.x - 0.04,lineEnd.y + 0.01, 3, "br");
   schlitz->SetLineColor(kBlack);
   schlitz->SetLineWidth(3);
   schlitz->SetFillColor(kWhite);
   schlitz->Draw();
   while(Time()<(BackScrewTime-1)*1000)
   {
      gPad->Modified(kTRUE);
      gPad->Update();
   }
   TVirtualPad *oldpad = gPad;
   TPad *stars = new TPad("stars", "stars", 0,0,1,1);
   stars->SetFillStyle(0);
   stars->SetFillColor(0);
   stars->Draw();
   stars->cd();   
   marker = BackStars(BackScrewTime);
   BackAnimateStars(marker, 1000*((Double_t)BackScrewTime-0.5));
   oldpad->Clear();
   oldpad->cd();   

////Grid
   std::vector<TEllipse *> dots;
   std::vector<TLine *> lines;
   Point p;
   Double_t gridSize = 0.2;
   
   Color_t colorIndices[2] = {TColor::GetColor(189,51,74), kBlack};
   Double_t lengths[2] = {0., 1.};
   TRadialGradient *grad = new TRadialGradient(1259, 2, lengths, colorIndices);
   grad->SetRadialGradient(TColorGradient::Point(0.5,0.5), 0.4);
   Int_t FrontGrad = 1259;

   grad = new TRadialGradient(1260, 2, lengths, colorIndices);
   grad->SetRadialGradient(TColorGradient::Point(0.5,0.5), 0.2);
   Int_t BackGrad = 1260;
   
   Int_t FrontColor = TColor::GetColor(51,189,166);
   Int_t BackColor = TColor::GetColor(27,97,85);
   
   gROOT->GetColor(FrontColor)->SetAlpha(0.5);
   gROOT->GetColor(BackColor)->SetAlpha(0.5);
	
   TEllipse *Proton = new TEllipse(0.5, 0.5, 0.03, 0.03*facY);
   Proton->SetFillColor(metalGrad);
   Proton->SetLineColor(kMagenta);
   Proton->Draw();

   //Draw Lines behind Dots
   for(Int_t i=0; i<linecoords.size(); i=i+2)
   {
	  if(coords[linecoords[i]-1].z == (-1)*gridSize)
	  {
		  Point p1 = ProjectToPlane(coords[linecoords[i]-1]);
		  Point p2 = ProjectToPlane(coords[linecoords[i+1]-1]);
		  TLine *line = new TLine(p1.x+0.5, p1.y+0.5, p2.x+0.5, p2.y+0.5);
		  line->SetLineColor(BackColor);
		  line->Draw();
		  lines.push_back(line);
	  }
   }
   
   //Draw The Dots
   for(Int_t i=0; i<coords.size(); i++)
   {
      p = ProjectToPlane(coords[i]);
      TEllipse *dot = new TEllipse(p.x+0.5, p.y+0.5, 0.03, 0.03*facY);
      if(coords[i].z == gridSize)
         dot->SetFillColor(FrontGrad);
      else
         dot->SetFillColor(BackGrad);
      dot->SetLineColor(kMagenta);
      dot->Draw();
      dots.push_back(dot);
   }
   
   //Draw Lines in Fron of Dots
   for(Int_t i=0; i<linecoords.size(); i=i+2)
   {
	  if(coords[linecoords[i]-1].z != (-1)*gridSize)
	  {
		  Point p1 = ProjectToPlane(coords[linecoords[i]-1]);
		  Point p2 = ProjectToPlane(coords[linecoords[i+1]-1]);
		  TLine *line = new TLine(p1.x+0.5, p1.y+0.5, p2.x+0.5, p2.y+0.5);
		  line->SetLineColor(FrontColor);
		  line->Draw();
		  lines.push_back(line);
	  }
   }
   stars->Delete();
   for(Int_t i=0; i<marker.size(); i++)
	  marker[i]->Draw();
   BackAnimateStarsLeave(marker, 1000*BackScrewTime);

   //Rotate
   Double_t alpha = 0.002;
   while(Time()<(BackAtomTime-1)*1000)
   {
	   for(Int_t i=0; i<coords.size(); i++)
	   {
		  p = ProjectToPlane(Rotate(coords[i], alpha));
		  dots[i]->SetX1(p.x+0.5);
		  dots[i]->SetY1(p.y+0.5);
	   }
	   for(Int_t i=0; i<linecoords.size(); i=i+2)
	   {
		  Point p1 = ProjectToPlane(Rotate(coords[linecoords[i]-1], alpha));
		  Point p2 = ProjectToPlane(Rotate(coords[linecoords[i+1]-1], alpha));
		  lines[TMath::Floor(i/2)]->SetX1(p1.x+0.5);
		  lines[TMath::Floor(i/2)]->SetY1(p1.y+0.5);
		  lines[TMath::Floor(i/2)]->SetX2(p2.x+0.5);
		  lines[TMath::Floor(i/2)]->SetY2(p2.y+0.5);
	   }
	   alpha = alpha + 0.001;
	   gPad->Modified(kTRUE);
	   gPad->Update();
   }
   oldpad = gPad;
   stars = new TPad("stars", "stars", 0,0,1,1);
   stars->SetFillStyle(0);
   stars->SetFillColor(0);
   stars->Draw();
   stars->cd();   
   
   marker = BackStars(BackAtomTime);
   BackAnimateStars(marker, 1000*((Double_t)BackAtomTime-0.5));
   oldpad->Clear();
   oldpad->cd();   

////Quarks
   Quark singleq = Quark(0.5, 0.5, 1.4);
   singleq.qtopleft->SetFillColor(qRgrad);
   singleq.qtopleft->SetLineColor(kBlack);
   singleq.qtopright->SetFillColor(qGgrad);
   singleq.qtopright->SetLineColor(kBlack);
   singleq.qbottom->SetFillColor(qBgrad);
   singleq.qbottom->SetLineColor(kBlack);
   singleq.qaround->SetFillColor(qBGgrad);
   singleq.qaround->SetLineColor(kMagenta);
   DrawQuark(singleq);
   
   for(Int_t i=0; i<marker.size(); i++)
	  marker[i]->Draw();
   BackAnimateStarsLeave(marker, 1000*BackAtomTime);
   
   Int_t mfak = 1000;
   Int_t kmax = 90;
   
   while(Time()<(BackQuarksTime-2)*1000)
   {
	  Double_t DirectionX = (Double_t)rand()/RAND_MAX/mfak-0.49/mfak;
	  Double_t DirectionY = (Double_t)rand()/RAND_MAX/mfak-0.49/mfak;

      for(Int_t k=0; k<=kmax; k++)
      {
         MoveQuark(singleq, DirectionX*TMath::Sin(k*TMath::Pi()/kmax)*TMath::Sin(k*TMath::Pi()/kmax)*(singleq.size+0.7), DirectionY*TMath::Sin(k*TMath::Pi()/kmax)*TMath::Sin(k*TMath::Pi()/kmax)*(singleq.size+0.7));
         gPad->Modified(kTRUE);
         gPad->Update();
      }
   }
   oldpad = gPad;
   stars = new TPad("stars", "stars", 0,0,1,1);
   stars->SetFillStyle(0);
   stars->SetFillColor(0);
   stars->Draw();
   stars->cd();   
   
   marker = BackStars(BackQuarksTime);
   BackAnimateStars(marker, 1000*((Double_t)BackQuarksTime-0.5));
   oldpad->Clear();
   oldpad->cd();   
   
////Space
   std::vector<TMarker *> sternchen;
   Int_t nStars = 50;
   Double_t x, y;
   Double_t dist = 0.1;
   for(Int_t i=0; i<nStars; i++)
   {
      x = (Double_t)rand()/RAND_MAX;
      y = (Double_t)rand()/RAND_MAX;
      
      if(!((x>gx-0.5*gw-dist)&&(x<gx+0.5*gw+dist)&&(y>gy-0.5*gh-dist)&&(y<gy+0.5*gh+dist)))
	  {
		  TMarker *s = new TMarker(x, y, 29);
		  s->SetMarkerSize((Double_t)rand()/RAND_MAX/2+1);
		  s->SetMarkerColor(TColor::GetColor(200,200,255));
		  s->Draw();      
		  sternchen.push_back(s);
	  }
   }
   //Credits
   Int_t creditsColor = TColor::GetColor(202,202,254);
   TLatex *sg4 = new TLatex(0.3461055,0.6611498,"Subground4");
   sg4->SetTextColor(creditsColor);
   sg4->SetTextSize(0.06);
   sg4->Draw();
   TLatex *nm4 = new TLatex(0.4481784,0.5587979,"0mod4");
   nm4->SetTextColor(creditsColor);
   nm4->SetTextFont(42);
   nm4->SetTextSize(0.04);
   nm4->Draw();
   TLatex *mcs = new TLatex(0.4183417,0.4651568,"M.C.square");
   mcs->SetTextColor(creditsColor);
   mcs->SetTextFont(42);
   mcs->SetTextSize(0.04);
   mcs->Draw();
   TLatex *sd = new TLatex(0.4261935,0.3671603,"Subdream");
   sd->SetTextColor(creditsColor);
   sd->SetTextFont(42);
   sd->SetTextSize(0.04);
   sd->Draw();
   gROOT->GetColor(creditsColor)->SetAlpha(0);
   
   for(Int_t i=0; i<marker.size(); i++)
	  marker[i]->Draw();
   BackAnimateStarsLeave(marker, 1000*BackQuarksTime);
   
   Double_t a = 0.1;
   while(Time()<BackSpaceTime*1000)
   {
	   a = a + 0.1;
	   gROOT->GetColor(creditsColor)->SetAlpha(a);
	   gPad->Modified(kTRUE);
	   gPad->Update();
   }
   
   sg4->Delete();
   nm4->Delete();
   mcs->Delete();
   sd->Delete();
   
   //Monolit
   Monolit();
}
//______________________________________________________________________
std::vector<TMarker *> BackStars(Int_t sec)
{
   Int_t nStars = 30;
   Double_t x, y;
   std::vector < TMarker * > marker;
   for(Int_t i=0; i<floor((Double_t)nStars/(Double_t)2); i++)
   {
      x = (Double_t)rand()/RAND_MAX;
      y = (Double_t)rand()/RAND_MAX;
      
      TMarker *s = new TMarker(x, y, 29);
      s->SetMarkerSize((Double_t)rand()/RAND_MAX/2+2);
      s->SetMarkerColor(TColor::GetColor((Float_t)rand()/RAND_MAX, (Float_t)rand()/RAND_MAX, (Float_t)rand()/RAND_MAX));
      s->Draw();
      
      x = (Double_t)rand()/RAND_MAX;
      y = (Double_t)rand()/RAND_MAX;
      
      TMarker *c = new TMarker(x, y, 29);
      c->SetMarkerSize((Double_t)rand()/RAND_MAX/2+2);
      c->SetMarkerColor(TColor::GetColor((Float_t)rand()/RAND_MAX, (Float_t)rand()/RAND_MAX, (Float_t)rand()/RAND_MAX));
      c->Draw();
      
      marker.push_back(s);
      marker.push_back(c);
   }
   return(marker);
}
//______________________________________________________________________
void BackAnimateStars(std::vector <TMarker *> marker, Int_t sec) 
{
   while (Time() < sec)
   {
      for(Int_t j=0; j<marker.size(); j++)
      {
         marker[j]->SetMarkerSize(marker[j]->GetMarkerSize()+(Double_t)60/(Double_t)(sec/1000));
      }
      gPad->Modified(kTRUE);
      gPad->Update();
   }
}

//______________________________________________________________________
void BackAnimateStarsLeave(std::vector <TMarker *> marker, Int_t sec)
{
   while (Time() < sec)
   {
      for(Int_t j=0; j<marker.size(); j++)
      {
         marker[j]->SetX(marker[j]->GetX()*1.04);
         marker[j]->SetY(marker[j]->GetY()*1.04);
      }
      gPad->Modified(kTRUE);
      gPad->Update();
   }
   
   //marker vorsichtshalber löschen
   for(Int_t i=0; i<marker.size(); i++)
   {
      marker[i]->Delete();
   }
   marker.clear();
}

//______________________________________________________________________
void Monolit()
{  
   std::vector<vec3> mocoords;
   std::vector<Int_t> molinecoords;
   std::vector<TLine *> lines;
   Point p;
   
   //Baue den Monolit
   mocoords.push_back(vec3(-0.5*gw, 0.5*gh, 0.5*gd));
   mocoords.push_back(vec3(0.5*gw, 0.5*gh, 0.5*gd));
   mocoords.push_back(vec3(0.5*gw, -0.5*gh, 0.5*gd));
   mocoords.push_back(vec3(-0.5*gw, -0.5*gh, 0.5*gd));
   
   mocoords.push_back(vec3(-0.5*gw, 0.5*gh, -0.5*gd));
   mocoords.push_back(vec3(0.5*gw, 0.5*gh, -0.5*gd));
   mocoords.push_back(vec3(0.5*gw, -0.5*gh, -0.5*gd));
   mocoords.push_back(vec3(-0.5*gw, -0.5*gh, -0.5*gd));
   
   //Draw the Lines
   molinecoords.push_back (4);
   molinecoords.push_back (5);
   
   molinecoords.push_back (5);
   molinecoords.push_back (6);
   
   molinecoords.push_back (6);
   molinecoords.push_back (7);
   
   molinecoords.push_back (7);
   molinecoords.push_back (4);
   
   molinecoords.push_back (4);
   molinecoords.push_back (0);
   
   molinecoords.push_back (5);
   molinecoords.push_back (1);
   
   molinecoords.push_back (6);
   molinecoords.push_back (2);
   
   molinecoords.push_back (7);
   molinecoords.push_back (3);
   
   molinecoords.push_back (0);
   molinecoords.push_back (1);
   
   molinecoords.push_back (1);
   molinecoords.push_back (2);
   
   molinecoords.push_back (2);
   molinecoords.push_back (3);
   
   molinecoords.push_back (3);
   molinecoords.push_back (0);

   //Draw Lines
   for(Int_t i=0; i<molinecoords.size(); i=i+2)
   {
	  Point p1 = ProjectToPlane(mocoords[molinecoords[i]]);
	  Point p2 = ProjectToPlane(mocoords[molinecoords[i+1]]);
	  TLine *line = new TLine(p1.x+gx, p1.y+gy, p2.x+gx, p2.y+gy);
	  line->SetLineColor(0);
     line->SetLineWidth(2);
	  line->Draw();
	  lines.push_back(line);
   }

   //Rotate
   for(Int_t i=0; i<mocoords.size(); i++)
   {
	   mocoords[i] = moRotate(mocoords[i], 4.8);
   }
   Double_t alpha = 0.002;
   Double_t kumalpha = alpha;
   Double_t minZ;
   Int_t count = 0;
   while((Time()< TatataTime*1000))
   {
	   if (kumalpha<1.1){
		   minZ = 0;
		   for(Int_t i=0; i<mocoords.size(); i++)
		   {
			   mocoords[i] = moRotate(mocoords[i], alpha);
			   if(mocoords[i].z<minZ) minZ = mocoords[i].z;
		   }
		   for(Int_t i=0; i<molinecoords.size(); i=i+2)
		   {
			  vec3 v1 = mocoords[molinecoords[i]];
			  vec3 v2 = mocoords[molinecoords[i+1]];
			  //Check if the line is visible
			  if(((v1.z == minZ)&&(v1.y>0))||((v2.z == minZ)&&(v2.y>0)))
				 lines[TMath::Floor(i/2)]->SetLineColor(1);
			  else 
				 lines[TMath::Floor(i/2)]->SetLineColor(0);
			  Point p1 = ProjectToPlane(v1);
			  Point p2 = ProjectToPlane(v2);
			  lines[TMath::Floor(i/2)]->SetX1(p1.x+gx);
			  lines[TMath::Floor(i/2)]->SetY1(p1.y+gy);
			  lines[TMath::Floor(i/2)]->SetX2(p2.x+gx);
			  lines[TMath::Floor(i/2)]->SetY2(p2.y+gy);
		   }
		   gPad->Modified(kTRUE);
		   gPad->Update();
		   kumalpha = kumalpha + alpha;
	   }
   }
   
   //turn completely if it is not yet
   if(kumalpha<1.1) {
	   for(Int_t i=0; i<mocoords.size(); i++)
	   {
		   mocoords[i] = moRotate(mocoords[i], 1.1-kumalpha);
	   }
	   for(Int_t i=0; i<molinecoords.size(); i=i+2)
	   {
		  vec3 v1 = mocoords[molinecoords[i]];
		  vec3 v2 = mocoords[molinecoords[i+1]];
		  //Check if the line is visible
		  if(((v1.z == minZ)&&(v1.y>0))||((v2.z == minZ)&&(v2.y>0)))
			 lines[TMath::Floor(i/2)]->SetLineColor(1);
		  else 
			 lines[TMath::Floor(i/2)]->SetLineColor(0);
		  Point p1 = ProjectToPlane(v1);
		  Point p2 = ProjectToPlane(v2);
		  lines[TMath::Floor(i/2)]->SetX1(p1.x+gx);
		  lines[TMath::Floor(i/2)]->SetY1(p1.y+gy);
		  lines[TMath::Floor(i/2)]->SetX2(p2.x+gx);
		  lines[TMath::Floor(i/2)]->SetY2(p2.y+gy);
	   }
	   gPad->Modified(kTRUE);
	   gPad->Update();
   }
   
   Int_t TextShadowColor = TColor::GetColor(102,2,2);
   TLatex *tex = new TLatex(0.129,0.60,"2000Heinz-Dieter");
   tex->SetTextColor(TextShadowColor);
   tex->SetTextSize(0.1149826);
   tex->SetLineWidth(2);
   tex->Draw();
      tex = new TLatex(0.24,0.46,"im Weltraum");
   tex->SetTextColor(TextShadowColor);
   tex->SetTextSize(0.11);
   tex->SetLineWidth(2);
   tex->Draw();   
      tex = new TLatex(0.1199749,0.6132404,"2000Heinz-Dieter");
   tex->SetTextColor(2);
   tex->SetTextSize(0.1149826);
   tex->SetLineWidth(2);
   tex->Draw();
      tex = new TLatex(0.2346106,0.4760453,"im Weltraum");
   tex->SetTextColor(2);
   tex->SetTextSize(0.11);
   tex->SetLineWidth(2);
   tex->Draw();
      tex = new TLatex(0.2518844,0.1406794,"Thank you ROOT Team! <3");
   tex->SetTextColor(TColor::GetColor(230, 145, 0));
   tex->SetLineWidth(2);
   tex->Draw();   
   
   while(Time()<DadaTime*1000)
   {
	   gPad->Modified(kTRUE);
	   gPad->Update();
   }
}
//______________________________________________________________________
vec3 moRotate(vec3 v, Double_t alpha)
{
   vec3 w = vec3();
   w.x = TMath::Cos(alpha)*v.x + TMath::Sin(alpha)*v.z;
   w.y = v.y;
   w.z = (-1)*TMath::Sin(alpha)*v.x + TMath::Cos(alpha)*v.z;
   return w;
}
