/// \file /// \ingroup tutorial_graphics /// \notebook -js /// Using TExec to handle keyboard events and TComplex to draw the Mandelbrot set. /// /// Pressing the keys 'z' and 'u' will zoom and unzoom the picture /// near the mouse location, 'r' will reset to the default view. /// /// Try it (in compiled mode!) with: `root mandelbrot.C+` /// /// \macro_image (js) /// /// ### Details /// /// when a mouse event occurs the myexec() function is called (by /// using AddExec). Depending on the pressed key, the mygenerate() /// function is called, with the proper arguments. Note the /// last_x and last_y variables that are used in myexec() to store /// the last pointer coordinates (px is not a pointer position in /// kKeyPress events). /// /// \macro_code /// /// \author Luigi Bardelli #include #include #include #include #include #include TH2F *last_histo=NULL; void mygenerate(double factor, double cen_x, double cen_y) { printf("Regenerating...\n"); // resize histo: if(factor>0) { double dx=last_histo->GetXaxis()->GetXmax()-last_histo->GetXaxis()->GetXmin(); double dy=last_histo->GetYaxis()->GetXmax()-last_histo->GetYaxis()->GetXmin(); last_histo->SetBins( last_histo->GetNbinsX(), cen_x-factor*dx/2, cen_x+factor*dx/2, last_histo->GetNbinsY(), cen_y-factor*dy/2, cen_y+factor*dy/2 ); last_histo->Reset(); } else { if(last_histo!=NULL) delete last_histo; // allocate first view... last_histo= new TH2F("h2", "Mandelbrot [move mouse and press z to zoom, u to unzoom, r to reset]", 200,-2,2,200,-2,2); last_histo->SetStats(0); } const int max_iter=50; for(int bx=1;bx<=last_histo->GetNbinsX();bx++) for(int by=1;by<=last_histo->GetNbinsY();by++) { double x=last_histo->GetXaxis()->GetBinCenter(bx); double y=last_histo->GetYaxis()->GetBinCenter(by); TComplex point( x,y); TComplex z=point; int iter=0; while (z.Rho()<2){ z=z*z+point; last_histo->Fill(x,y); iter++; if(iter>max_iter) break; } } last_histo->SetContour(99); last_histo->Draw("colz"); gPad->Modified(); gPad->Update(); printf("Done.\n"); } void myexec() { // get event information int event = gPad->GetEvent(); int px = gPad->GetEventX(); int py = gPad->GetEventY(); // some magic to get the coordinates... double xd = gPad->AbsPixeltoX(px); double yd = gPad->AbsPixeltoY(py); float x = gPad->PadtoX(xd); float y = gPad->PadtoY(yd); static float last_x; static float last_y; if(event!=kKeyPress) { last_x=x; last_y=y; return; } const double Z=2.; switch(px){ case 'z': // ZOOM mygenerate(1./Z, last_x, last_y); break; case 'u': // UNZOOM mygenerate(Z , last_x, last_y); break; case 'r': // RESET mygenerate(-1 , last_x, last_y); break; }; } void mandelbrot() { // cosmetics... gStyle->SetPadGridX(kTRUE); gStyle->SetPadGridY(kTRUE); new TCanvas("canvas","View Mandelbrot set"); // this generates and draws the first view... mygenerate(-1,0,0); // add exec gPad->AddExec("myexec","myexec()"); }